/**
 * .mcb-single-article-page — Phase 5 visual implementation.
 *
 * Authoritative source: source-design/blog-post-original.zip
 * (blog-post.html + styles.css, the "A flat to a forest" Living 80
 * article). Values below are read directly from that stylesheet's own
 * `:root` tokens and `.blog-post-*`/`.blog-*` rules, not approximated.
 *
 * This template is plugin-owned, not Page-Pack-owned (unlike the Blog
 * overview, which lives in blog-page-pack-v2.zip) — so it cannot reach
 * the Blog overview Page Pack's `.pp-blog` scoped custom properties
 * (different DOM subtree, no shared ancestor) or the global Header Site
 * Part's `.pp-mycabin-header` ones. Same convention as both of those:
 * design tokens are declared LOCALLY, scoped to this template's own root
 * class (`--mcb-*`, never `:root`), matching Page Pack Spec §5's "layer
 * 2, never :root" rule even though this isn't a Page Pack file. Values
 * are copied from the same design system, not reinvented.
 *
 * Every selector is scoped under .mcb-single-article-page so nothing
 * here can leak to Pages, Demo Days, the Blog overview, or global
 * Header/Footer. Gutenberg core-block output (core/paragraph,
 * core/heading, core/image, core/quote, core/list, core/gallery) is
 * styled via its own plain tags/classes as direct children of
 * `.blog-article` — never a bare `h1 {}`/`p {}`/`img {}`/`blockquote {}`
 * selector.
 */

.mcb-single-article-page {
	--mcb-ink:          #27272C;
	--mcb-bone:         #FFFFFF;
	--mcb-surface:      #FBF6F3;
	--mcb-accent:       #917EBC;
	--mcb-accent-soft:  #CDCBFF;
	--mcb-tint:         #E6E6FF;

	--mcb-stone:             color-mix(in oklab, var(--mcb-ink) 11%, var(--mcb-bone));
	--mcb-ink-hair:          color-mix(in oklab, var(--mcb-ink) 7%,  var(--mcb-bone));
	--mcb-ink-line:          color-mix(in oklab, var(--mcb-ink) 13%, var(--mcb-bone));
	--mcb-tint-line:         color-mix(in oklab, var(--mcb-accent) 18%, var(--mcb-tint));
	--mcb-tint-line-strong:  color-mix(in oklab, var(--mcb-accent) 34%, var(--mcb-tint));

	--mcb-ink-72: color-mix(in oklab, var(--mcb-ink) 72%, transparent);
	/* 65%, not 56% — source's own WCAG AA fix (its newer anthracite ink
	   measured 3.55:1 against beige at 56%; 65% restores ~4.6:1). Kept
	   exactly, including the name/value mismatch, to stay byte-identical
	   with the authoritative source token. */
	--mcb-ink-56: color-mix(in oklab, var(--mcb-ink) 65%, transparent);

	--mcb-maxw:   1280px;
	--mcb-gutter: clamp(18px, 4vw, 40px);
	/* Local copy of the live global Header Site Part's own fixed height
	   (site-parts/mycabin-header/frontend.css `--pp-hdr-h`) — that
	   variable is scoped to `.pp-mycabin-header`, a DOM sibling of this
	   template's root, so it cannot be read via inheritance here. Same
	   re-declaration pattern the Blog overview Page Pack already uses
	   for its own hero top-clearance. */
	--mcb-hdr-h:  clamp(58px, 7vw, 74px);
	--mcb-sec-y-p: clamp(48px, 7vw, 104px);

	--mcb-r-pill: 999px;
	--mcb-r-card: 11px;
	--mcb-r-xs:   7px;

	--mcb-t-med: .25s;

	font-family: "Poppins", "Helvetica Neue", Helvetica, sans-serif;
	background: var(--mcb-bone);
}

/* Correction round (v0.4.1): Phase 5 never set this. Without it, any
   element that pairs a fixed `width` (or `width:100%`) with non-zero
   `padding`/`border` renders WIDER than intended under the browser's
   content-box default — exactly what made the sidebar's "See upcoming
   demo days" button (`width:100%` + `padding:0 19px` on `.btn`) push
   past its card's own edges. Applied broadly, once, the standard way. */
.mcb-single-article-page,
.mcb-single-article-page *,
.mcb-single-article-page *::before,
.mcb-single-article-page *::after {
	box-sizing: border-box;
}

