/**
 * post — CPT stylesheet (W1 blog). Loaded by inc/enqueue.php ONLY on blog
 * articles and the blog listing (rmd_enqueue_cpt_style + rmd_is_blog_view).
 *
 * Ported from redesign-blog/ — _src/_shared.css, _src/_promo-card.css and the
 * per-page <style> blocks of blog-single / blog-archive, merged into the one
 * file the per-CPT convention asks for. The mockups stay the design source and
 * are never deployed; this is the theme's copy.
 *
 * ── Two things changed in the port, both load-bearing ───────────────────────
 * 1. EVERYTHING IS SCOPED TO `.rmd-bl`, the class both templates put on <main>.
 *    The mockups left the shared components unscoped because a standalone file
 *    has nothing to collide with. Here .rmd-card, .rmd-chip, .rmd-btn and
 *    .rmd-wrap share a page with parent Vault, UiCore and Elementor. Same rule
 *    as case_study.css, which scopes to `.rmd-case`.
 * 2. `--shadow-card` was RENAMED to `--sh-card` (and its pair to `--sh-lift`).
 *    main.css publishes a --shadow-card of its own, with a different value;
 *    redeclaring the name on .rmd-bl would silently shadow the theme token for
 *    everything inside the blog. Different value, different name.
 *
 * ── @layer components is load-bearing ───────────────────────────────────────
 * main.css establishes the layer order and puts its component rules in
 * `components`. Rejoining that layer keeps Tailwind UTILITIES winning over
 * these rules; an unlayered file would silently beat every utility class in the
 * templates. This file must load AFTER main.css — enqueue.php declares that
 * dependency, don't drop it.
 *
 * Hand-written plain CSS: no @apply, no Tailwind functions, only var(--token).
 * No build step — edit and deploy.
 */