/* Header correction round (v0.4.2): source's own base reset
   (styles.css line 158) is `h1, h2, h3, h4, p, blockquote, figure {
   margin: 0; }` — every spacing value in this file was written assuming
   that reset exists, since source relies entirely on explicit
   margin-top (never margin-bottom) for vertical rhythm. This file never
   had the reset itself, so every element's own BROWSER DEFAULT bottom
   margin (a <p>'s ~1em, an <h1>'s ~0.67em) was silently adding to the
   next element's own explicit margin-top — e.g. `.breadcrumb` (a <p>)
   plus `.blog-tag`'s `margin-top:16px`, or `.blog-post-header h1` plus
   `.blog-byline`'s `margin-top:20px` — compounding into visibly larger
   gaps than intended. Matches source's own selector list exactly. */
.mcb-single-article-page h1,
.mcb-single-article-page h2,
.mcb-single-article-page h3,
.mcb-single-article-page h4,
.mcb-single-article-page p,
.mcb-single-article-page blockquote,
.mcb-single-article-page figure {
	margin: 0;
}

/* Header correction round (v0.4.2): source's own sitewide "fine paper
   grain" texture (styles.css line 145-156, `body::after`) — a
   position:fixed, viewport-covering overlay, so it is visible behind
   every section on every page, not scoped to any one hero. Reproduced
   here at this template's own root using the exact same technique/
   values, matching the identical precedent already used for the Blog
   overview Page Pack (`incoming-page-packs/_build/blog-v2/frontend.css`'s
   `.pp-blog::after`, from its own v2.0.4 correction round) rather than
   added to the Design System globally, which stays out of this plugin's
   scope. `position:fixed` means this still covers the full viewport
   regardless of which element it's declared on (no ancestor here
   creates a new containing block), so it renders correctly without
   needing `position:relative` on this root. */
.mcb-single-article-page::after {
	content: "";
	position: fixed;
	inset: 0;
	z-index: 200;
	pointer-events: none;
	opacity: .05;
	background-image: radial-gradient(color-mix(in oklab, var(--mcb-ink) 55%, transparent) .5px, transparent .5px);
	background-size: 3px 3px;
}

.mcb-single-article-page a {
	color: inherit;
	text-decoration: none;
}

.mcb-single-article-page a:focus-visible,
.mcb-single-article-page button:focus-visible {
	outline: 2px solid var(--mcb-accent);
	outline-offset: 2px;
}

.mcb-single-article-page .wrap {
	max-width: var(--mcb-maxw);
	margin: 0 auto;
	padding-inline: var(--mcb-gutter);
}

/* --- Article header ---------------------------------------------------- */

.mcb-single-article-page .blog-post-header {
	padding: calc(var(--mcb-hdr-h) + clamp(24px, 4vw, 40px)) 0 0;
}

.mcb-single-article-page .breadcrumb {
	display: flex;
	align-items: center;
	gap: 8px;
	font-size: 12.5px;
	color: var(--mcb-ink-56);
}
.mcb-single-article-page .breadcrumb a:hover { color: var(--mcb-ink); }

.mcb-single-article-page .blog-tag {
	display: inline-flex;
	align-items: center;
	align-self: flex-start;
	padding: 4px 11px;
	border-radius: var(--mcb-r-pill);
	background: var(--mcb-tint);
	border: 1px solid var(--mcb-tint-line-strong);
	color: var(--mcb-accent);
	font-size: 11.5px;
	font-weight: 500;
	white-space: nowrap;
}
.mcb-single-article-page .blog-post-header .blog-tag { margin-top: 16px; }

.mcb-single-article-page .blog-post-header h1 {
	margin-top: 14px;
	font-size: clamp(28px, 4.4vw, 44px);
	line-height: 1.12;
	letter-spacing: -.02em;
	font-weight: 500;
	max-width: 24ch;
	color: var(--mcb-ink);
}

.mcb-single-article-page .blog-byline { display: flex; align-items: center; gap: 10px; }
.mcb-single-article-page .blog-post-header .blog-byline { margin-top: 20px; }

.mcb-single-article-page .blog-byline__avatar {
	width: 28px;
	height: 28px;
	flex: none;
	border-radius: var(--mcb-r-pill);
	overflow: hidden;
}
/* Scoped to the header's byline specifically, matching source's own
   documented fix (a broader `.slot` selector there once shrank the full
   hero photo to avatar size — this template never had that bug since it
   uses `.blog-byline__avatar` rather than a shared `.slot` class, but the
   36px-in-header-only sizing itself is still the source's real rule). */
.mcb-single-article-page .blog-post-header .blog-byline__avatar { width: 36px; height: 36px; }
.mcb-single-article-page .blog-byline__avatar img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
.mcb-single-article-page .blog-byline__name { font-size: 13px; font-weight: 500; color: var(--mcb-ink); }
.mcb-single-article-page .blog-byline__meta { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--mcb-ink-56); }

.mcb-single-article-page .blog-post-media {
	margin-top: clamp(24px, 4vw, 36px);
	position: relative;
	aspect-ratio: 16 / 9;
	overflow: hidden;
	background: var(--mcb-surface);
}
.mcb-single-article-page .blog-post-media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
.mcb-single-article-page .blog-post-media--no-image { background: #f0f0f1; }

/* --- Article body / sidebar layout -------------------------------------- */

.mcb-single-article-page .blog-post-section { padding: clamp(32px, 5vw, 48px) 0 var(--mcb-sec-y-p); }
.mcb-single-article-page .blog-post-layout {
	display: grid;
	grid-template-columns: 1fr;
	gap: clamp(28px, 4vw, 40px);
	align-items: start;
}
@media (min-width: 900px) {
	.mcb-single-article-page .blog-post-layout { grid-template-columns: 2fr 1fr; }
	.mcb-single-article-page .blog-sidebar { position: sticky; top: calc(var(--mcb-hdr-h) + 24px); }
}

/* --- Article content (native Gutenberg, the_content()) ------------------ */

.mcb-single-article-page .blog-article {
	max-width: 68ch;
	font-size: 15px;
	line-height: 1.75;
	font-weight: 300;
	color: var(--mcb-ink-72);
}

.mcb-single-article-page .blog-article > p { margin-top: 18px; }

.mcb-single-article-page .blog-article > h2,
.mcb-single-article-page .blog-article > h3,
.mcb-single-article-page .blog-article > h4,
.mcb-single-article-page .blog-article > h5,
.mcb-single-article-page .blog-article > h6 {
	margin-top: clamp(28px, 4vw, 36px);
	font-size: 19px;
	line-height: 1.3;
	letter-spacing: -.015em;
	font-weight: 500;
	color: var(--mcb-ink);
}

/* core/image, core/gallery. Source's own bespoke inline-photo wrapper
   (`.blog-post-media--inline`) only exists in its static prototype's
   hand-authored HTML — native Gutenberg content never emits that class —
   so real inline photos are styled through core/image's own
   `figure.wp-block-image` output instead. No border-radius, matching the
   source (only its cards — .blog-card/.blog-featured/.blog-post-cta —
   get rounded corners; full-width photos don't).
   Correction round (v0.4.1): Phase 5 left the <img> itself unconstrained
   (natural aspect ratio, width capped at 100%) — for a real uploaded
   photo whose own dimensions aren't a tidy landscape ratio, that could
   render far taller than intended. `.blog-post-media--inline`'s own
   source rule IS `aspect-ratio: 4 / 3`, so that same box (with
   object-fit: cover, so no distortion, safe for any future image) is
   applied directly to the <img>, matching the actual source visual
   result rather than the source's markup shape it can't have. */
.mcb-single-article-page .blog-article > figure {
	margin: clamp(24px, 4vw, 32px) 0;
}
.mcb-single-article-page .blog-article img {
	max-width: 100%;
	width: 100%;
	height: auto;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	display: block;
}
.mcb-single-article-page .blog-article figcaption {
	margin-top: 8px;
	font-size: 12.5px;
	line-height: 1.5;
	color: var(--mcb-ink-56);
	text-align: center;
}
.mcb-single-article-page .blog-article > figure.wp-block-gallery {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
	gap: 12px;
}

.mcb-single-article-page .blog-article > ul,
.mcb-single-article-page .blog-article > ol {
	margin-top: 18px;
	padding-left: 1.2em;
	font-size: 15px;
	line-height: 1.75;
	font-weight: 300;
	color: var(--mcb-ink-72);
}
.mcb-single-article-page .blog-article li + li { margin-top: 6px; }

/* core/quote — the source's own prominent pull-quote treatment,
   reproduced on WordPress's real quote-block output rather than a custom
   quote block, so editors never need anything but the normal block. */
.mcb-single-article-page .blog-article > blockquote {
	margin: clamp(24px, 4vw, 32px) 0;
	padding-left: clamp(18px, 2.4vw, 24px);
	border-left: 3px solid var(--mcb-accent-soft);
	font-size: 18px;
	line-height: 1.5;
	font-weight: 400;
	font-style: italic;
	color: var(--mcb-ink);
}
.mcb-single-article-page .blog-article > blockquote p { margin: 0; }
.mcb-single-article-page .blog-article > blockquote cite {
	display: block;
	margin-top: 8px;
	font-size: 13px;
	font-style: normal;
	color: var(--mcb-ink-56);
}

/* First content block shouldn't carry a leading gap, whichever block
   type the editor happened to start the article with. */
.mcb-single-article-page .blog-article > p:first-child,
.mcb-single-article-page .blog-article > h2:first-child,
.mcb-single-article-page .blog-article > h3:first-child,
.mcb-single-article-page .blog-article > h4:first-child,
.mcb-single-article-page .blog-article > h5:first-child,
.mcb-single-article-page .blog-article > h6:first-child,
.mcb-single-article-page .blog-article > figure:first-child,
.mcb-single-article-page .blog-article > blockquote:first-child,
.mcb-single-article-page .blog-article > ul:first-child,
.mcb-single-article-page .blog-article > ol:first-child {
	margin-top: 0;
}

/* --- Sidebar: share + Demo Days CTA -------------------------------------- */

.mcb-single-article-page .blog-sidebar {
	display: flex;
	flex-direction: column;
	gap: clamp(20px, 3vw, 28px);
}

.mcb-single-article-page .blog-share { display: flex; align-items: center; gap: 12px; }
.mcb-single-article-page .blog-share span { font-size: 12.5px; color: var(--mcb-ink-56); }
.mcb-single-article-page .blog-share__icons { display: flex; gap: 8px; }
.mcb-single-article-page .blog-share__icons a,
.mcb-single-article-page .blog-share__icons button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	padding: 0;
	border-radius: var(--mcb-r-pill);
	border: 1px solid var(--mcb-ink-line);
	background: none;
	color: var(--mcb-ink-72);
	cursor: pointer;
}
.mcb-single-article-page .blog-share__icons a:hover,
.mcb-single-article-page .blog-share__icons button:hover {
	background: var(--mcb-surface);
	color: var(--mcb-ink);
}