@layer components {

/* ══════════════════════════════════════════════════════════════════════════
   TOKENS
   Mapped onto main.css's @theme tokens where one exists, so a palette change
   in src/tailwind.css reaches the blog too; the literal is the fallback that
   keeps this sheet readable on its own. The rest (gradients, the reading
   measure, the type scale) have no @theme equivalent and are declared here.
   ══════════════════════════════════════════════════════════════════════════ */

.rmd-bl {
	--ink: var(--color-ink, #041135);
	--purp: var(--color-purp, #3943FF);
	--purpsoft: var(--color-purpsoft, #F3F4FF);
	--slight: var(--color-slight, #596980);
	--bord: var(--color-bord, #E9EAF2);
	--redder: var(--color-redder, #E4004D);
	--orng: var(--color-orng, #FA9329);
	--nuk: var(--color-nuk, #F9FAFB);

	--grad-cta: linear-gradient(90deg, #D7045A 50%, #FC8831 100%);
	--grad-edge: linear-gradient(155deg, #3943FF 58%, #E4004D 85%, #FA9329 100%);
	--sh-card: 0 8px 26px rgba(4, 17, 53, .05);
	--sh-lift: 0 20px 40px -20px rgba(4, 17, 53, .18);

	/* THE READING MEASURE — and, since 13/08, the ONLY width in the column.
	   ~72 characters per line at 19px, inside the 45–75 the eye tracks without
	   losing its place. In pixels and not in `ch`: `ch` is the width of the "0",
	   and Poppins' zero is wide — 68ch came out at 714px, i.e. 95 characters, the
	   opposite of the intent.

	   IT USED TO BE 620, AGAINST A 720 COLUMN, and the 100px offset was the
	   mockup's deliberate rhythm: text short, figures wide. That reads as rhythm
	   in a page of prose with the occasional picture. It does not survive this
	   blog, where the articles carry tables and stat cards every few paragraphs —
	   the right edge then jumps 100px in and out on almost every block, and what
	   was meant as a breath reads as things failing to line up. One edge now:
	   text, figures, tables and components all stop at the same place. Restoring
	   the offset means putting --measure back to 620 and this to 680, nothing
	   more.

	   680 → 640 ON 17/08/2026. The body is back at 19px after a pass at 17.5,
	   but the column stayed narrow: 640px of 19px Poppins measures about 66
	   characters, which is the comfortable end of the 60–70 range, where 680 sat
	   nearer 70 and every line asked a little more of the eye. The leading is the
	   variable that was actually wrong — 1.9 put 36px between baselines of 19px
	   text, which is what read as "too much space". 1.72 is the editorial value
	   for this size. */
	--measure: 640px;

	--lh-body: 1.72;
	--lh-text: 1.72;

	/* THE TYPE SCALE. Six roles, six values, for both templates. Any new size
	   must fit one of these roles, or the scale scatters again.
	     --t-label  uppercase eyebrows, chips, counters, table headers
	     --t-meta   dates, breadcrumbs, card footers, credits
	     --t-ui     buttons, filters, contents, search, arrow links, captions
	     --t-sec    card excerpts, tables, bio, promo-card copy
	     --t-lead   callouts, FAQ, key-points, steps
	     --t-body   the article's running text
	   Headings keep their own shorter run: 18 (card) · 21 (h3) · 23 (promo) ·
	   26 (section title), then the clamp()s of h1/h2. */
	--t-label: 11.5px;
	--t-meta: 13px;
	--t-ui: 15px;
	--t-sec: 16px;
	--t-lead: 17px;
	--t-body: 19px;

	--wrap: var(--container-content, 1200px);

	font-family: var(--font-sans, 'Poppins', ui-sans-serif, system-ui, sans-serif);
	color: var(--ink);
	background: #fff;
	-webkit-font-smoothing: antialiased;
	line-height: 1.5;
}

/* Neither the injected chrome nor parent Vault sets box-sizing, and every fixed
   height then comes out padding-taller than asked — the opening band set to
   440px measured 508. Scoped to .rmd-bl only: the header and footer are shared
   with the case studies and were laid out in content-box, so their model is not
   changed under their feet. */
.rmd-bl, .rmd-bl *, .rmd-bl *::before, .rmd-bl *::after { box-sizing: border-box; }

.rmd-bl :where(h1, h2, h3, h4, p, ul, ol, li, figure, blockquote, dl, dd) { margin: 0; padding: 0; }
.rmd-bl :where(ul, ol) { list-style: none; }
/* Bold stops at 600 everywhere; without this a <strong> outside .rmd-prose falls
   back to the browser's `bolder` (700) and a fifth weight appears. `:where()` so
   component rules keep the upper hand. */
.rmd-bl :where(strong, b) { font-weight: 600; }
/* Neutralise the parent theme's link colour at ZERO specificity. Written
   `.rmd-bl a` this would be (0,1,1) and beat every single-class component rule:
   the white button on the navy promo card would inherit the card's white and
   disappear. `:where()` adds nothing, so the rule only applies by default. */
:where(.rmd-bl a) { color: inherit; }
.rmd-bl img { max-width: 100%; display: block; }

/* One focus rule for the whole design, declared once rather than added
   component by component — that is how one gets forgotten. */
.rmd-bl :where(a, button, summary, input, [tabindex]):focus-visible {
	outline: 3px solid var(--purp);
	outline-offset: 3px;
	border-radius: 4px;
}

.rmd-bl .rmd-wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 24px; }
.rmd-bl .rmd-sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }

/* ══════════════════════════════════════════════════════════════════════════
   SHARED COMPONENTS
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Chips ────────────────────────────────────────────────────────────────
   One chip in the whole blog, taken as-is from .rmd-cscard__chip. No colour
   code per section: the section is written in the chip's text, and tinting it
   would only add a second alphabet to learn. */
.rmd-bl .rmd-chip {
	display: inline-flex; align-items: center; align-self: flex-start;
	background: var(--purpsoft); color: var(--purp);
	font-size: var(--t-label); font-weight: 600; letter-spacing: .04em;
	padding: 5px 12px; border-radius: 9999px;
	text-decoration: none;
}
.rmd-bl a.rmd-chip:hover { background: #E7E9FF; }

/* The footer's eyebrow (.rmd-fd-lbl), in a light-background version. */
.rmd-bl .rmd-lbl {
	font-size: var(--t-label); font-weight: 600; letter-spacing: .14em;
	text-transform: uppercase; color: var(--slight);
}

/* ── Buttons ──────────────────────────────────────────────────────────────
   The solid gradient is reserved for the primary action: the header button and
   the footer button already carry it, and a third decorative use would cost it
   its value as a signal. */
.rmd-bl .rmd-btn {
	position: relative; overflow: hidden;
	display: inline-flex; align-items: center; justify-content: center; gap: 10px;
	border: 1px solid transparent; border-radius: 10px;
	padding: 14px 26px;
	font: inherit; font-size: var(--t-ui); font-weight: 500; line-height: 1.2;
	text-decoration: none; white-space: nowrap; cursor: pointer;
	transition: transform .15s ease, opacity .15s ease, background-color .15s ease, border-color .15s ease, color .15s ease;
}
.rmd-bl .rmd-btn svg { flex: 0 0 auto; }

.rmd-bl .rmd-btn--cta { color: #fff; background-image: var(--grad-cta); box-shadow: 0 14px 34px -18px rgba(215, 4, 90, .6); }
.rmd-bl .rmd-btn--cta:hover { opacity: .95; }
.rmd-bl .rmd-btn--cta::before {
	content: ''; position: absolute; top: 0; left: -75%; width: 50%; height: 100%;
	background: linear-gradient(120deg, transparent, rgba(255, 255, 255, .45), transparent);
	transform: skewX(-20deg); animation: rmdCtaShine 3s ease-in-out infinite;
}
.rmd-bl .rmd-btn--ghost { color: var(--ink); background: #fff; border-color: var(--bord); }
/* The secondary action turns violet, not grey: it sits on a white card where
   the old --nuk hover was invisible. Violet is the brand's link colour — it
   announces a target without reaching for the gradient next to it. */
.rmd-bl .rmd-btn--ghost:hover { color: var(--purp); background: var(--purpsoft); border-color: #C9CEFF; }
.rmd-bl .rmd-btn--onink { color: var(--ink); background: #fff; }
.rmd-bl .rmd-btn--onink:hover { background: rgba(255, 255, 255, .88); }
.rmd-bl .rmd-btn--outink { color: #fff; background: transparent; border-color: rgba(255, 255, 255, .28); }
.rmd-bl .rmd-btn--outink:hover { background: rgba(255, 255, 255, .08); border-color: rgba(255, 255, 255, .5); }
.rmd-bl .rmd-btn--sm { padding: 10px 18px; }

/* The shine keyframes the CTA button calls, declared here as case_study.css and
   rmd-chrome.css each declare it — IDENTICALLY, and that is the point: a sheet
   that uses the animation carries its definition, so no stylesheet depends on
   another one being loaded to make its own button move. The mockup's build
   script had synthesised a 60% stop; the theme's value is 25%, and the theme's
   is the one that ships. */
@keyframes rmdCtaShine {
	0%   { left: -75%; }
	25%  { left: 125%; }
	100% { left: 125%; }
}

/* Arrow link — same red and same slide as .rmd-cscard__more. */
.rmd-bl .rmd-more {
	display: inline-flex; align-items: center; gap: 8px;
	color: var(--redder); font-size: var(--t-ui); font-weight: 600; text-decoration: none;
	/* 24px minimum height: the link measured 23px and missed the minimum touch
	   target (WCAG 2.5.8). min-height rather than padding — it clears the
	   threshold without moving what surrounds it. */
	min-height: 24px;
}
.rmd-bl .rmd-more svg { transition: transform .25s ease; }
.rmd-bl .rmd-more:hover svg { transform: translateX(4px); }

/* ── Breadcrumb ─────────────────────────────────────────────────────────── */
.rmd-bl .rmd-crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: var(--t-meta); color: var(--slight); }
.rmd-bl .rmd-crumbs a { text-decoration: none; }
.rmd-bl .rmd-crumbs a:hover { color: var(--ink); text-decoration: underline; }
.rmd-bl .rmd-crumbs li { display: inline-flex; align-items: center; gap: 8px; }
.rmd-bl .rmd-crumbs li + li::before { content: '›'; color: #B9BFCE; }
.rmd-bl .rmd-crumbs [aria-current] { color: var(--ink); font-weight: 500; max-width: 100%; }
/* The article's own name closes the trail, one ellipsed line: the full title
   sits directly below as the H1 — the crumb locates, the H1 announces, and a
   wrapping crumb would say everything twice. */
.rmd-bl .rmd-crumbs__here { max-width: 34ch; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ── Byline ───────────────────────────────────────────────────────────────
   The portrait carries the same red ring as the footer's expert band
   (.rmd-fd-face-img). That is what makes a face read as "someone to talk to"
   rather than stock illustration; the blog inherits the sign. */
.rmd-bl .rmd-by { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 18px; }
/* 48px (04/09, was 44): the face is now always there — portrait, Gravatar or
   silhouette by rmd_author_portrait_html() — and carries the credit with the
   name; the ring is the same red the author page and the footer wear. */
.rmd-bl .rmd-by__face { flex: 0 0 auto; width: 48px; height: 48px; border-radius: 50%; object-fit: cover; object-position: top center; border: 2px solid var(--redder); background: var(--nuk); }
.rmd-bl .rmd-by__who { font-size: var(--t-ui); font-weight: 600; }
/* The role after the name, the way a press byline reads: “Ayoub Rhillane · SEO
   expert”. Regular weight and slate so the name stays the credit; on a narrow
   screen it wraps under the name and the dot goes with it. */
.rmd-bl .rmd-by__role { font-weight: 400; color: var(--slight); }
.rmd-bl .rmd-by__role::before { content: '·'; margin: 0 8px; color: #B9BFCE; }
/* The byline name links to the author archive (26/08). Ink at rest — a violet
   name would outrank the title above it — the link only shows its hand on
   hover, same manner as the breadcrumb's. */
.rmd-bl .rmd-by__who a { text-decoration: none; }
.rmd-bl .rmd-by__who a:hover { color: var(--purp); text-decoration: underline; }
.rmd-bl .rmd-by__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; font-size: var(--t-meta); color: var(--slight); }
.rmd-bl .rmd-by__meta li + li::before { content: '·'; margin-right: 10px; color: #B9BFCE; }
.rmd-bl .rmd-by__meta li { display: inline-flex; align-items: center; }

/* ── Article card ─────────────────────────────────────────────────────────
   Twin of .rmd-cscard (assets/css/cpt/case_study.css): same radius, border,
   shadow and gradient-edge lift on hover. An article card and a case-study
   card must be able to share a grid without a visible seam. */
.rmd-bl .rmd-card {
	display: flex; flex-direction: column;
	background: #fff; border: 1px solid var(--bord); border-radius: 16px; overflow: hidden;
	box-shadow: var(--sh-card);
	transition: transform .3s ease, box-shadow .3s ease, border-color .3s ease;
}
.rmd-bl .rmd-card__link { display: flex; flex-direction: column; height: 100%; color: inherit; text-decoration: none; }
.rmd-bl .rmd-card__media { position: relative; aspect-ratio: 16 / 10; background: var(--nuk); overflow: hidden; }
.rmd-bl .rmd-card__image { width: 100%; height: 100%; object-fit: cover; display: block; }
.rmd-bl .rmd-card__body { display: flex; flex-direction: column; flex: 1; padding: 22px 22px 20px; }
.rmd-bl .rmd-card__title { margin-top: 14px; color: var(--ink); font-size: 18px; font-weight: 600; line-height: 1.3; letter-spacing: -.01em; }
.rmd-bl .rmd-card__ex {
	margin-top: 10px; color: var(--slight); font-size: var(--t-sec); line-height: var(--lh-text);
	display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.rmd-bl .rmd-card__foot {
	display: flex; align-items: center; gap: 10px;
	margin-top: auto; padding-top: 16px;
	font-size: var(--t-meta); color: var(--slight);
}
.rmd-bl .rmd-card__foot .rmd-card__sep { color: #B9BFCE; }
.rmd-bl .rmd-card:hover {
	transform: translateY(-3px);
	box-shadow: var(--sh-lift);
	border-color: transparent;
	background-image: linear-gradient(#fff, #fff), var(--grad-edge);
	background-origin: border-box;
	background-clip: padding-box, border-box;
}

/* No featured image → the same branded placeholder a thumbnail-less case study
   renders (.rmd-cscard__media--empty + .rmd-cscard__placeholder-logo). The mark
   is an <img> placed by the template, not a background on the frame: the .5
   opacity must touch the LOGO only — on the frame it would wash out the tint
   behind it too. */
.rmd-bl .rmd-card__media--empty {
	background: linear-gradient(135deg, #EEF0FF 0%, #FBFCFE 55%, #F6F4FF 100%);
}
.rmd-bl .rmd-card__placeholder {
	display: flex; align-items: center; justify-content: center;
	width: 100%; height: 100%;
}
.rmd-bl .rmd-card__placeholder-logo { width: 46%; max-width: 188px; height: auto; opacity: .5; }

/* Reading time — the one figure a reader checks before clicking. */
.rmd-bl .rmd-clock { display: inline-flex; align-items: center; gap: 6px; }
.rmd-bl .rmd-clock svg { width: 13px; height: 13px; flex: none; opacity: .8; }

/* ── The Google result ────────────────────────────────────────────────────
   The object of the trade, drawn in HTML rather than captured as an image: it
   resizes without pixelating, it translates, and it is fixed in one line the
   day Google redraws its results. One scale to set — everything is in em, the
   container gives the font-size (9.5px in a promo card, 14px as a figure).

   Kept in the theme even though no template prints one today: it is what the
   promo card below shows by default, and an editor pasting that markup into a
   Custom HTML block gets the component whole. */
.rmd-bl .rmd-serp {
	display: flex; flex-direction: column; gap: .85em;
	font-size: 13px;
	background: #fff; border: 1px solid var(--bord); border-radius: .9em; padding: 1em;
}
.rmd-bl .rmd-serp__q {
	display: flex; align-items: center; gap: .6em;
	border: 1px solid var(--bord); border-radius: 9999px; padding: .5em .9em;
	font-size: .92em; color: var(--slight);
}
.rmd-bl .rmd-serp__q svg { width: 1em; height: 1em; flex: none; opacity: .55; }
.rmd-bl .rmd-serp__r { display: grid; gap: .28em; }
.rmd-bl .rmd-serp__u { display: flex; align-items: center; gap: .5em; font-size: .76em; color: var(--slight); }
.rmd-bl .rmd-serp__fav { flex: none; width: 1.5em; height: 1.5em; border-radius: 50%; background-image: var(--grad-edge); }
.rmd-bl .rmd-serp__h { font-size: .96em; font-weight: 500; line-height: 1.3; color: #1A0DAB; }
.rmd-bl .rmd-serp__d { font-size: .78em; line-height: 1.45; color: var(--slight); }
.rmd-bl .rmd-serp__r--win { position: relative; padding-left: .9em; }
.rmd-bl .rmd-serp__r--win::before {
	content: ''; position: absolute; left: 0; top: .1em; bottom: .1em;
	width: 3px; border-radius: 3px; background: var(--grad-cta);
}
.rmd-bl .rmd-serp__r--win .rmd-serp__h { color: var(--purp); }
/* Competitors: the shape is enough — text there would add nothing and invent
   brand names. */
.rmd-bl .rmd-serp__bar { height: .55em; border-radius: .3em; background: var(--bord); }
.rmd-bl .rmd-serp__bar--s { width: 55%; }
.rmd-bl .rmd-serp__bar--m { width: 78%; }
.rmd-bl .rmd-serp__pos {
	display: inline-flex; align-items: center; gap: .45em; align-self: flex-start;
	background: rgba(22, 179, 100, .1); color: #0F8F4E;
	font-size: .72em; font-weight: 600; letter-spacing: .03em;
	padding: .35em .8em; border-radius: 9999px;
}

/* ── Section heading ──────────────────────────────────────────────────────── */
.rmd-bl .rmd-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 16px 32px; }
.rmd-bl .rmd-head__t { font-size: 26px; font-weight: 500; letter-spacing: -.02em; line-height: 1.15; }
.rmd-bl .rmd-head__t .thin { font-weight: 300; color: var(--slight); }
.rmd-bl .rmd-head__s { margin-top: 10px; max-width: 58ch; font-size: var(--t-sec); line-height: var(--lh-text); color: var(--slight); }

/* ══════════════════════════════════════════════════════════════════════════
   THE PROMO CARD
   The requested component (reference: hims.com/blog). Five variants, ONE
   markup — only the container class changes.

     .rmd-promo             Google result on the right, two actions  (default)
     .rmd-promo--photo      the visual becomes an image
     .rmd-promo--flat       no visual, one action                    (mid-text)
     .rmd-promo--ink        navy, end of article
     .rmd-promo--stack      visual on top, for a grid cell

   It stops at four lines of copy. A card that grows becomes a section, and the
   reader skips it like an ad.

   NO TEMPLATE PRINTS ONE YET — there are no fields for it. The CSS ships so an
   editor can paste the markup into a Custom HTML block and get the component
   whole; giving it an authoring UI (ACF, or a block) is its own piece of work.
   Dosage, when that happens: one card per third of an article, three maximum,
   never before the first chapter.
   ══════════════════════════════════════════════════════════════════════════ */

.rmd-bl .rmd-promo {
	position: relative;
	display: flex; align-items: center; gap: 26px;
	background: #fff;
	border: 1px solid var(--bord); border-radius: 18px;
	padding: 22px;
	box-shadow: var(--sh-card);
	transition: transform .3s ease, box-shadow .3s ease, border-color .3s ease;
}

/* The lift is the case-study card's: gradient border, 3px rise. The card is not
   clickable as a whole (its two buttons go to two different places), so the lift
   fires on hover only, never on focus — it would announce a target that is not
   there. */
.rmd-bl .rmd-promo:hover {
	transform: translateY(-3px);
	box-shadow: var(--sh-lift);
	border-color: transparent;
	background-image: linear-gradient(#fff, #fff), var(--grad-edge);
	background-origin: border-box;
	background-clip: padding-box, border-box;
}

.rmd-bl .rmd-promo__main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; }
.rmd-bl .rmd-promo__t {
	margin-top: 12px;
	font-size: 23px; font-weight: 500; letter-spacing: -.02em; line-height: 1.2;
	color: var(--ink);
	text-wrap: balance;
}
.rmd-bl .rmd-promo__p { margin-top: 8px; max-width: 46ch; font-size: var(--t-sec); line-height: var(--lh-text); color: var(--slight); }
.rmd-bl .rmd-promo__acts { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }

/* Fixed width, stretched height: the cards do not all carry the same amount of
   copy, and a free-ratio image would make the height jump from one card to the
   next inside one article. */
.rmd-bl .rmd-promo__media {
	flex: 0 0 188px; align-self: stretch; min-height: 168px;
	position: relative; overflow: hidden;
	border-radius: 12px; background: #fff; border: 1px solid var(--bord);
}
.rmd-bl .rmd-promo .rmd-serp {
	height: 100%; justify-content: center;
	font-size: 9.5px; border: 0; border-radius: 0; padding: 1.2em;
}

/* ── Image variant ──────────────────────────────────────────────────────── */
.rmd-bl .rmd-promo--photo .rmd-promo__media {
	background: linear-gradient(135deg, #EEF0FF 0%, #FBFCFE 55%, #F6F4FF 100%);
	border-color: transparent;
}
.rmd-bl .rmd-promo--photo .rmd-promo__media img { position: relative; width: 100%; height: 100%; object-fit: cover; }

/* ── Navy variant — end of article ──────────────────────────────────────────
   Same navy as the footer, so the card announces the contact band that follows
   instead of competing with it. It used to carry the footer's gradient rule on
   its top edge too; the owner cut it on 09/09 (same call as the flat card's
   bar: it read as decoration). The navy ground, the white button and the
   compact Google result are the whole signature. */
.rmd-bl .rmd-promo--ink { background: var(--ink); border-color: var(--ink); color: #fff; overflow: hidden; }
.rmd-bl .rmd-promo--ink .rmd-promo__t { color: #fff; }
.rmd-bl .rmd-promo--ink .rmd-promo__p { color: rgba(255, 255, 255, .62); }
.rmd-bl .rmd-promo--ink .rmd-chip { background: rgba(255, 255, 255, .1); color: #fff; }
.rmd-bl .rmd-promo--ink .rmd-promo__media { background: rgba(255, 255, 255, .06); border-color: rgba(255, 255, 255, .1); }
.rmd-bl .rmd-promo--ink .rmd-serp { background: rgba(255, 255, 255, .06); }
.rmd-bl .rmd-promo--ink .rmd-serp__u { color: rgba(255, 255, 255, .6); }
.rmd-bl .rmd-promo--ink .rmd-serp__h { color: #fff; }
.rmd-bl .rmd-promo--ink .rmd-serp__bar { background: rgba(255, 255, 255, .16); }
/* No gradient border here: on navy it disappears. The card rises, that is all. */
.rmd-bl .rmd-promo--ink:hover { background-image: none; border-color: var(--ink); }

/* ── Visual-less variant ────────────────────────────────────────────────────
   For the mid-text breathers, where one more image would break the thread. No
   visual at all: a title and one button. It used to carry a vertical gradient
   bar in place of the visual (the footer accordions' mark, stood upright); the
   owner cut it on 09/09 — it read as decoration, not as the design — so the
   card is now the sentence and its action, nothing else. The action is the
   gradient button, small, so the one thing on the card that asks for a click
   looks like one (the outline button it had read as a link). */
.rmd-bl .rmd-promo--flat { gap: 20px; padding: 20px 24px; }
.rmd-bl .rmd-promo--flat .rmd-promo__main { flex-direction: row; align-items: center; gap: 20px; flex-wrap: wrap; }
.rmd-bl .rmd-promo--flat .rmd-promo__t { margin-top: 0; font-size: 18px; font-weight: 600; letter-spacing: -.01em; }
.rmd-bl .rmd-promo--flat .rmd-promo__acts { margin-top: 0; margin-left: auto; }

/* ── Grid-cell variant ──────────────────────────────────────────────────────
   The visual moves on top so the card lines up with the article cards beside
   it: same image height, same text start. */
.rmd-bl .rmd-promo--stack { flex-direction: column; align-items: stretch; gap: 0; padding: 0; }
.rmd-bl .rmd-promo--stack .rmd-promo__media {
	flex: none; align-self: auto; min-height: 0; aspect-ratio: 16 / 10;
	display: flex; padding: 22px;
	border-radius: 0; border: 0; border-bottom: 1px solid var(--bord);
	background: linear-gradient(135deg, #EEF0FF 0%, #FBFCFE 55%, #F6F4FF 100%);
}
.rmd-bl .rmd-promo--stack .rmd-serp {
	height: auto; width: 100%; margin: auto;
	font-size: 11px; padding: 1em;
	background: #fff; border: 1px solid var(--bord); border-radius: 8px;
	box-shadow: 0 14px 34px -22px rgba(4, 17, 53, .4);
}
.rmd-bl .rmd-promo--stack .rmd-promo__main { padding: 22px; }
.rmd-bl .rmd-promo--stack .rmd-promo__t { font-size: 21px; }
.rmd-bl .rmd-promo--stack .rmd-promo__acts { margin-top: auto; padding-top: 18px; }

@media (max-width: 720px) {
	.rmd-bl .rmd-promo { flex-direction: column; align-items: stretch; gap: 18px; }
	/* The visual goes UNDER the copy: on a phone the screen opens on the promise,
	   not on a picture that pushes the title out of view. */
	.rmd-bl .rmd-promo__media { order: 2; flex: none; align-self: auto; min-height: 0; aspect-ratio: 16 / 9; }
	.rmd-bl .rmd-promo__main { order: 1; }
	.rmd-bl .rmd-promo__t { font-size: 21px; }
	.rmd-bl .rmd-promo__acts { width: 100%; }
	.rmd-bl .rmd-promo__acts .rmd-btn { flex: 1 1 auto; }

	.rmd-bl .rmd-promo--flat { flex-direction: row; }
	.rmd-bl .rmd-promo--flat .rmd-promo__acts { width: auto; margin-left: 0; }
	.rmd-bl .rmd-promo--flat .rmd-promo__main { flex-direction: column; align-items: flex-start; gap: 14px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   THE ARTICLE  (.rmd-bp)
   ══════════════════════════════════════════════════════════════════════════ */

/* `padding-top` and never the `padding` shorthand: .rmd-bp__top, .rmd-bp__grid
   and .rmd-bp__end ALSO carry .rmd-wrap, whose 24px sides a shorthand would
   reset to zero. Invisible on a wide screen — the page has its own margins —
   and the text touched the edge on a phone. */
/* The band now carries its own padding, so .rmd-bp__top starts flush against it
   and holds only the credits. */
.rmd-bl .rmd-bp__top { padding-top: 0; }
.rmd-bl .rmd-bp__h1 {
	margin-top: 16px; max-width: 900px;
	font-size: clamp(30px, 5vw, 48px); font-weight: 500;
	letter-spacing: -.03em; line-height: 1.06; color: var(--ink);
	text-wrap: balance;
}
/* An uncategorised post has no chip, so the title lands straight under the
   breadcrumb — where 16px is a collision rather than a gap. */
.rmd-bl .rmd-bp__coverin > nav + .rmd-bp__h1 { margin-top: 24px; }
/* The standfirst in 300: the theme already uses that weight for the light half
   of its headings (.thin in the footer and the case studies). Here it separates
   the promise from the body without changing family. */
.rmd-bl .rmd-bp__lead {
	margin-top: 20px; max-width: 62ch;
	font-size: clamp(17px, 2vw, 21px); font-weight: 300; line-height: 1.62; color: var(--slight);
}
/* The rule sits UNDER the credits, not over them: the band's own edge already
   closes what is above, and a second line two dozen pixels below it read as a
   mistake. Here it does the job that was always the point — it ends the credits
   and opens the article. */
.rmd-bl .rmd-bp__by {
	margin-top: 0; padding: 22px 0 24px;
	border-bottom: 1px solid var(--bord);
	justify-content: space-between;
}
/* Face beside the credit, never above it (04/09): the text block is wider than
   the room left next to the face on a phone, and .rmd-by's flex-wrap let it drop
   under. The block shrinks instead and wraps its own lines — the meta list
   already knows how. */
.rmd-bl .rmd-bp__byin { gap: 14px; flex-wrap: nowrap; }
.rmd-bl .rmd-bp__byin > div { flex: 1 1 auto; min-width: 0; }
.rmd-bl .rmd-bp__share { display: flex; align-items: center; gap: 8px; }
.rmd-bl .rmd-bp__sh {
	position: relative;              /* anchor for the "Link copied" confirmation */
	display: inline-flex; align-items: center; justify-content: center;
	width: 38px; height: 38px; border-radius: 10px;
	border: 1px solid var(--bord); background: #fff; color: var(--slight);
	cursor: pointer; transition: color .15s ease, border-color .15s ease, background-color .15s ease;
}
.rmd-bl .rmd-bp__sh:hover { color: var(--ink); border-color: #D8DAE8; background: var(--nuk); }
.rmd-bl .rmd-bp__sh svg { width: 16px; height: 16px; fill: currentColor; }
/* The copy-link confirmation: the button says what just happened, where the
   click happened. A banner at the top of the screen would have to be hunted. */
.rmd-bl .rmd-bp__sh[data-copied]::after {
	content: attr(data-copied);
	position: absolute; margin-top: -62px;
	background: var(--ink); color: #fff; font-size: var(--t-label); font-weight: 500;
	padding: 6px 10px; border-radius: 7px; white-space: nowrap;
}

/* ── The opening band ──────────────────────────────────────────────────────
   Cover, breadcrumb, title and standfirst in ONE dark block, edge to edge. It
   sits OUTSIDE .rmd-wrap — a child of the container cannot break out of its
   1200px — so the band is full-bleed and its inner div carries the container.

   MIN-height, not height: the band has a floor, and the title decides the rest.
   A fixed height would either clip a four-line headline or leave a hole under a
   short one. The floor is in clamp() rather than a ratio for the reason the
   picture-only version already had: at full width a 3/1 is 480px on a 1440
   screen but 640px on a 1920, and the band ends up pushing the title out of view
   on the large displays it was supposed to flatter.

   `isolation: isolate` makes this a stacking context, which is what lets the
   image (-2) and the scrim (-1) sit BEHIND the text without either escaping the
   band or needing a z-index on the text itself. */
.rmd-bl .rmd-bp__cover {
	position: relative; isolation: isolate; overflow: hidden;
	display: flex; align-items: flex-end;
	min-height: clamp(360px, 44vw, 580px);
	background: var(--ink);
	color: #fff;
}
.rmd-bl .rmd-bp__cover > img {
	position: absolute; inset: 0; z-index: -2;
	width: 100%; height: 100%; object-fit: cover;
}

/* THE SCRIM. A photo chosen for a blog post was not chosen to be read on, so
   the type cannot depend on it: the gradient is heaviest exactly where the text
   sits and lifts off towards the top, where the picture is still the subject.
   Values are the brand navy at opacity, not black — black over a warm photo
   reads as a printing fault, the navy reads as the site. */
.rmd-bl .rmd-bp__cover--photo::after {
	content: ''; position: absolute; inset: 0; z-index: -1;
	background: linear-gradient(
		to top,
		rgba(4, 17, 53, .94) 0%,
		rgba(4, 17, 53, .86) 26%,
		rgba(4, 17, 53, .66) 55%,
		rgba(4, 17, 53, .46) 80%,
		rgba(4, 17, 53, .38) 100%
	);
}

/* No featured image: the band keeps its shape and swaps its ground for the
   brand's own light — the same two sweeps the footer and the case-study covers
   use, over the navy. One layout for both states, one set of text colours. */
.rmd-bl .rmd-bp__cover--flat {
	background:
		radial-gradient(120% 130% at 8% -20%, rgba(57, 67, 255, .55) 0%, rgba(57, 67, 255, 0) 58%),
		radial-gradient(90% 120% at 102% 108%, rgba(228, 0, 77, .42) 0%, rgba(228, 0, 77, 0) 62%),
		var(--ink);
}

/* The container. Bottom padding is the small one — the copy sits low in the
   band, near the article it introduces; the top padding only matters when a long
   title grows the band past its floor. */
.rmd-bl .rmd-bp__coverin {
	position: relative; width: 100%;
	padding-top: clamp(64px, 9vw, 128px);
	padding-bottom: clamp(30px, 3.4vw, 52px);
}

/* Text on the band. Every colour here is an override of the light-ground rule
   further up, kept together so the on-dark palette is one block to read rather
   than five exceptions scattered through the file. */
.rmd-bl .rmd-bp__cover .rmd-crumbs { color: rgba(255, 255, 255, .68); }
.rmd-bl .rmd-bp__cover .rmd-crumbs a:hover { color: #fff; }
.rmd-bl .rmd-bp__cover .rmd-crumbs li + li::before { color: rgba(255, 255, 255, .38); }
.rmd-bl .rmd-bp__cover .rmd-crumbs [aria-current] { color: #fff; }
/* THE CHIP, IN THE BRAND'S OWN VIOLET. Two earlier tries were wrong in the same
   way — both were pale. Translucent white read as grey on grey over a photo; the
   lavender pill from the archive cards is a LIGHT-ground treatment, and on the
   navy band a near-white pill is a hole punched in the picture rather than a
   label. Solid #3943FF is the mark itself: the colour of every link in the body,
   of the chapter numbers, of the chip's own text everywhere else.
   White on it is 6.1:1 — comfortably past AA at this size and weight.

   NOT the CTA gradient, deliberately, however "brand" it looks. It is reserved
   for the primary action (see the button block above): the header button and the
   footer button carry it, and spending it on a category label — an element that
   names something rather than asks for a click — is exactly the third decorative
   use that costs it its value as a signal. */
.rmd-bl .rmd-bp__cover .rmd-chip {
	margin-top: 20px;
	background: var(--purp); color: #fff;
}
.rmd-bl .rmd-bp__cover .rmd-bp__h1 { color: #fff; }
.rmd-bl .rmd-bp__cover .rmd-bp__lead { color: rgba(255, 255, 255, .76); }

/* ── The layout: reading column + rail ─────────────────────────────────────
   The column is 680px — the reading measure itself, see --measure — the rail
   290, the gap 56. The whole is centred, which leaves the column slightly left
   of the page centre: exactly the gutter the chapter numbers hang into (see
   .rmd-bp__h2).

   The column was 720 while the text inside it was 620. Collapsing the two to one
   value is what removes the 100px step the right edge used to make at every
   figure and every table. */
/* The gutter went 56 → 88 with the single-width column. It had never needed to
   be wide: the text used to stop 100px short of the column's edge, so the rail
   already had 156px of air in front of it and only the rare full-width figure
   came close. Now that every block runs to 680, that 156 became 56 for the whole
   article and the rail sat right on the text. The 88 buys back most of the
   breathing room while keeping the aligned edge that replaced it. */
.rmd-bl .rmd-bp__grid,
.rmd-bl .rmd-bp__end { display: grid; gap: 0 88px; grid-template-columns: minmax(0, 680px); justify-content: center; }
.rmd-bl .rmd-bp__grid { padding-top: 46px; }
@media (min-width: 1040px) {
	/* The end block (author, and anything added later) reuses the SAME layout,
	   second column included even though it puts nothing there: that is what
	   gives it exactly the body's left edge. Centred on 720px alone it landed
	   166px further right, and the page stepped sideways at the very moment the
	   reader finished reading. */
	.rmd-bl .rmd-bp__grid,
	.rmd-bl .rmd-bp__end { grid-template-columns: minmax(0, 680px) 290px; }
}

/* ── The table of contents ─────────────────────────────────────────────────
   THE sign of the page. A vertical rail that fills with the brand gradient as
   the reader descends: the footer accordions' mark, stood upright and put to
   work. Two things read at once — how much is left, and which chapter this is.

   It only appears from 1040px. Below that it becomes a collapsed <details> at
   the top of the article: on a phone one more column has nowhere to go. */
.rmd-bl .rmd-bp__rail { display: none; }
@media (min-width: 1040px) {
	.rmd-bl .rmd-bp__rail { display: block; grid-row: 1; grid-column: 2; }
	/* A LONG ARTICLE MUST NOT LOSE ITS LAST CHAPTERS. The rail is sticky, so its
	   height is whatever the list needs — and past a dozen chapters that is taller
	   than the screen. The overflow was simply unreachable: it sat below the fold
	   of a box that never scrolls, so on the longest guides (the ones that need a
	   table of contents most) the final entries could not be clicked at all.

	   Bounded to the viewport minus the sticky offset and a little air, it scrolls
	   on its own. `overscroll-behavior: contain` stops the page from taking over
	   the moment the list hits its end — without it, a reader scrolling the rail
	   gets thrown down the article the instant they reach the last chapter. */
	.rmd-bl .rmd-bp__railin {
		position: sticky; top: 112px;
		max-height: calc(100vh - 112px - 28px);
		overflow-y: auto;
		overscroll-behavior: contain;
		/* Room for the scrollbar so it never sits on the chapter titles, and a
		   thin one where the browser allows it — the rail is a quiet object. */
		padding-right: 6px;
		scrollbar-width: thin;
		scrollbar-color: var(--bord) transparent;
	}
	.rmd-bl .rmd-bp__railin::-webkit-scrollbar { width: 6px; }
	.rmd-bl .rmd-bp__railin::-webkit-scrollbar-track { background: transparent; }
	.rmd-bl .rmd-bp__railin::-webkit-scrollbar-thumb { background: var(--bord); border-radius: 3px; }
	.rmd-bl .rmd-bp__railin:hover::-webkit-scrollbar-thumb { background: #D8DAE8; }
}
.rmd-bl .rmd-toc { position: relative; margin-top: 16px; padding-left: 20px; }
.rmd-bl .rmd-toc__track { position: absolute; left: 0; top: 6px; bottom: 6px; width: 2px; border-radius: 2px; background: var(--bord); overflow: hidden; }
.rmd-bl .rmd-toc__fill {
	display: block; width: 100%; height: 0;
	background: linear-gradient(180deg, #D7045A 0%, #FC8831 100%);
	transition: height .12s linear;
}
.rmd-bl .rmd-toc ol { display: grid; }
.rmd-bl .rmd-toc__l {
	display: flex; gap: 11px; padding: 9px 0;
	font-size: var(--t-ui); line-height: 1.45; color: var(--slight); text-decoration: none;
	transition: color .18s ease, padding-left .18s ease;
}
.rmd-bl .rmd-toc__l:hover { color: var(--ink); padding-left: 5px; }
.rmd-bl .rmd-toc__l[aria-current="true"] { color: var(--ink); font-weight: 500; }
.rmd-bl .rmd-toc__n { flex: 0 0 auto; font-variant-numeric: tabular-nums; font-size: var(--t-label); font-weight: 600; letter-spacing: .08em; color: #B9BFCE; padding-top: .18em; }
.rmd-bl .rmd-toc__l[aria-current="true"] .rmd-toc__n { color: var(--purp); }

/* Collapsed version, under 1040px. */
.rmd-bl .rmd-bp__toc-m { margin-top: 34px; border: 1px solid var(--bord); border-radius: 14px; background: var(--nuk); padding: 4px 18px; }
@media (min-width: 1040px) { .rmd-bl .rmd-bp__toc-m { display: none; } }
.rmd-bl .rmd-bp__toc-m > summary { display: flex; align-items: center; gap: 12px; padding: 14px 0; cursor: pointer; list-style: none; }
.rmd-bl .rmd-bp__toc-m > summary::-webkit-details-marker { display: none; }
.rmd-bl .rmd-bp__toc-m > summary::before { content: ''; flex: 0 0 auto; width: 16px; height: 2px; border-radius: 2px; background: var(--grad-cta); }
.rmd-bl .rmd-bp__toc-m .rmd-bp__chev { margin-left: auto; transition: transform .22s ease; color: var(--slight); }
.rmd-bl .rmd-bp__toc-m[open] .rmd-bp__chev { transform: rotate(180deg); }
.rmd-bl .rmd-bp__toc-m .rmd-toc { margin: 0; padding: 0 0 12px 0; }
.rmd-bl .rmd-bp__toc-m .rmd-toc__track { display: none; }

/* ── The body ──────────────────────────────────────────────────────────────
   Two widths, not one. Text stops at the reading measure (--measure, 620px);
   figures, tables and promo cards take the column's full 720px and therefore
   overhang the text column. That offset is what gives the page its rhythm —
   without it everything falls on one edge and the article reads as a document. */
/* overflow-wrap: a measure this narrow cannot absorb a word that does not break.
   Three production articles carry one — a 62-character example URL in
   /en/blog/on-page-seo-guide-…/, a 50-character image filename in
   /fr-fr/blog/seo-on-page-en-france/ — and without this they push the whole
   column sideways on a phone. break-word rather than anywhere: it only breaks a
   word that would otherwise overflow, so ordinary French prose is untouched. */
.rmd-bl .rmd-prose { max-width: var(--measure); font-size: var(--t-body); line-height: var(--lh-body); color: rgba(4, 17, 53, .84); overflow-wrap: break-word; }

/* THE FLOW PARENTS. The measure and the rhythm are applied to the CHILDREN of a
   flow parent, not to every descendant — a <p> inside a table cell or inside a
   promo card is not part of the article's flow and must keep its own spacing.
   `.rmd-prose` is the flow parent for the classic and block editors, whose
   content sits directly inside it. Elementor's text widget nests its paragraphs
   three wrappers deep, so `.elementor-widget-container` is a flow parent too;
   without it an Elementor-built article got the measure applied to the whole
   Elementor tree and no rhythm at all between its paragraphs. Two posts on
   staging are built that way — the same fix covers any future one. */
.rmd-bl .rmd-prose > *,
.rmd-bl .rmd-prose .elementor-widget-container > * { max-width: var(--measure); }
.rmd-bl .rmd-prose > figure,
.rmd-bl .rmd-prose > .rmd-tw,
.rmd-bl .rmd-prose > .wp-block-table,
.rmd-bl .rmd-prose > .rmd-tws,
.rmd-bl .rmd-prose > .rmd-promo,
.rmd-bl .rmd-prose .elementor-widget-container > figure,
.rmd-bl .rmd-prose .elementor-widget-container > .rmd-tw,
.rmd-bl .rmd-prose .elementor-widget-container > .rmd-tws { max-width: none; }
.rmd-bl .rmd-prose > * + *,
.rmd-bl .rmd-prose .elementor-widget-container > * + * { margin-top: 28px; }

/* PASS-THROUGH WRAPPERS — markup that exists only to hold other markup. They get
   no measure of their own, or the article would be capped at 620px twice: once
   on the wrapper, once on the text inside it, and the figures could never reach
   the full column. Declared after the flow rules and with one class more, so it
   wins on both counts. */
.rmd-bl .rmd-prose :is(
	.elementor, .elementor-section, .elementor-container, .elementor-row,
	.elementor-column, .elementor-column-wrap, .elementor-widget-wrap,
	.elementor-element, .elementor-widget, .elementor-widget-container,
	.e-con, .e-con-inner, .e-child, .e-parent,
	.wp-block-group, .wp-block-group__inner-container, .entry-content
) { max-width: none; width: auto; }

.rmd-bl .rmd-prose strong, .rmd-bl .rmd-prose b { font-weight: 600; color: var(--ink); }
.rmd-bl .rmd-prose a:not(.rmd-btn):not(.rmd-more) {
	color: var(--purp); text-decoration: underline;
	text-underline-offset: 3px; text-decoration-thickness: 1px;
}
.rmd-bl .rmd-prose a:not(.rmd-btn):not(.rmd-more):hover { text-decoration-thickness: 2px; }
/* CHILD combinators, not descendants (24/08): Gutenberg nests a <ul> INSIDE an
   <ol>'s <li> (a numbered step with sub-bullets — /blog/e-commerce-maroc/). With
   `ul li` and `ol li` both matching those nested items, the cascade resolved
   PER PROPERTY: the number content from `ol li::before` (declared later) but the
   6px circle box from `ul li::before` — so sub-bullets showed digits stacked
   vertically inside a purple dot, and their counter-increment made the parent's
   numbering run straight through them (7, 10, 13…). `>` scopes each list type
   to its own children; combinators add no specificity, so the .rmd-key note
   below still holds and the component blocks are untouched. */
/* minmax(0, 1fr) (03/09): a grid item's default minimum width is its longest
   unbreakable word, so a bare path in a bullet (/category/subcategory/…/page in
   the on-page SEO guide) grew the item past the column and widened the whole
   layout viewport to 465px on a phone — the "page scrolls sideways" report.
   A track allowed to shrink to 0 lets the item be narrow, and the prose's
   overflow-wrap: break-word then breaks the word. Paragraphs never had the
   problem: they are not grid items. Same on <ol> below. */
.rmd-bl .rmd-prose ul { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
.rmd-bl .rmd-prose ul > li { position: relative; padding-left: 24px; }
.rmd-bl .rmd-prose ul > li::before {
	content: ''; position: absolute; left: 4px; top: .78em;
	width: 6px; height: 6px; border-radius: 50%; background: var(--purp);
}
/* Ordered lists keep their numbers — the reset above removed the marker for
   every list, and a numbered procedure is the one place the number IS the
   information. */
.rmd-bl .rmd-prose ol { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; counter-reset: rmdol; }
.rmd-bl .rmd-prose ol > li { position: relative; padding-left: 34px; counter-increment: rmdol; }
.rmd-bl .rmd-prose ol > li::before {
	content: counter(rmdol) '.';
	position: absolute; left: 0; top: 0;
	font-weight: 600; color: var(--purp); font-variant-numeric: tabular-nums;
}
/* ── Sub-headings ────────────────────────────────────────────────────────────
   h2 is the CHAPTER and is styled as .rmd-bp__h2 further down — the class is put
   there by rmd_blog_prepare_content(), which also numbers it. The rule below is
   the floor for the ones it could not reach (an <h2> a page builder rewrote, an
   empty heading it skipped on purpose): a chapter title must never fall back to
   body text, whatever happened upstream.

   THE SPACING IS ASYMMETRIC ON PURPOSE. A heading with the same air above and
   below belongs to neither side and reads as one more paragraph — which is
   exactly how the sub-headings came out on staging. Each one gets a wide gap
   above and a narrow one to the text it introduces, so the hierarchy is legible
   from the shape of the page before a word is read. */
/* :where() so this contributes NO specificity: .rmd-bp__h2 stays the one
   authority on how a chapter title looks, and this only fills the gap when the
   class is absent. */
.rmd-bl .rmd-prose :where(h2) { font-size: clamp(24px, 3.2vw, 30px); font-weight: 600; letter-spacing: -.02em; line-height: 1.2; color: var(--ink); }
.rmd-bl .rmd-prose h3 { margin-top: 40px; font-size: 21px; font-weight: 600; letter-spacing: -.01em; line-height: 1.35; color: var(--ink); }
.rmd-bl .rmd-prose h4 { margin-top: 32px; font-size: var(--t-lead); font-weight: 600; line-height: 1.4; color: var(--ink); }
.rmd-bl .rmd-prose h5 { margin-top: 28px; font-size: var(--t-sec); font-weight: 600; line-height: 1.45; color: var(--ink); }
/* h6 is the one heading level that cannot get bigger than the level above it, so
   it is set apart by weight and colour instead of size. */
.rmd-bl .rmd-prose h6 { margin-top: 24px; font-size: var(--t-label); font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--purp); }

.rmd-bl .rmd-prose :is(h2, h3, h4, h5, h6) + *,
.rmd-bl .rmd-prose .elementor-widget-container > :is(h2, h3, h4, h5, h6) + * { margin-top: 20px; }
/* Two headings in a row are a title and its subtitle, not two sections. 22px is
   more than the 16px a heading gives its own text and far less than the 50 it
   takes from the previous one — the pair reads as one unit. */
.rmd-bl .rmd-prose :is(h2, h3, h4, h5, h6) + :is(h2, h3, h4, h5, h6) { margin-top: 26px; }

.rmd-bl .rmd-prose code {
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	font-size: .88em; background: var(--nuk); border: 1px solid var(--bord);
	border-radius: 5px; padding: .12em .4em;
}

/* A figure, a table or one of the components is not a paragraph: it needs air on
   both sides. Sibling margins collapse, hence the rule on the NEXT element rather
   than a margin-bottom that would be swallowed.

   The list is every block an editor can insert from the library (inc/blocks.php)
   plus the two the editors produce on their own. `.rmd-cmp` is the wrapper a
   component carries when it is used OFF the blog — harmless here, and it means
   one rule covers both cases. */
.rmd-bl .rmd-prose > :is(figure, .rmd-tw, .rmd-tws, .rmd-promo, .rmd-key, .rmd-steps, .rmd-faq, .rmd-src, .rmd-quote, .rmd-cmp) { margin-top: 36px; }
.rmd-bl .rmd-prose > :is(figure, .rmd-tw, .rmd-tws, .rmd-promo, .rmd-key, .rmd-steps, .rmd-faq, .rmd-src, .rmd-quote, .rmd-cmp) + * { margin-top: 36px; }
/* …except before a chapter title, which opens its own space already. */
.rmd-bl .rmd-prose > :is(figure, .rmd-tw, .rmd-tws, .rmd-promo, .rmd-key, .rmd-steps, .rmd-faq, .rmd-src, .rmd-quote, .rmd-cmp) + :is(h2, .rmd-bp__h2) { margin-top: 56px; }

/* Chapter title. The number hangs in the gutter from 1240px — below that it
   stays inside the box, or it would bite into the edge of the screen.

   NOT a flex container, since 19/08/2026, and the reason is a production
   screenshot: in a flex h2 every child is a flex item, so a title written as
   `Choosing the Right <strong>Keywords</strong> for…` is not a sentence but
   three boxes, each wrapping its own words into a narrow column the moment
   space runs short — and an <img> an import had left inside the heading became
   a fourth box that would not shrink below the full column (`max-width: 100%`
   is where a flex item's automatic minimum size STOPS shrinking, not a cap)
   and rode over the table of contents. A block h2 with an absolute counter
   keeps the same geometry and lets the title be text again: <strong> is a word
   in the sentence and wrapping is the browser's. (inc/blog.php now lifts such
   images out of headings too — this rule is what stops a heading's own inline
   children from ever becoming boxes.) */
.rmd-bl .rmd-bp__h2 {
	position: relative; padding-left: 32px; margin-top: 56px;
	font-size: clamp(24px, 3.2vw, 30px); font-weight: 600;
	letter-spacing: -.02em; line-height: 1.2; color: var(--ink);
	scroll-margin-top: 112px;
}
/* The chapter number, drawn and never written. It was a <span> in the h2 until
   18/08/2026; aria-hidden kept it from screen readers but not from crawlers, which
   read text and saw "01" welded to the front of every heading. Generated content
   has no node to read. decimal-leading-zero reproduces the old sprintf('%02d') at
   every count, 01 through 99 and past it. Absolute, so every line of the title
   starts at the same edge and the number sits beside the FIRST one — the hanging
   indent the flex column used to draw. top is .55em of the NUMBER's own font,
   the exact offset its padding-top produced as a flex item. */
.rmd-bl .rmd-prose { counter-reset: rmdchap; }
.rmd-bl .rmd-bp__h2::before {
	counter-increment: rmdchap;
	content: counter(rmdchap, decimal-leading-zero);
	position: absolute; left: 0; top: .55em;
	font-size: var(--t-meta); font-weight: 600; letter-spacing: .1em;
	color: var(--purp); font-variant-numeric: tabular-nums;
}
@media (min-width: 1240px) {
	.rmd-bl .rmd-bp__h2 { padding-left: 0; }
	.rmd-bl .rmd-bp__h2::before { left: -46px; }
}

/* ── Key points ────────────────────────────────────────────────────────────
   Lavender = information, white-with-border = action (the promo cards), navy =
   "let's talk". Three backgrounds, three intentions. Authored as a Custom HTML
   block for now. */
.rmd-bl .rmd-key { border: 1px solid #E3E5FF; border-radius: 16px; background: var(--purpsoft); padding: 24px 26px; }
.rmd-bl .rmd-key__h { font-size: var(--t-label); font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--purp); }
/* Selectors deliberately as long as the body's (`.rmd-prose ul li`): at equal
   specificity order decides, and this block is declared later. Written shorter,
   the body's round bullet came back in front of the tick. */
.rmd-bl .rmd-key ul { display: grid; gap: 11px; margin-top: 16px; }
.rmd-bl .rmd-key ul li { position: relative; padding-left: 26px; font-size: var(--t-lead); line-height: var(--lh-text); color: rgba(4, 17, 53, .84); }
.rmd-bl .rmd-key ul li::before {
	content: ''; position: absolute; left: 2px; top: .42em;
	width: 11px; height: 6px; border-radius: 0;
	border-left: 2px solid var(--purp); border-bottom: 2px solid var(--purp);
	background: none; transform: rotate(-45deg);
}

/* ── Aside callout ─────────────────────────────────────────────────────────
   The label is the case studies' eyebrow (`.rmd-case .eyebrow`): white pill,
   rule, violet text and the house arrow at the end — astride the panel's edge.
   Background --nuk and not lavender: lavender is taken by the key points, and a
   practical aside ranks one notch below. */
.rmd-bl .rmd-tip {
	position: relative;
	border: 1px solid var(--bord); border-radius: 16px;
	background: var(--nuk); padding: 32px 26px 26px;
}
.rmd-bl .rmd-tip__l {
	position: absolute; top: 0; left: 22px; transform: translateY(-50%);
	display: inline-flex; align-items: center; gap: 12px;
	border-radius: 9999px; border: 1px solid var(--bord); background: #fff;
	padding: 8px 13px 8px 18px;
	font-size: var(--t-meta); font-weight: 500; letter-spacing: -.01em; color: var(--purp);
	box-shadow: var(--sh-card);
}
/* The brand arrow as a background rather than markup: the label stays a single
   text node, read as-is by a screen reader. */
.rmd-bl .rmd-tip__l::after {
	content: ''; flex: 0 0 auto; width: 28px; height: 17px;
	background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 18' fill='none'%3E%3Cpath d='M2 9h24m0 0-6-6m6 6-6 6' stroke='%233943FF' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center / contain;
}
.rmd-bl .rmd-tip p { font-size: var(--t-lead); line-height: var(--lh-text); color: var(--slight); }
.rmd-bl .rmd-tip p strong { color: var(--ink); font-weight: 600; }
/* The pill overhangs the top edge: without this reserve it bites into the
   preceding paragraph. */
.rmd-bl .rmd-prose > .rmd-tip { margin-top: 48px; }
.rmd-bl .rmd-prose > .rmd-tip + * { margin-top: 42px; }
@media (max-width: 620px) {
	.rmd-bl .rmd-tip { padding: 30px 20px 22px; }
	.rmd-bl .rmd-tip__l { left: 16px; padding-left: 15px; font-size: 13px; }
}

/* ── Numbered steps ────────────────────────────────────────────────────────
   Numbered because the order carries the information. The counter comes from
   CSS, not the markup — inserting a step in the middle costs no renumbering. */
.rmd-bl .rmd-steps { counter-reset: rmdstep; display: grid; gap: 2px; }
.rmd-bl .rmd-steps li { counter-increment: rmdstep; position: relative; padding: 18px 0 18px 52px; border-top: 1px solid var(--bord); }
.rmd-bl .rmd-steps li:last-child { border-bottom: 1px solid var(--bord); }
.rmd-bl .rmd-steps li::before {
	content: counter(rmdstep, decimal-leading-zero);
	position: absolute; left: 0; top: 19px;
	font-size: var(--t-meta); font-weight: 600; letter-spacing: .08em;
	color: var(--purp); font-variant-numeric: tabular-nums;
}
.rmd-bl .rmd-steps b { display: block; font-size: var(--t-lead); font-weight: 600; color: var(--ink); }
.rmd-bl .rmd-steps p { margin-top: 6px; font-size: var(--t-sec); line-height: var(--lh-text); color: var(--slight); }

/* ── Tables ──────────────────────────────────────────────────────────────── */
.rmd-bl .rmd-tw { overflow-x: auto; border: 1px solid var(--bord); border-radius: 14px; }
.rmd-bl .rmd-table { width: 100%; border-collapse: collapse; font-size: var(--t-sec); line-height: var(--lh-text); min-width: 660px; }
.rmd-bl .rmd-table th, .rmd-bl .rmd-table td { text-align: left; padding: 14px 18px; border-bottom: 1px solid var(--bord); }
/* The first column carries the screen reading ("Impressions ↗ · clicks →"):
   broken across two lines on the middot it becomes unreadable. So it never
   wraps — the table scrolls instead. */
.rmd-bl .rmd-table tbody td:first-child { white-space: nowrap; }
.rmd-bl .rmd-table thead th { background: var(--nuk); font-size: var(--t-label); font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--slight); }
.rmd-bl .rmd-table tbody tr:last-child td { border-bottom: 0; }
.rmd-bl .rmd-table td b { color: var(--ink); font-weight: 600; }
.rmd-bl .rmd-table .rmd-ok { color: #0F8F4E; font-weight: 600; }

/* ── Pull quote ────────────────────────────────────────────────────────────
   No panel and no drawn quote mark: a gradient rule above, and the text
   breathes on white. Same choice as the case studies' client quotes. */
.rmd-bl .rmd-quote { padding-top: 26px; }
.rmd-bl .rmd-quote::before { content: ''; display: block; width: 54px; height: 3px; border-radius: 3px; background: var(--grad-cta); margin-bottom: 20px; }
.rmd-bl .rmd-quote p { font-size: clamp(20px, 2.4vw, 23px); font-weight: 300; line-height: 1.55; letter-spacing: -.01em; color: var(--ink); }
.rmd-bl .rmd-quote footer { margin-top: 14px; font-size: var(--t-meta); color: var(--slight); }

/* ── FAQ ───────────────────────────────────────────────────────────────────
   Native <details>: the answers stay in the DOM for Google and work without
   JavaScript. Same grammar as the footer accordions. Rank Math owns the
   FAQPage schema — the theme emits none. */
.rmd-bl .rmd-faq { margin-top: 26px; }
.rmd-bl .rmd-faq details { border-top: 1px solid var(--bord); }
.rmd-bl .rmd-faq details:last-of-type { border-bottom: 1px solid var(--bord); }
.rmd-bl .rmd-faq summary {
	display: flex; align-items: center; gap: 14px; padding: 18px 4px;
	cursor: pointer; list-style: none;
	font-size: var(--t-lead); font-weight: 500; color: var(--ink);
	transition: padding-left .18s ease;
}
.rmd-bl .rmd-faq summary::-webkit-details-marker { display: none; }
.rmd-bl .rmd-faq summary:hover { padding-left: 10px; }
.rmd-bl .rmd-faq summary::before { content: ''; flex: 0 0 auto; width: 16px; height: 2px; border-radius: 2px; background: var(--grad-cta); }
.rmd-bl .rmd-faq__chev {
	margin-left: auto; flex: 0 0 auto; width: 26px; height: 26px;
	display: flex; align-items: center; justify-content: center; border-radius: 50%;
	border: 1px solid var(--bord); color: var(--slight);
	transition: transform .22s ease, border-color .18s ease, color .18s ease;
}
.rmd-bl .rmd-faq details[open] .rmd-faq__chev { transform: rotate(180deg); color: var(--ink); border-color: #D8DAE8; }
.rmd-bl .rmd-faq__a { padding: 0 4px 22px 34px; font-size: var(--t-sec); line-height: var(--lh-text); color: var(--slight); }

/* ── Sources ─────────────────────────────────────────────────────────────── */
.rmd-bl .rmd-src { margin-top: 20px; counter-reset: rmdsrc; display: grid; gap: 12px; }
.rmd-bl .rmd-src li { counter-increment: rmdsrc; position: relative; padding-left: 34px; font-size: var(--t-ui); line-height: var(--lh-text); color: var(--slight); }
.rmd-bl .rmd-src li::before {
	content: counter(rmdsrc);
	position: absolute; left: 0; top: 1px;
	width: 22px; height: 22px; border-radius: 50%;
	display: flex; align-items: center; justify-content: center;
	background: var(--nuk); border: 1px solid var(--bord);
	font-size: var(--t-label); font-weight: 600; color: var(--slight); font-variant-numeric: tabular-nums;
}
.rmd-bl .rmd-src a { color: var(--purp); text-decoration: underline; text-underline-offset: 3px; }

/* ── Author box ──────────────────────────────────────────────────────────── */
.rmd-bl .rmd-auth { display: flex; flex-wrap: wrap; gap: 22px; align-items: flex-start; border: 1px solid var(--bord); border-radius: 16px; background: var(--nuk); padding: 26px; }
.rmd-bl .rmd-auth__face { flex: 0 0 auto; width: 84px; height: 84px; border-radius: 50%; object-fit: cover; object-position: top center; border: 3px solid var(--redder); }
.rmd-bl .rmd-auth__b { flex: 1 1 260px; }
.rmd-bl .rmd-auth__n { font-size: var(--t-lead); font-weight: 600; color: var(--ink); }
.rmd-bl .rmd-auth__r { font-size: var(--t-meta); color: var(--purp); font-weight: 500; margin-top: 2px; }
.rmd-bl .rmd-auth__p { margin-top: 12px; font-size: var(--t-sec); line-height: var(--lh-text); color: var(--slight); }
.rmd-bl .rmd-auth__l { margin-top: 14px; }

/* ── End blocks ──────────────────────────────────────────────────────────── */
.rmd-bl .rmd-bp__end { padding-top: 56px; }
.rmd-bl .rmd-bp__endin > * + * { margin-top: 44px; }
.rmd-bl .rmd-rel { padding: 64px 0 88px; border-top: 1px solid var(--bord); margin-top: 64px; }
.rmd-bl .rmd-rel__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; margin-top: 30px; }
@media (max-width: 900px) { .rmd-bl .rmd-rel__grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .rmd-bl .rmd-rel__grid { grid-template-columns: 1fr; } }

@media (max-width: 720px) {
	.rmd-bl .rmd-bp__by { gap: 14px; }
	.rmd-bl .rmd-by__face { width: 44px; height: 44px; }
	/* Date and reading time STACK next to the face on a phone (04/09): side by
	   side they wrapped, and the separator dot opened the second line. */
	.rmd-bl .rmd-bp__byin .rmd-by__meta { flex-direction: column; align-items: flex-start; gap: 3px; }
	.rmd-bl .rmd-bp__byin .rmd-by__meta li + li::before { content: none; margin: 0; }
	/* The role too: its own line under the name on a phone, no dot. Inline it
	   fit at 360px and split at 320px — and any longer name or role splits at
	   390 — with the dot opening the second line. Four short lines beside the
	   face read the same on every phone and with every name. */
	.rmd-bl .rmd-by__role { display: block; margin-top: 1px; }
	.rmd-bl .rmd-by__role::before { content: none; margin: 0; }
	/* The author box on a phone (04/09): face LEFT with name and role beside it,
	   bio and link full width below — the flex-wrap version dropped the whole
	   text block under an 84px face. Same display: contents grid the author
	   page's hero uses. A box without a role lets the name take both rows. */
	/* gap 0 14: the box's desktop gap (22px) would otherwise become the ROW gap
	   too and push the role 22px under the name. */
	.rmd-bl .rmd-auth { display: grid; grid-template-columns: 64px minmax(0, 1fr); gap: 0 14px; align-items: center; padding: 20px; }
	.rmd-bl .rmd-auth__face { width: 64px; height: 64px; grid-row: 1 / 3; }
	.rmd-bl .rmd-auth__b { display: contents; }
	.rmd-bl .rmd-auth__n { grid-column: 2; align-self: end; }
	.rmd-bl .rmd-auth__n:has(+ .rmd-auth__p) { grid-row: 1 / 3; align-self: center; }
	.rmd-bl .rmd-auth__r { grid-column: 2; align-self: start; margin-top: 2px; }
	.rmd-bl .rmd-auth__p, .rmd-bl .rmd-auth__l { grid-column: 1 / -1; }
	.rmd-bl .rmd-auth__p { margin-top: 16px; }
	/* THE AIR COMES BACK DOWN ON A PHONE. 26px between paragraphs is generous on a
	   720px column and oppressive on a 350px one: the same gap is a rest there and
	   half a screen of nothing here, and the reader loses the thread between two
	   blocks they can no longer see at once. The desktop rhythm is the one that was
	   widened; this keeps the phone at what it already read well at. */
	.rmd-bl .rmd-prose > * + *,
	.rmd-bl .rmd-prose .elementor-widget-container > * + * { margin-top: 22px; }
	.rmd-bl .rmd-prose h3 { margin-top: 34px; }
	.rmd-bl .rmd-prose h4 { margin-top: 28px; }
	.rmd-bl .rmd-bp__h2 { margin-top: 44px; }
	.rmd-bl .rmd-prose > :is(figure, .rmd-tw, .rmd-tws, .rmd-promo, .rmd-key, .rmd-steps, .rmd-faq, .rmd-src, .rmd-quote, .rmd-cmp) { margin-top: 28px; }
	.rmd-bl .rmd-prose > :is(figure, .rmd-tw, .rmd-tws, .rmd-promo, .rmd-key, .rmd-steps, .rmd-faq, .rmd-src, .rmd-quote, .rmd-cmp) + * { margin-top: 28px; }
	/* On a phone the band is the whole first screen. Its floor comes down and the
	   share row drops under the byline instead of squeezing beside it. */
	.rmd-bl .rmd-bp__cover { min-height: clamp(320px, 78vw, 430px); }
	.rmd-bl .rmd-bp__share { margin-left: -2px; }
	/* The body drops a notch on a phone — carried by the TOKEN, not by
	   .rmd-prose: everything expressed in --t-body follows without being asked.
	   It has to move whenever the desktop size does, or the notch it promises
	   quietly becomes no notch at all. */
	.rmd-bl { --t-body: 17.5px; }
	.rmd-bl .rmd-bp__end { padding-top: 40px; }
	.rmd-bl .rmd-rel { padding: 44px 0 64px; margin-top: 44px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   EDITOR BRIDGE
   The mockup's article body was hand-written markup. A real one is not: the 193
   posts on this site were written in THREE different editors, and all three are
   still in the archive.

     classic     bare <h2>, <p>, <table>, <img> — no classes at all (~2/3)
     block       .wp-block-heading, <figure class="wp-block-table">, … (~1/3)
     Elementor   the same tags, buried under .elementor-widget-container

   So nothing here may key on a block class alone. Each rule below is written
   against the ELEMENT, and the block/builder classes only ever ADD to it. That
   is what was missing: the port styled `.wp-block-table` and left the classic
   editor's bare <table> to the parent theme, which drew it as five columns of
   naked text — the "tables not styled" report.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Images ──────────────────────────────────────────────────────────────────
   Bare <img> included: the classic editor drops one straight into a <p>, with a
   width/height attribute pair that has nothing to do with this column. */
.rmd-bl .rmd-prose img {
	/* BLOCK, and that is the whole fix for "the space under my images is off".
	   The classic editor drops a bare <img> straight into a <p>: left inline it
	   sits on the TEXT BASELINE, which reserves room for descenders under the
	   picture and none above it, so the gap reads asymmetric whatever the rhythm
	   above says. Block takes the image out of the line box entirely and what
	   surrounds it becomes exactly the flow rhythm, nothing else. */
	display: block; max-width: 100%; height: auto; border-radius: 14px;
}
.rmd-bl .rmd-prose figure img { display: block; }
.rmd-bl .rmd-prose figcaption {
	margin-top: 16px; font-size: var(--t-ui); line-height: var(--lh-text); color: var(--slight);
}
.rmd-bl .rmd-prose figcaption b, .rmd-bl .rmd-prose figcaption strong { color: var(--ink); font-weight: 600; }
.rmd-bl .rmd-prose .wp-block-image { margin-left: 0; margin-right: 0; }
/* An image alone in a paragraph is a figure that lost its frame — give it the
   figure's full column rather than the text measure. */
.rmd-bl .rmd-prose > p:has(> img:only-child) { max-width: none; }

/* ── Tables ──────────────────────────────────────────────────────────────────
   Three wrappers, one design: <figure class="wp-block-table"> from the block
   editor, .rmd-tw from the components below, and .rmd-tw again from
   rmd_blog_wrap_bare_tables() (inc/blog.php), which frames the classic editor's
   unwrapped tables at render time. The frame has to be a box that is NOT the
   table: `overflow-x: auto` on a <table> loses the border-radius. */
.rmd-bl .rmd-prose .wp-block-table,
.rmd-bl .rmd-prose .rmd-tw {
	overflow-x: auto; border: 1px solid var(--bord); border-radius: 14px;
}
.rmd-bl .rmd-prose table {
	width: 100%; border-collapse: collapse;
	font-size: var(--t-sec); line-height: var(--lh-text);
}
.rmd-bl .rmd-prose th,
.rmd-bl .rmd-prose td {
	text-align: left; padding: 14px 18px;
	border: 0; border-bottom: 1px solid var(--bord);
	vertical-align: top;
}
.rmd-bl .rmd-prose thead th {
	background: var(--nuk);
	font-size: var(--t-label); font-weight: 600; letter-spacing: .1em;
	text-transform: uppercase; color: var(--slight);
}
.rmd-bl .rmd-prose tbody tr:last-child td { border-bottom: 0; }
/* The classic editor writes no <thead>: the header row is the first <tr>, and
   the only thing marking it is a <b> in every cell. Read it as the header — but
   only the tint and the weight, never the uppercase transform, because if the
   guess is wrong that row is a sentence of real content shouting. */
.rmd-bl .rmd-prose table:not(:has(thead)) tbody tr:first-child td {
	background: var(--nuk); color: var(--ink); font-weight: 600;
}
/* Cells hold paragraphs in classic markup — one per line of text. Left alone
   they inherit the article's 1.9 line-height and 32px rhythm and each row grows
   to three times its height. */
.rmd-bl .rmd-prose th > p,
.rmd-bl .rmd-prose td > p { max-width: none; line-height: var(--lh-text); }
.rmd-bl .rmd-prose th > p + p,
.rmd-bl .rmd-prose td > p + p { margin-top: 6px; }
.rmd-bl .rmd-prose td b, .rmd-bl .rmd-prose td strong { color: var(--ink); font-weight: 600; }
/* The caption belongs under the frame, not inside the scroll area. */
.rmd-bl .rmd-prose .wp-block-table figcaption { padding: 0 18px 16px; margin-top: 12px; }

/* ── Tables wider than the phone (03/09) ───────────────────────────────────
   The frame scrolls, but nothing said so: a phone shows no scrollbar and the
   design drew no edge, so a table wider than the screen (391–601px against a
   340px frame, measured on eight articles) read as cut off. post.js wraps ONLY
   the frames that really overflow in a shell — .rmd-tws > (hint, .rmd-tws__box
   > frame) — and keeps three flags on it: is-more while there is content to
   the right, is-scrolled while the reader is away from the start (live — the
   left fade must lift again at the start), has-scrolled once they have ever
   moved (retires the hint). The box draws what the frame cannot (an absolutely
   positioned child of a scroll container scrolls away with the content): a
   fading right edge, a fading left edge while scrolled, and a one-line hint
   above the table until the first scroll. is-fit is set when a rotation makes
   the table fit again. */
.rmd-bl .rmd-prose .wp-block-table,
.rmd-bl .rmd-prose .rmd-tw { scrollbar-width: thin; scrollbar-color: #B9BFCE transparent; -webkit-overflow-scrolling: touch; }
.rmd-bl .rmd-tws__box { position: relative; }
.rmd-bl .rmd-tws__box::before,
.rmd-bl .rmd-tws__box::after {
	content: ''; position: absolute; top: 1px; bottom: 1px; width: 44px;
	pointer-events: none; opacity: 0; transition: opacity .2s ease;
}
.rmd-bl .rmd-tws__box::after { right: 1px; border-radius: 0 13px 13px 0; background: linear-gradient(270deg, #fff 22%, rgba(255, 255, 255, 0)); }
.rmd-bl .rmd-tws__box::before { left: 1px; border-radius: 13px 0 0 13px; background: linear-gradient(90deg, #fff 22%, rgba(255, 255, 255, 0)); }
.rmd-bl .rmd-tws.is-more:not(.is-fit) .rmd-tws__box::after { opacity: 1; }
.rmd-bl .rmd-tws.is-scrolled:not(.is-fit) .rmd-tws__box::before { opacity: 1; }
.rmd-bl .rmd-tws__hint {
	display: flex; align-items: center; gap: 6px; margin-bottom: 8px;
	font-size: var(--t-meta); font-weight: 500; color: var(--slight);
}
.rmd-bl .rmd-tws__hint::before { content: 'Swipe to see the whole table'; }
.rmd-bl .rmd-tws__hint:lang(fr)::before { content: 'Faites glisser pour voir tout le tableau'; }
.rmd-bl .rmd-tws__hint::after { content: '→'; }
.rmd-bl .rmd-tws.has-scrolled .rmd-tws__hint,
.rmd-bl .rmd-tws.is-fit .rmd-tws__hint { display: none; }
/* Phone cell padding lives in the UNLAYERED block at the end of the file:
   block-library sets .wp-block-table td { padding: .5em } unlayered, which no
   layered rule can beat. The caption is ours alone. */
@media (max-width: 640px) {
	.rmd-bl .rmd-prose .wp-block-table figcaption { padding: 0 12px 14px; }
}

/* ── Quotes — core's blockquote, given the pull quote's gradient rule. ─────── */
.rmd-bl .rmd-prose blockquote { padding-top: 26px; }
.rmd-bl .rmd-prose blockquote::before { content: ''; display: block; width: 54px; height: 3px; border-radius: 3px; background: var(--grad-cta); margin-bottom: 20px; }
.rmd-bl .rmd-prose blockquote p { font-size: clamp(20px, 2.4vw, 23px); font-weight: 300; line-height: 1.55; letter-spacing: -.01em; color: var(--ink); }
.rmd-bl .rmd-prose blockquote cite { display: block; margin-top: 14px; font-size: var(--t-meta); font-style: normal; color: var(--slight); }

/* Separator and code block. */
.rmd-bl .rmd-prose hr, .rmd-bl .rmd-prose .wp-block-separator { border: 0; border-top: 1px solid var(--bord); margin-top: 54px; }
.rmd-bl .rmd-prose pre {
	overflow-x: auto; padding: 18px 20px; border-radius: 12px;
	background: var(--nuk); border: 1px solid var(--bord);
	font-size: var(--t-sec); line-height: 1.6;
}
.rmd-bl .rmd-prose pre code { background: none; border: 0; padding: 0; font-size: inherit; }

/* Embeds keep their aspect ratio inside the column. The bare <iframe> case is
   the classic editor's: a YouTube embed pasted as raw markup carries a fixed
   560×315 and nothing else, so it juts out of a 620px column on desktop and off
   the screen on a phone. 16/9 rather than the attribute pair, because the
   attributes are what is wrong. */
.rmd-bl .rmd-prose iframe {
	display: block; width: 100%; max-width: 100%; border: 0; border-radius: 14px;
}
.rmd-bl .rmd-prose iframe:not([height]),
.rmd-bl .rmd-prose .wp-block-embed iframe { aspect-ratio: 16 / 9; height: auto; }
/* An embed is a figure, not a sentence: it takes the whole column. */
.rmd-bl .rmd-prose > .wp-block-embed,
.rmd-bl .rmd-prose > iframe,
.rmd-bl .rmd-prose > p:has(> iframe:only-child) { max-width: none; }

/* Core's alignment classes: full/wide are as wide as the column allows, and no
   wider — this is a 720px reading column, not a page builder. */
.rmd-bl .rmd-prose .alignfull,
.rmd-bl .rmd-prose .alignwide { max-width: none; }
.rmd-bl .rmd-prose .aligncenter { margin-left: auto; margin-right: auto; }

/* ══════════════════════════════════════════════════════════════════════════
   THE ARCHIVE  (.rmd-ba)
   Reuses the case-study archive's frame: same width, same breathing room, same
   pagination. The site's two archives must look alike.
   ══════════════════════════════════════════════════════════════════════════ */

.rmd-bl.rmd-ba { padding-bottom: 88px; }

/* ── Opening band ──────────────────────────────────────────────────────────
   Full screen width, like the article's cover: the blog's two pages open on the
   same gesture. It sits OUTSIDE .rmd-wrap — its children carry the container,
   it does not.

   ONE column since 13/08. It was two — the title on the left, a search box on
   the right, section filter chips on a rule under both. Search and filters were
   removed; what is left is a title, and a title does not need a grid. Putting
   them back means bringing back the second column (minmax(0, 400px)), the 940px
   single-column override, and the .rmd-ba__ftbar row under the band. */
/* THE BAND NEEDS A FLOOR NOW THAT IT ONLY HOLDS A TITLE. With the search box and
   the filter row gone there was nothing left to give it height, and it collapsed
   to 162px — a strip, against the article's 580px band. The two pages stopped
   opening on the same gesture, which is the whole reason this band exists, and
   the brand curves behind it had no room to read as anything but a smudge.

   A floor, not a fixed height: a long term name or a two-line standfirst still
   grows it. ~345px at 1440 — about three fifths of the article's band, which is
   the right relation. A listing announces, a cover carries. */
/* Floor LOWERED and centring made true (27/08, owner: the band read as empty):
   360px of floor over a title + three lines left ~130px of dead sky pooling
   at the BOTTOM — the old padding-top was inside the centring and pushed the
   content up off-axis. Symmetric padding + a 300px cap: the band still
   announces, it just stops holding a room it does not use. */
.rmd-bl .rmd-ba__hero {
	position: relative; overflow: hidden;
	display: flex; align-items: center;
	min-height: clamp(210px, 21vw, 300px);
	background: #fff; border-bottom: 1px solid var(--bord);
	padding: 32px 0;
}
.rmd-bl .rmd-ba__bg { position: absolute; inset: 0; width: 100%; height: 100%; opacity: .9; pointer-events: none; }
/* The content goes back above the background — without this it disappears
   under the SVG. `width: 100%` because the wrap is now a flex ITEM: without it
   it shrinks to its longest line and the whole band lurches to the centre. */
.rmd-bl .rmd-ba__hero > .rmd-wrap { position: relative; z-index: 1; width: 100%; }
.rmd-bl .rmd-ba__heroin { padding: 26px 0 30px; }

.rmd-bl .rmd-ba__h1 {
	font-size: clamp(32px, 5vw, 48px); font-weight: 500;
	letter-spacing: -.03em; line-height: 1.08; color: var(--ink);
}
.rmd-bl .rmd-ba__h1 .thin { font-weight: 300; color: var(--slight); }
.rmd-bl .rmd-ba__sub { margin-top: 16px; max-width: 46ch; font-size: var(--t-lead); line-height: var(--lh-text); color: var(--slight); }

/* ── The author hero (26/08) ──────────────────────────────────────────────
   The footer expert band's vocabulary grown to page scale, laid FLAT on the
   band — a first version boxed it in a white card with the gradient edge;
   the owner cut the card the same day: the elements, not the frame. So:
   red-ringed portrait (or a slate-on-lavender SILHOUETTE when no photo
   exists — the hero holds its shape either way), name, role, the share
   block's own icon recipe for the socials, and the bio HELD TO THREE LINES
   with its glide (rules further down). Every element renders nothing when
   its field is empty. Data: inc/author-profile.php. */
.rmd-bl .rmd-authcard {
	display: flex; flex-wrap: wrap; align-items: flex-start; gap: 26px 38px;
	/* PERCEIVED parity with the hub, not numeric parity (27/08 — the numeric
	   version was tried and read cramped). The hub's air is min-height slack
	   its two-line content never uses, ~80px gifted to each side; the author
	   hero FILLS its band, so the same 26/30 inset left it airless. This
	   padding buys back what the hub gets for free: with the band's 32px,
	   ~70px above the block and ~76px below — the margins the eye actually
	   compares. */
	padding: 38px 0 44px;
}
/* More sky above the breadcrumb on the author page (27/08, owner's eye — the
   32px shared band inset read tight over a profile header). Scoped by the WP
   body class so the hub's freshly-trued centring is left alone: there the
   crumb's air comes from min-height slack, and raising the band's top pad
   would only push its centred content back down. */
body.author .rmd-bl .rmd-ba__hero { padding-top: 64px; }
/* PHONES: the announcing band is a desktop luxury. Every desktop value above
   ran untouched on 390px screens and stacked ~100px of near-empty sky over
   the breadcrumb (measured 27/08, hub and author both) — a third of the
   viewport spent before a word of content. The floor goes entirely (the band
   is its strokes and border, not its height) and every inset compresses. */
@media (max-width: 700px) {
	.rmd-bl .rmd-ba__hero { min-height: 0; padding: 18px 0 24px; }
	body.author .rmd-bl .rmd-ba__hero { padding-top: 30px; }
	.rmd-bl .rmd-authcard { padding: 18px 0 24px; gap: 18px 24px; }
}
.rmd-bl .rmd-authcard__face {
	flex: 0 0 auto; width: 120px; height: 120px; border-radius: 50%;
	object-fit: cover; object-position: top center; border: 3px solid var(--redder);
}
.rmd-bl .rmd-authcard__b { min-width: 0; flex: 1 1 340px; }
/* The bio row (27/08): a full-width flex child under the avatar/identity
   pair — the paragraph restarts at the avatar's left edge instead of
   continuing the right column over a hole beneath the portrait. The
   container's row-gap spaces it; the sub's own top margin would double it. */
.rmd-bl .rmd-authcard__bio { flex: 1 1 100%; min-width: 100%; }
.rmd-bl .rmd-authcard__bio .rmd-ba__sub { margin-top: 0; }
.rmd-bl .rmd-authcard__eyebrow { margin-bottom: 12px; }
.rmd-bl .rmd-authcard__row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 18px; }
/* A card headline, not a band headline — rmd-ba__h1's clamp is sized for the
   open band; equal specificity, declared later, wins on order. */
.rmd-bl .rmd-authcard__n { font-size: clamp(26px, 3.4vw, 36px); }
.rmd-bl .rmd-authcard__soc { display: flex; gap: 8px; }
/* Same recipe as the article's share buttons (.rmd-bp__sh) — one icon family
   across the blog. fill scoped off the [fill="none"] stroke glyphs. */
.rmd-bl .rmd-authcard__sl {
	display: inline-flex; align-items: center; justify-content: center;
	width: 38px; height: 38px; border-radius: 50%;
	border: 1px solid var(--bord); background: #fff; color: var(--slight);
	transition: border-color .15s ease, background-color .15s ease;
}
/* SOLID brand pills (27/08, second pass — coloured glyphs on white still read
   washed out): each network's own colour as the GROUND, white glyph on top —
   the treatment the networks themselves use for their buttons. Hover lifts
   and brightens the pill; the glyph never changes. */
.rmd-bl .rmd-authcard__sl--in { background: #0A66C2; border-color: transparent; color: #fff; }
.rmd-bl .rmd-authcard__sl--x { background: #0F1419; border-color: transparent; color: #fff; }
.rmd-bl .rmd-authcard__sl--site { background: var(--purp); border-color: transparent; color: #fff; }
/* Instagram's ground is its brand GRADIENT — the network's own button, not a
   flat swatch: the three official stops at 45°, like the app icon.
   background-origin: the pill keeps its 1px (transparent) border, and a
   gradient is sized to the PADDING box then tiled into that ring — so the
   ring showed the far end of the gradient as a 1px seam on the sides
   (measured 02/09). A flat colour tiles invisibly; a gradient must span the
   border box. */
.rmd-bl .rmd-authcard__sl--ig { background: linear-gradient(45deg, #F9CE34, #EE2A7B, #6228D7); background-origin: border-box; border-color: transparent; color: #fff; }
.rmd-bl .rmd-authcard__sl { transition: border-color .15s ease, background-color .15s ease, filter .15s ease, transform .15s ease; }
.rmd-bl .rmd-authcard__sl:hover { border-color: #D8DAE8; background: var(--nuk); }
.rmd-bl .rmd-authcard__sl--in:hover { background: #0A66C2; filter: brightness(1.14); transform: translateY(-1px); border-color: transparent; }
.rmd-bl .rmd-authcard__sl--x:hover { background: #0F1419; filter: brightness(1.35); transform: translateY(-1px); border-color: transparent; }
.rmd-bl .rmd-authcard__sl--site:hover { background: var(--purp); filter: brightness(1.14); transform: translateY(-1px); border-color: transparent; }
.rmd-bl .rmd-authcard__sl--ig:hover { background: linear-gradient(45deg, #F9CE34, #EE2A7B, #6228D7); background-origin: border-box; filter: brightness(1.1); transform: translateY(-1px); border-color: transparent; }
.rmd-bl .rmd-authcard__sl svg { width: 16px; height: 16px; }
.rmd-bl .rmd-authcard__sl svg:not([fill="none"]) { fill: currentColor; }
.rmd-bl .rmd-authcard__role { margin-top: 6px; font-size: var(--t-lead); color: var(--slight); }
.rmd-bl .rmd-authcard__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin-top: 14px; font-size: var(--t-meta); color: var(--slight); }
.rmd-bl .rmd-authcard__meta li { display: inline-flex; align-items: center; }
.rmd-bl .rmd-authcard__meta li + li::before { content: '·'; margin-right: 10px; color: #B9BFCE; }
/* PHONES (27/08, third pass — the miniature-desktop and the side-by-side
   both read cramped at 390px; the owner asked for better): the CENTRED
   STACK, the profile pattern every major platform lands on for mobile —
   avatar, eyebrow, name, role, stats, icons, each centred on its own line,
   using the width symmetrically instead of fighting over it. The BIO alone
   stays left-aligned: centred paragraphs are hard to read. display:contents
   dissolves the desktop name/socials row so the column owns every piece;
   order sends the icons to the foot of the identity stack. */
@media (max-width: 700px) {
	/* DECIDED (27/08, owner's final pick after six passes — the press-byline
	   hierarchy): the NAME is the hero, full width and unchallenged; the
	   avatar shrinks to 48px and slots beside the role/stats lines like a
	   byline signature; the socials take their own row; the bio closes,
	   full width. No block ever competes with another for width. Grid +
	   display:contents dissolves the desktop wrappers so every piece is
	   freely placeable. Do not reshuffle without a new owner decision. */
	.rmd-bl .rmd-authcard {
		display: grid;
		grid-template-columns: auto 1fr;
		gap: 0 12px;
		grid-template-areas:
			"eyebrow eyebrow"
			"name    name"
			"face    role"
			"face    meta"
			"soc     soc"
			"bio     bio";
	}
	.rmd-bl .rmd-authcard__b, .rmd-bl .rmd-authcard__row { display: contents; }
	.rmd-bl .rmd-authcard__eyebrow { grid-area: eyebrow; margin-bottom: 8px; }
	.rmd-bl .rmd-authcard__n { grid-area: name; font-size: 27px; }
	.rmd-bl .rmd-authcard__face {
		grid-area: face; align-self: center;
		width: 48px; height: 48px; border-width: 2px;
		margin-top: 10px;
	}
	.rmd-bl .rmd-authcard__role { grid-area: role; align-self: end; margin-top: 10px; font-size: 15.5px; }
	.rmd-bl .rmd-authcard__meta { grid-area: meta; align-self: start; margin-top: 4px; }
	.rmd-bl .rmd-authcard__soc { grid-area: soc; margin-top: 16px; }
	.rmd-bl .rmd-authcard__bio { grid-area: bio; margin-top: 16px; text-align: left; }
}

/* The bio shows WHOLE by default (27/08, owner's rule): the accordion is the
   exception for marathon bios, not the norm. The clamp sits at NINE lines —
   post.js only reveals the toggle when the clamp actually bites, so a bio
   that fits (Ayoub's runs ~6 lines at this full-column measure) prints
   complete with no button at all, while a 9+-line one folds. FULL column
   width (owner's call — a 60ch cap left a void between text and socials, and
   pushed ordinary bios over the fold threshold). */
.rmd-bl .rmd-ba__heroin--author .rmd-ba__sub {
	max-width: none;
	display: -webkit-box; -webkit-line-clamp: 9; -webkit-box-orient: vertical; overflow: hidden;
}
/* Unfolded state, toggled by the post.js module. Same selector depth as the
   clamp above, declared after — it wins on order, not on a specificity race.
   overflow stays HIDDEN here: the unfold animates via max-height (the clamp
   itself cannot animate), and hidden is what max-height clips against
   mid-flight. Nothing overflows an unfolded paragraph anyway. */
/* Back to THREE lines on phones — AFTER the base rule on purpose: same
   specificity, later wins. The nine-line "show it whole" rule is a
   desktop-measure rule; the same bio runs 12+ lines at 390px and buried
   the articles. post.js measures real truncation, so the accordion button
   returns on mobile by itself. */
@media (max-width: 700px) {
	.rmd-bl .rmd-ba__heroin--author .rmd-ba__sub { -webkit-line-clamp: 3; }
}
.rmd-bl .rmd-ba__heroin--author .rmd-ba__sub--open { display: block; -webkit-line-clamp: unset; overflow: hidden; }
.rmd-bl .rmd-ba__heroin--author .rmd-ba__anim { transition: max-height .35s ease; }
@media (prefers-reduced-motion: reduce) {
	.rmd-bl .rmd-ba__heroin--author .rmd-ba__anim { transition: none; }
}
/* The toggle: a text button in the link violet, no chrome of its own — it acts
   on the paragraph above it, and a bordered button would outrank the cards. */
.rmd-bl .rmd-ba__more {
	display: inline-flex; align-items: center; gap: 8px;
	margin-top: 14px; padding: 0; border: 0; background: none; cursor: pointer;
	font: inherit; font-size: var(--t-ui); font-weight: 500; color: var(--purp);
}
.rmd-bl .rmd-ba__more:hover .rmd-ba__more-t { text-decoration: underline; }
/* The arrow badge: chevron in a lavender disc, flipped by aria-expanded — the
   attribute the toggle already maintains, so the icon can never disagree with
   the state it points at. */
.rmd-bl .rmd-ba__more-i { width: 18px; height: 18px; transition: transform .25s ease; }
.rmd-bl .rmd-ba__more-i circle { fill: var(--purpsoft); }
.rmd-bl .rmd-ba__more-i polyline { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.rmd-bl .rmd-ba__more[aria-expanded="true"] .rmd-ba__more-i { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) {
	.rmd-bl .rmd-ba__more-i { transition: none; }
}

/* ── Featured ──────────────────────────────────────────────────────────────
   The same card, laid on its side. Not one more component: the format changes,
   not the nature of the object — and the reader recognises the card they will
   meet again in the grid. */
.rmd-bl .rmd-ba__lead { margin-top: 46px; }
.rmd-bl .rmd-ba__lead .rmd-card { margin-top: 16px; }
/* The grid is carried by the LINK, not the card: `display:contents` on an <a>
   removes it from the accessibility tree in several browsers — the title would
   stay clickable with a mouse and invisible to a keyboard. */
.rmd-bl .rmd-card--wide .rmd-card__link { display: grid; grid-template-columns: 1.05fr 1fr; }
.rmd-bl .rmd-card--wide .rmd-card__media { aspect-ratio: auto; height: 100%; min-height: 260px; }
.rmd-bl .rmd-card--wide .rmd-card__body { padding: 34px 36px; justify-content: center; }
.rmd-bl .rmd-card--wide .rmd-card__title { margin-top: 16px; font-size: clamp(21px, 2.4vw, 26px); font-weight: 500; letter-spacing: -.02em; line-height: 1.2; }
.rmd-bl .rmd-card--wide .rmd-card__ex { margin-top: 14px; font-size: var(--t-sec); -webkit-line-clamp: 4; }
.rmd-bl .rmd-card--wide .rmd-card__foot { margin-top: 22px; padding-top: 0; }
@media (max-width: 820px) {
	.rmd-bl .rmd-card--wide .rmd-card__link { grid-template-columns: 1fr; }
	.rmd-bl .rmd-card--wide .rmd-card__media { aspect-ratio: 16 / 10; min-height: 0; }
	.rmd-bl .rmd-card--wide .rmd-card__body { padding: 24px 22px 22px; }
}

/* ── The grid ──────────────────────────────────────────────────────────────
   Three columns, like the case-study archive, and the same breakpoints — the
   two pages must fold at the same place. */
.rmd-bl .rmd-ba__all { margin-top: 52px; }
.rmd-bl .rmd-ba__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; margin-top: 24px; }
@media (max-width: 900px) { .rmd-bl .rmd-ba__grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .rmd-bl .rmd-ba__grid { grid-template-columns: 1fr; } }

/* ── Pagination ────────────────────────────────────────────────────────────
   Styled on the markup the_posts_pagination() actually prints (nav.pagination >
   .page-numbers), rather than on the mockup's hand-built .rmd-ba__pg: core
   already gets the ellipsis and the prev/next edge cases right. */
.rmd-bl .pagination { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 48px; }
.rmd-bl .pagination .screen-reader-text { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
.rmd-bl .pagination .nav-links { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.rmd-bl .pagination .page-numbers {
	display: inline-flex; align-items: center; justify-content: center;
	min-width: 40px; height: 40px; padding: 0 12px;
	border: 1px solid var(--bord); border-radius: 10px;
	color: var(--ink); font-size: var(--t-ui); font-weight: 500; text-decoration: none;
	transition: background-color .15s ease, border-color .15s ease;
}
.rmd-bl .pagination a.page-numbers:hover { background: #F3F4F6; }
.rmd-bl .pagination .page-numbers.current { background: var(--ink); color: #fff; border-color: var(--ink); }
.rmd-bl .pagination .page-numbers.dots { border: 0; min-width: 20px; color: #B9BFCE; }

/* ── Empty state ─────────────────────────────────────────────────────────── */
.rmd-bl .rmd-ba__empty { padding: 72px 0 40px; text-align: center; }
.rmd-bl .rmd-ba__empty-h { font-size: 26px; font-weight: 500; letter-spacing: -.02em; color: var(--ink); }
.rmd-bl .rmd-ba__empty-p { margin-top: 12px; font-size: var(--t-sec); line-height: var(--lh-text); color: var(--slight); }
.rmd-bl .rmd-ba__empty .rmd-more { margin-top: 22px; }

@media (max-width: 720px) {
	/* NO top padding (27/08): this 30px predates the full-bleed band and was
	   THE mystery white strip between the header and the hero on every phone —
	   invisible in the local previews, which render the band without the
	   chrome's <main>. The band opens flush under the header, as on desktop;
	   the breathing inside it is the band's own job. */
	.rmd-bl.rmd-ba { padding: 0 0 64px; }
	.rmd-bl .rmd-ba__lead { margin-top: 34px; }
	.rmd-bl .rmd-ba__all { margin-top: 38px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   MOTION
   ══════════════════════════════════════════════════════════════════════════ */
/* THE ENTRANCE (27/08, owner's ask — the landing pages' "mirage"): the blog's
   content materializes in a short fade while the chrome above it stays
   instant. Two deliberate numbers:
   · .01, not 0 — Chrome excludes only TRUE-zero opacity from Largest
     Contentful Paint, so this exact reveal costs nothing in Core Web Vitals;
     a from-0 fade would push the article cover's LCP by the whole duration.
   · .55s — long enough to read as a materialization, short enough that a
     reader arriving mid-scroll from a SERP never waits on it. */
@keyframes rmdEntrance { from { opacity: .01; } to { opacity: 1; } }
.rmd-bl { animation: rmdEntrance .55s ease-out both; }

/* AJAX page swap (27/08, the owner's pick over a "load more"): the numbered
   pagination stays the UI; post.js exchanges the listing wrap in place, the
   reader stays put, and the skeletons below ARE the transition. The fresh
   cards then rise in so the change of page reads as a change. */
@keyframes rmdCardIn { from { opacity: .01; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.rmd-bl .rmd-card-in { animation: rmdCardIn .4s ease-out both; }
/* Skeleton cards — the ghosts post.js raises when the exchange outlives
   250ms. They wear the real card's frame and media ratio, so nothing jumps
   when the articles land; the shimmer sweeps left, and dies to a still
   ground under prefers-reduced-motion via the global motion rule. */
.rmd-bl .rmd-sk { pointer-events: none; }
.rmd-bl .rmd-sk .rmd-card__media,
.rmd-bl .rmd-sk__line {
	background: linear-gradient(90deg, #EEF0F6 25%, #F7F8FC 37%, #EEF0F6 63%);
	background-size: 400% 100%;
	animation: rmdShimmer 1.3s ease infinite;
}
.rmd-bl .rmd-sk__line { display: block; height: 13px; border-radius: 7px; margin-top: 12px; }
.rmd-bl .rmd-sk__line--chip { width: 64px; height: 22px; border-radius: 999px; margin-top: 0; }
.rmd-bl .rmd-sk__line--title { height: 17px; width: 85%; margin-top: 16px; }
.rmd-bl .rmd-sk__line--short { width: 55%; }
@keyframes rmdShimmer { from { background-position: 100% 0; } to { background-position: 0 0; } }

@media (prefers-reduced-motion: reduce) {
	.rmd-bl { animation: none; }
	.rmd-bl *, .rmd-bl *::before, .rmd-bl *::after {
		animation-duration: .001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: .001ms !important;
		scroll-behavior: auto !important;
	}
	.rmd-bl .rmd-card:hover, .rmd-bl .rmd-promo:hover { transform: none; }
}

}

/* ══════════════════════════════════════════════════════════════════════════
   UNLAYERED ANTIDOTE — deliberately OUTSIDE @layer components. Do not move it
   inside: being unlayered is the whole mechanism.

   wp-admin injects the Tailwind PLAY CDN site-wide (a WPCode head snippet,
   there for a Tailwind-styled form/popup — cdn.tailwindcss.com, the dev-only
   runtime build). That script scans every class in the DOM and generates
   UNLAYERED utilities for whatever parses as one. Gutenberg stamps `size-full`
   on every full-size image, and Tailwind's `.size-full` is
   `width:100%; height:100%`.

   MEASURED ON PROD 19/08/2026, /en/blog/reactive-web-design/: the figure's
   height:100% resolved against its grid area — the whole article — so one
   image became a ~28 000px empty box, the footer landed mid-page and the rest
   of the article painted underneath it. 33 of 193 posts on the main site carry
   the class; this article was just the loudest. (Its tailwind.config disables
   preflight, so the colliding utility really is the only projectile — verified
   by diffing the generated stylesheet: `.size-full` was the single rule.)

   A rule inside @layer cannot answer it — unlayered beats layered whatever the
   specificity — so this one stays unlayered and wins by SPECIFICITY instead:
   (0,2,1) against the utility's (0,1,0), whichever loads last. width/height
   back to auto is exactly what WP core intends for the class (it never styles
   it); the layered img rules then apply as designed.

   The REAL fix is scoping that snippet in wp-admin to the pages whose markup
   needs it. This line makes the blog immune either way. */
.rmd-bl :is(figure, img).size-full {
	width: auto; height: auto;
}

/* Same mechanism, second projectile (03/09): the block editor's own table
   classes. `.has-fixed-layout` (table-layout: fixed; width: 100%) forces three
   or four columns into a 340px phone frame — 85px cells, words stacked one per
   line — and `.has-text-align-center` on every cell of a comparison table
   centres text that is already breaking. Both come from block-library CSS,
   unlayered, so the layered table rules above cannot touch them. Under 640px
   the frame is the scrolling box and columns may take their natural width;
   above it the editor's choices stand. Specificity (0,3,1) and (0,3,0) against
   the library's (0,2,0) and (0,1,0). */
@media (max-width: 640px) {
	.rmd-bl .rmd-prose table.has-fixed-layout { table-layout: auto; }
	.rmd-bl .rmd-prose :is(td, th).has-text-align-center { text-align: left; }
	/* .wp-block-table td { padding: .5em } is block-library's too (0,1,1) —
	   the classic .rmd-tw tables already get this from the layered rules. */
	.rmd-bl .rmd-prose :is(.wp-block-table, .rmd-tw) :is(td, th) { padding: 10px 12px; }
	/* A FLOOR under every column (owner's phone recording, 03/09 evening). With
	   the fixed layout released, Chrome sized the guide's four columns at ~100px
	   and wrapped by word — but WebKit treats a cell that inherits the prose's
	   overflow-wrap: break-word as breakable at EVERY character when it sizes
	   auto-layout columns, so Safari crushed "Keyword type" to one letter per
	   line (K/E/Y/W/O/R/D) and the table "fitted" 340px unreadably. 140px of
	   content per cell (164 with padding) means a column is never narrower than
	   a word: 2 columns still fit a phone, 3+ scroll in the frame with the hint
	   above. overflow-wrap: normal on the cells is the second half for WebKit —
	   columns are sized by whole words; a genuinely long string widens its
	   column, and the frame scrolls, which is what the frame is for. */
	.rmd-bl .rmd-prose :is(td, th) { min-width: 140px; overflow-wrap: normal; }
}

/* Third projectile, and the one that hit every article (owner's phone recording,
   03/09): the FIGURE rhythm. The layered rule asks 36px above a figure, 28 on a
   phone; measured on staging every image sat at 0px from its heading or the
   paragraph before it, on desktop too. Two unlayered sheets zero it: the Tailwind
   Play CDN's reset (`figure { margin: 0 }`, site-wide snippet) and block-library's
   `.wp-block-image { margin: 0 0 1em }`. Both beat any layered value, so the
   rhythm lives here, at (0,2,1) and (0,2,2) against their (0,0,1) and (0,1,0).
   The gap BELOW a figure is carried by the next element's margin-top (layered,
   untouched by either sheet) and was already right — 36px, 28 on a phone.
   An image straight under a heading is that heading's own illustration: it sits
   a little closer to its title (24px, 20 on a phone — the distance a paragraph
   keeps from a heading) than to the text that follows it. */
.rmd-bl .rmd-prose > figure,
.rmd-bl .rmd-prose .elementor-widget-container > figure { margin-top: 36px; margin-bottom: 0; }
.rmd-bl .rmd-prose :is(h2, h3, h4, h5, h6) + figure { margin-top: 24px; }
@media (max-width: 720px) {
	.rmd-bl .rmd-prose > figure,
	.rmd-bl .rmd-prose .elementor-widget-container > figure { margin-top: 28px; }
	.rmd-bl .rmd-prose :is(h2, h3, h4, h5, h6) + figure { margin-top: 20px; }
}

/* Fourth (03/09, regression sweep): the block editor's table BORDERS. Its inline
   sheet (#wp-block-table-inline-css, unlayered) draws `td, th { border: 1px
   solid }` — a full grid, in the text colour — plus `thead { border-bottom: 3px
   solid }`. The design, in the layered rules above, wants row lines only, in
   --bord, the header row tinted, and nothing under the last row inside the
   rounded frame; every one of those declarations was losing. Same cure as the
   three blocks above. The classic editor's .rmd-tw tables never had the
   problem: WordPress ships no CSS for a bare <table>. */
.rmd-bl .rmd-prose .wp-block-table :is(td, th) { border: 0; border-bottom: 1px solid var(--bord); }
.rmd-bl .rmd-prose .wp-block-table :is(thead, tfoot) { border: 0; }
.rmd-bl .rmd-prose .wp-block-table tbody tr:last-child td { border-bottom: 0; }
/* …and the cell padding the design asks for (14×18), which the same inline
   sheet's `padding: .5em` was also overriding. Above 640px only: the phone
   block earlier in this file keeps 10×12 there, and this later rule must not
   reach down and undo it. */
@media (min-width: 641px) {
	.rmd-bl .rmd-prose .wp-block-table :is(td, th) { padding: 14px 18px; }
}