.mcb-single-article-page .blog-post-cta {
	padding: clamp(20px, 2.6vw, 26px);
	background: var(--mcb-tint);
	border: 1px solid var(--mcb-tint-line-strong);
	border-radius: var(--mcb-r-card);
}
.mcb-single-article-page .blog-post-cta h3 { font: 500 16px "Poppins", sans-serif; letter-spacing: -.015em; color: var(--mcb-ink); }
.mcb-single-article-page .blog-post-cta p { margin-top: 6px; font-size: 13px; line-height: 1.55; font-weight: 300; color: var(--mcb-ink-72); }
.mcb-single-article-page .blog-post-cta .btn { margin-top: 14px; width: 100%; }

/* Shared button base, scoped locally — same values as the Blog overview
   Page Pack's own `.pp-blog .btn`/`.btn--ink` (different CSS ownership
   boundary, identical design-system values). */
.mcb-single-article-page .btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	height: 38px;
	padding: 0 19px;
	border-radius: var(--mcb-r-pill);
	font: 500 15px "Poppins", sans-serif;
	white-space: nowrap;
	cursor: pointer;
	border: 0;
	transition: background var(--mcb-t-med), color var(--mcb-t-med);
}
.mcb-single-article-page .btn--ink { background: var(--mcb-ink); color: var(--mcb-bone); }
.mcb-single-article-page .btn--ink:hover { background: var(--mcb-accent); color: var(--mcb-bone); }

/* --- Latest posts -------------------------------------------------------- */

/* Correction round (v0.4.1), USER-APPROVED SOURCE OVERRIDE: source's own
   `.blog-related-section` has zero top padding (0 0 var(--sec-y-p)) —
   the user explicitly wants more breathing room above "Latest posts"
   than the source itself has. Do not revert this to 0 in a future
   source-parity audit; it is a deliberate deviation, not a bug. Value
   matches this template's own established top-padding rhythm (same
   clamp() used by .blog-post-section above). */
.mcb-single-article-page .blog-related-section { padding: clamp(32px, 5vw, 48px) 0 var(--mcb-sec-y-p); background: var(--mcb-surface); }
.mcb-single-article-page .blog-related-section > .wrap > h2 {
	font-size: clamp(20px, 2.8vw, 26px);
	letter-spacing: -.02em;
	font-weight: 500;
	color: var(--mcb-ink);
}

.mcb-single-article-page .blog-grid {
	margin-top: clamp(32px, 5vw, 48px);
	display: grid;
	grid-template-columns: 1fr;
	gap: clamp(16px, 2.2vw, 22px);
}
@media (min-width: 900px) {
	.mcb-single-article-page .blog-grid { grid-template-columns: repeat(3, 1fr); }
}

.mcb-single-article-page .blog-card {
	display: flex;
	flex-direction: column;
	background: var(--mcb-bone);
	border: 1px solid var(--mcb-stone);
	border-radius: var(--mcb-r-card);
	overflow: hidden;
}
.mcb-single-article-page .blog-card__media { position: relative; aspect-ratio: 4 / 3; }
.mcb-single-article-page .blog-card__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
.mcb-single-article-page .blog-card__body {
	padding: clamp(18px, 2.2vw, 22px);
	display: flex;
	flex-direction: column;
	gap: 10px;
	flex: 1;
}
.mcb-single-article-page .blog-card__body .blog-tag { margin-bottom: 2px; }
.mcb-single-article-page .blog-card__body h3 { font-size: 17px; line-height: 1.25; letter-spacing: -.015em; font-weight: 500; color: var(--mcb-ink); }
.mcb-single-article-page .blog-card__body p { font-size: 13px; line-height: 1.55; font-weight: 300; color: var(--mcb-ink-72); flex: 1; }
.mcb-single-article-page .blog-card__foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 4px; }
.mcb-single-article-page .blog-card__foot .read-time { font-size: 12px; color: var(--mcb-ink-56); }

/* --- Newsletter ------------------------------------------------------------ */

.mcb-single-article-page .blog-newsletter-section {
	padding: clamp(36px, 5vw, 56px) 0;
	background: var(--mcb-tint);
	border-block: 1px solid var(--mcb-tint-line);
}
.mcb-single-article-page .blog-newsletter-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: clamp(20px, 3vw, 32px);
}
.mcb-single-article-page .blog-newsletter-row h2 { font-size: clamp(22px, 3vw, 28px); letter-spacing: -.02em; font-weight: 500; color: var(--mcb-ink); }
.mcb-single-article-page .blog-newsletter-row p { margin-top: 6px; font-size: 13.5px; font-weight: 300; color: var(--mcb-ink-72); max-width: 44ch; }
/* Correction round (v0.4.1), USER-APPROVED VISUAL OVERRIDE: source's own
   `.blog-newsletter-form` has no explicit `align-items`, defaulting to
   flex's own `stretch` — the input (sized by its own padding) and the
   button (a fixed `height: 38px` from `.btn`) can end up visibly
   uneven. `align-items: center` guarantees both sit on the same
   center line regardless of their own box heights, at the user's
   explicit request.
   Correction round (v0.4.3) — LIVE-VERIFIED root cause of the input
   shrinking 10px (exactly one `gap` unit) and the button following it
   left on real focus: a password-manager BROWSER EXTENSION (confirmed
   live via DevTools: NordPass) inserts its own `<nordpass-icon>` custom
   element as a genuine DOM child of THIS form the moment the email
   input is focused — `document.querySelector('.blog-newsletter-form
   ').children` measured 3 children unfocused, 4 focused. That extra,
   effectively-zero-width element still counts as one more item on
   `display:flex`'s single row, so its own `gap:10px` neighbor-spacing
   was being charged against the only flexible item (the input,
   `flex-grow:1`) even though the injected element itself takes no
   visible width — this was never CSS this template controls, and can
   happen with any extension that behaves the same way, not just this
   one. Switched to `display: grid; grid-template-columns: minmax(0,
   1fr) auto;` (exactly two explicit columns: input, button) — CSS
   Grid's default auto-flow places any THIRD, unexpected child into a
   new implicit ROW rather than stealing width from the two explicit
   columns, making this row structurally immune to an extension
   inserting extra DOM here, not just to this one extension's specific
   behavior.
   Follow-up, same live session: that fix removed the HORIZONTAL shift
   but left a VERTICAL one — the injected element's own new implicit
   row still has real height (measured live: form height 47px unfocused
   -> 57px focused, a full extra row), which `align-items: center` on
   the OUTER `.blog-newsletter-row` then re-centers around, visibly
   nudging the whole form up/down. `grid-auto-rows: 0` alone was tried
   first and re-measured live as INSUFFICIENT: form height still grew
   47px -> 57px. Root cause (CSS Grid spec, not a guess): a grid item's
   default `min-height` is `auto`, which resolves to its own content's
   min-content size and can force its track to grow past an explicit
   `grid-auto-rows: 0` — the exact same "automatic minimum size" rule
   flexbox is more commonly known for. The spec's own fix is to give the
   ITEM (not the track) a non-`visible` `overflow`, which resets that
   item's automatic minimum size to 0. The injected element's own tag
   name isn't predictable (any extension could do this, not just this
   one) so it's targeted generically: every direct child of this row —
   `overflow: hidden` costs nothing for the label (already visually
   hidden), input, or button (none rely on visible overflow to render
   correctly), and an extension's own icon typically positions its
   actual visible badge via its own `position: fixed`/`absolute` CSS,
   which escapes an ancestor's `overflow: hidden` clipping entirely — so
   this does not hide the icon, only stops it from being able to grow
   this row. Re-measured live after this fix (same real mouse click):
   form height, form top, and every descendant's own top position are
   now identical focused vs. unfocused, in addition to the horizontal
   geometry already fixed, and the icon still renders normally. */
/* `grid-template-rows: auto` (one EXPLICIT row, sized naturally to
   input/button's own real content) is required alongside `grid-auto-
   rows: 0` — without it, `grid-template-rows` defaults to `none`, which
   means there is no "explicit" row at all and EVERY row (including
   the real, first one) is sized by `grid-auto-rows`, collapsing the
   entire form to 0 height. Live-verified this exact regression after
   deploying `grid-auto-rows: 0` alone. */
/* `gap: 10px` (the single-value shorthand) sets BOTH column-gap AND
   row-gap. That row-gap still renders between row 1 (explicit) and row
   2 (the injected element's own implicit row) even though row 2 itself
   is 0px tall — live-verified: form height stayed 57px (47 + 10 row-
   gap) after the two fixes above. Only a column-gap (between input and
   button) is ever wanted here — there is no legitimate second row —
   so row-gap is set to 0 explicitly instead of relying on the `gap`
   shorthand. */
.mcb-single-article-page .blog-newsletter-form { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: auto; grid-auto-rows: 0; align-items: center; column-gap: 10px; row-gap: 0; flex: 0 1 420px; min-width: 260px; }
.mcb-single-article-page .blog-newsletter-form > * { overflow: hidden; }
/* 0.9.1: safety valve for genuinely narrow/mobile widths, matching the
   Blog archive newsletter's own identical breakpoint — at very small
   viewports `min-width:260px` above can no longer share space with the
   button on one row without squeezing the email field uncomfortably
   narrow, so input and button stack instead. No change above 480px. */
@media (max-width: 480px) {
  .mcb-single-article-page .blog-newsletter-form { grid-template-columns: 1fr; }
}
.mcb-single-article-page .blog-newsletter-form input {
	min-width: 0;
	width: 100%;
	font: 400 14px "Poppins", sans-serif;
	color: var(--mcb-ink);
	background: var(--mcb-bone);
	border: 1px solid var(--mcb-ink-hair);
	border-radius: var(--mcb-r-xs);
	padding: 12px 14px;
	outline: none;
}
.mcb-single-article-page .blog-newsletter-form input:focus-visible { outline: 2px solid var(--mcb-accent-soft); outline-offset: 2px; }
.mcb-single-article-page .blog-newsletter-form input::placeholder { color: var(--mcb-ink-56); }

/* --- States carried over from Phase 3 (still needed, functional) -------- */

.mcb-single-article-page .mcb-copy-status:empty { display: none; }

.mcb-single-article-page .screen-reader-text {
	border: 0;
	clip: rect(1px, 1px, 1px, 1px);
	clip-path: inset(50%);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
	word-wrap: normal !important;
}

/* Correction round (v0.4.1): removed. This rule matched the form's
   `[data-mcb-newsletter-placeholder]` marker attribute regardless of
   whether the fields were actually `disabled` — so it kept visually
   muting the Subscribe button even after the `disabled` attribute
   itself was removed from the template (article-newsletter.php), which
   is what the user actually reported. The marker attribute stays on
   the form (a genuine, harmless "no provider hooked yet" flag future
   integration code can still check for) — it just no longer drives any
   dimmed styling. */
