/* ==========================================================================
   Additions — the small number of things the design files do not cover.
   Everything here exists because a mockup used an inline style, or because a
   client requirement arrived after the handoff. Keep this file short: if a
   rule belongs to the design, it belongs in the generated style.css instead.
   ========================================================================== */

/* The mockups wrap the newsletter form in an inline style. Named instead, so
   the same markup can be reused in the homepage band, the article footer and
   the rail without repeating it three times. */
.nl-form {
	flex: 1 1 auto;
	min-width: min(300px, 100%);
	max-width: 520px;
}

/* Search form. Used on the search results page and the 404. */
.bm-search {
	display: flex;
	gap: 10px;
	flex-wrap: wrap;
	margin: 22px 0 8px;
}

.bm-search input[type="search"] {
	flex: 1 1 auto;
	min-width: min(280px, 100%);
	padding: 13px 16px;
	border: 1.5px solid var(--line, #e3e0da);
	background: #fff;
	font: inherit;
	font-size: 15px;
}

.bm-search input[type="search"]:focus-visible {
	outline: 2px solid var(--red-ui, #e84a3c);
	outline-offset: 1px;
}

.bm-search button {
	padding: 13px 26px;
	border: 0;
	background: var(--red-ui, #e84a3c);
	color: #fff;
	font-family: var(--display, inherit);
	font-weight: 800;
	font-size: 12px;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	cursor: pointer;
}

.bm-search button:hover {
	background: var(--red-ink, #c63528);
}

/* Capital Business Media logo in the footer — a client requirement that
   arrived after the design was signed off. */
.foot-cbm {
	display: flex;
	justify-content: center;
	padding: 26px 0 4px;
	border-top: 1px solid rgba(255, 255, 255, 0.12);
	margin-top: 26px;
}

.foot-cbm img {
	width: auto;
	height: 38px;
	max-width: 100%;
	opacity: 0.75;
	transition: opacity 0.15s;
}

.foot-cbm a:hover img {
	opacity: 1;
}

/* Screen-reader-only text. The design uses .sr-only on the homepage H1 but
   only defines it in that one file. */
.sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* WordPress core pagination, used on search, author and generic archives.
   Category archives use the design's own .pager markup. */
.navigation.pagination {
	margin: 34px 0 8px;
}

.navigation.pagination .nav-links {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.navigation.pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 42px;
	height: 42px;
	padding: 0 12px;
	border: 1.5px solid var(--line, #e3e0da);
	background: #fff;
	font-family: var(--display, inherit);
	font-weight: 800;
	font-size: 13px;
}

.navigation.pagination .page-numbers.current {
	background: var(--black, #171614);
	border-color: var(--black, #171614);
	color: #fff;
}

.navigation.pagination a.page-numbers:hover {
	border-color: var(--red-ui, #e84a3c);
	color: var(--red-ink, #c63528);
}

/* ==========================================================================
   Profiles — modelled on Property Portfolio Investor's layout, in the
   Business Matters design language. Square portrait, "At a glance" panel.
   ========================================================================== */

.profile-layout .pmain {
	font-family: var(--body, inherit);
}

.phead {
	display: grid;
	grid-template-columns: 220px minmax(0, 1fr);
	gap: 28px;
	align-items: start;
	padding-bottom: 26px;
	margin-bottom: 30px;
	border-bottom: 3px solid var(--black, #171614);
}

.phead .portrait {
	aspect-ratio: 1 / 1;
	overflow: hidden;
	border: 1px solid var(--line, #e3e0da);
}

.phead .portrait img,
.profile-cards .portrait img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

/* Key facts. The <h3> sits inside the <dl> to match PPI's markup, so it needs
   pulling out of the definition-list flow explicitly. */
.keyfacts {
	margin: 0 0 18px;
}

.keyfacts h3 {
	font-family: var(--display, inherit);
	font-weight: 900;
	font-size: 12px;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	margin: 0 0 12px;
	padding-bottom: 10px;
	border-bottom: 3px solid var(--red, #e84a3c);
}

.keyfacts .kf {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	gap: 7px 18px;
	font-size: 14.5px;
}

.keyfacts dt {
	font-family: var(--display, inherit);
	font-weight: 800;
	font-size: 10.5px;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	color: var(--grey-2, #6b6862);
	padding-top: 3px;
}

.keyfacts dd {
	margin: 0;
	line-height: 1.45;
}

.connect {
	display: flex;
	align-items: center;
	gap: 14px;
	flex-wrap: wrap;
	font-family: var(--display, inherit);
	font-weight: 800;
	font-size: 11px;
	text-transform: uppercase;
	letter-spacing: 0.06em;
}

.connect .lbl {
	color: var(--grey-2, #6b6862);
}

.connect a {
	color: var(--red-ink, #c63528);
}

.connect a:hover {
	text-decoration: underline;
}

/* Portrait cards in the archive and the "More profiles" row. */
.profile-cards .img.portrait {
	aspect-ratio: 1 / 1;
	overflow: hidden;
}

@media (max-width: 699px) {
	.phead {
		grid-template-columns: minmax(0, 1fr);
		gap: 20px;
	}

	.phead .portrait {
		max-width: 200px;
	}
}

/* ==========================================================================
   Reveal-on-scroll safety.

   The design hides every `.reveal` element with opacity:0 and relies on
   JavaScript to add `.in` when it scrolls into view. If that script does not
   run — a blocked asset, an ad-blocker, an old browser — the whole page is
   invisible and the reader sees a blank screen that appears not to scroll.

   The `bm-js` class is set inline in <head> before anything paints, so the
   hidden state only ever applies when JavaScript is definitely running.
   ========================================================================== */

html:not(.bm-js) .reveal {
	opacity: 1 !important;
	transform: none !important;
	transition: none !important;
}

/* Someone who has asked for reduced motion gets the content, not the movement. */
@media (prefers-reduced-motion: reduce) {
	.reveal {
		opacity: 1 !important;
		transform: none !important;
		transition: none !important;
	}
}

/* ==========================================================================
   Scroll fix.

   The page would not scroll with a mouse wheel, although window.scrollTo()
   worked perfectly — which is exactly what made this look for so long like a
   JavaScript fault rather than a CSS one.

   The cause is overflow propagation. The viewport takes its overflow from the
   ROOT element; only when the root is `visible` in both axes is the value
   taken from <body> instead — and body is then painted as though it were
   `visible` itself. Live has no overflow rule on <html> at all, so that is the
   path live takes, and live scrolls.

   cbm-responsive.css sets overflow-x:hidden on BOTH html and body. Because
   html is then not `visible`, html's value is the one that goes to the
   viewport and body keeps its own — and `hidden` on one axis forces the other
   to compute to `auto`. That makes <body> a scroll container exactly as tall
   as its own content: it can never scroll, and it sits between the pointer and
   the viewport swallowing every wheel event. Programmatic scrolling still
   worked because it addresses the viewport directly.

   An earlier attempt here used `overflow-x: clip`, on the grounds that clip
   does not create a scroll container. That is true of the element it is set
   on, and irrelevant here: clip is still not `visible`, so body stayed the
   scroll container and the page stayed stuck.

   Forcing html to `visible` in both axes restores live's behaviour. Horizontal
   overflow is still clipped, because body's own overflow-x:hidden is now what
   propagates to the viewport — and body.drawer-open{overflow:hidden} locks
   scrolling behind the mobile menu for that same reason.
   ========================================================================== */

html {
	overflow-x: visible;
	overflow-y: visible;
}

/* ==========================================================================
   Contact form feedback.

   The design's form is a mockup — its submit handler only changes the button
   label. The real one reports what actually happened, so these two states
   need styling the design does not provide.
   ========================================================================== */

.bm-form-ok,
.bm-form-error {
	padding: 14px 16px;
	margin: 0 0 18px;
	font-size: 14.5px;
	line-height: 1.5;
	border-left: 4px solid;
}

.bm-form-ok {
	background: #eef7f0;
	border-left-color: #2e7d47;
	color: #1d5c31;
}

.bm-form-error {
	background: #fdf0ee;
	border-left-color: var(--red-ui, #e84a3c);
	color: var(--red-ink, #c63528);
}

.bm-form-error a {
	color: inherit;
	font-weight: 700;
	text-decoration: underline;
}

/* ==========================================================================
   Newsletter schedule on the subscribe page.

   Richard supplied the real names and send times on 29 Aug, replacing the four
   the designer invented. Eight of them, so a plain list rather than cards —
   the reader is scanning for a day and a subject, not browsing.

   Individual opt-in is not wired up yet: the Mailchimp form posts a hidden
   field of seven tag IDs and subscribes to all of them at once, and there is
   nothing in the markup saying which ID is which newsletter. Turning this list
   into checkboxes needs that mapping from Mailchimp.
   ========================================================================== */

.nl-list {
	list-style: none;
	margin: 0 0 34px;
	padding: 0;
	border-top: 1px solid var(--line, #e3e0da);
}

.nl-list li {
	display: grid;
	grid-template-columns: minmax(120px, 1.1fr) minmax(120px, 1fr) minmax(0, 2.4fr);
	gap: 4px 22px;
	align-items: baseline;
	padding: 15px 0;
	border-bottom: 1px solid var(--line, #e3e0da);
}

.nl-name {
	font-family: var(--display, inherit);
	font-weight: 800;
	font-size: 15px;
}

.nl-when {
	font-family: var(--display, inherit);
	font-weight: 700;
	font-size: 11.5px;
	text-transform: uppercase;
	letter-spacing: 0.09em;
	color: var(--red-ink, #c63528);
	font-variant-numeric: tabular-nums;
}

.nl-what {
	font-size: 14.5px;
	line-height: 1.5;
	color: var(--grey-2, #6b6862);
}

@media (max-width: 699px) {
	.nl-list li {
		grid-template-columns: minmax(0, 1fr);
		gap: 3px;
		padding: 13px 0;
	}
}

/* ---------------------------------------------------------------------------
   Advert creatives
   ---------------------------------------------------------------------------
   The theme's base rule is `img{width:100%;height:100%;object-fit:cover}`,
   which is right for editorial thumbnails that must fill a fixed card, and
   wrong for an advertiser's creative. A booked banner is supplied at an exact
   size (the zone register in inc/ads.php declares them) and must render at
   that size: never upscaled -- the 970x250 billboard was being stretched to
   ~1209px, i.e. ~1814 device pixels on a 1.5x screen -- and never cropped,
   which `object-fit:cover` would do the moment a creative's ratio differed
   from its box.

   So: natural size, centred, shrink-to-fit on narrow screens only.
   -------------------------------------------------------------------------*/
.blogkit-ad img,
.bm-sponsor-logo img {
	width: auto;
	height: auto;
	max-width: 100%;
	object-fit: contain;
	margin-left: auto;
	margin-right: auto;
}

/* The banner zones are centred bands; the rail/MPU zones sit in a narrow
   column where the creative already fills the width. */
.blogkit-ad-zone {
	display: flex;
	justify-content: center;
}

/* ---------------------------------------------------------------------------
   Newsletter picker
   ---------------------------------------------------------------------------
   The schedule list doubles as the choice, so the row gains a checkbox column
   and becomes a <label> -- the whole row is the hit area, not just the 18px
   box. The plain `.nl-list` rules above still style a non-interactive list, so
   both forms of the block keep working.
   -------------------------------------------------------------------------*/
.nl-list--pick li {
	display: block;
	padding: 0;
}

.nl-list--pick .nl-row {
	display: grid;
	grid-template-columns: 22px minmax(110px, 1.1fr) minmax(110px, 1fr) minmax(0, 2.4fr);
	gap: 4px 18px;
	align-items: baseline;
	padding: 14px 0;
	cursor: pointer;
}

.nl-list--pick .nl-pick {
	width: 17px;
	height: 17px;
	margin: 0;
	accent-color: var(--red-ink, #c63528);
	cursor: pointer;
	/* Sit with the name, not centred against a description that wraps to three
	   lines -- otherwise the box drifts below the row it labels. */
	align-self: start;
	margin-top: 1px;
}

/* An unticked row recedes, so what you are getting reads at a glance. */
.nl-list--pick .nl-row:has(.nl-pick:not(:checked)) .nl-name,
.nl-list--pick .nl-row:has(.nl-pick:not(:checked)) .nl-when,
.nl-list--pick .nl-row:has(.nl-pick:not(:checked)) .nl-what {
	opacity: 0.45;
}

.nl-list--pick .nl-row:hover .nl-name {
	color: var(--red-ink, #c63528);
}

.nl-picker .nl-none {
	margin: 0 0 14px;
	font-size: 14px;
	font-weight: 700;
	color: var(--red-ink, #c63528);
}

@media (max-width: 699px) {
	.nl-list--pick .nl-row {
		grid-template-columns: 22px minmax(0, 1fr);
		gap: 3px 14px;
		padding: 13px 0;
	}

	/* Name sits beside the box; the rest lines up under it. */
	.nl-list--pick .nl-when,
	.nl-list--pick .nl-what {
		grid-column: 2;
	}
}

/* The API path reports back here instead of throwing the reader onto a
   Mailchimp page. Only ever visible after a submission. */
.nl-picker .nl-msg {
	margin: 14px 0 0;
	padding: 12px 14px;
	font-size: 15px;
	line-height: 1.45;
	border-left: 3px solid;
}

.nl-picker .nl-msg.is-ok {
	border-color: var(--green-ink, #2f7a4f);
	background: var(--green-wash, #eef6f1);
	color: var(--green-ink, #2f7a4f);
}

.nl-picker .nl-msg.is-error {
	border-color: var(--red-ink, #c63528);
	background: var(--red-wash, #fdf0ee);
	color: var(--red-ink, #c63528);
}

.nl-picker button[disabled] {
	opacity: 0.6;
	cursor: progress;
}

/* ---------------------------------------------------------------------------
   Inline newsletter sign-up
   ---------------------------------------------------------------------------
   Occupies a leaderboard slot when it is unsold. Sized to sit comfortably in a
   728x90 band on desktop and stack on a phone.
   -------------------------------------------------------------------------*/
.nl-inline {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
	gap: 10px 28px;
	align-items: center;
	padding: 18px 22px;
	border: 1px solid var(--line, #e3e0da);
	border-left: 4px solid var(--red-ink, #c63528);
	background: var(--wash, #fdf6ee);
}

.nl-inline .lbl {
	display: block;
	font-family: var(--display, inherit);
	font-weight: 800;
	font-size: 11.5px;
	text-transform: uppercase;
	letter-spacing: 0.09em;
	color: var(--red-ink, #c63528);
	margin-bottom: 3px;
}

.nl-inline-copy p {
	margin: 0;
	font-size: 15.5px;
	line-height: 1.4;
}

.nl-inline-form {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 0;
}

.nl-inline-form input[type="email"] {
	flex: 1 1 200px;
	min-width: 0;
	margin: 0;
}

.nl-inline-form button {
	flex: 0 0 auto;
	margin: 0;
	min-height: 44px;
}

/* The message and warning span the whole form when they appear. */
.nl-inline-form .nl-msg,
.nl-inline-form .nl-none {
	flex: 1 1 100%;
	margin: 4px 0 0;
}

@media (max-width: 767px) {
	.nl-inline {
		grid-template-columns: minmax(0, 1fr);
		padding: 16px 18px;
	}
}

/* ---------------------------------------------------------------------------
   Magazine issue pages
   -------------------------------------------------------------------------*/
.mag-issue-hero {
	padding: 44px 0 40px;
	background: var(--wash, #fdf6ee);
	border-bottom: 3px solid var(--black, #171614);
}

.mag-issue-grid {
	display: grid;
	grid-template-columns: 280px minmax(0, 1fr);
	gap: 48px;
	align-items: center;
}

.mag-issue-cover img {
	width: 100%;
	height: auto;
	display: block;
	box-shadow: 0 18px 40px rgba(23, 22, 20, 0.22);
	transform: rotate(-2deg);
}

.mag-issue-intro .kick {
	display: block;
	font-family: var(--display, inherit);
	font-weight: 800;
	font-size: 11.5px;
	text-transform: uppercase;
	letter-spacing: 0.09em;
	color: var(--red-ink, #c63528);
	margin-bottom: 8px;
}

.mag-issue-intro h1 {
	margin: 0 0 12px;
}

.mag-issue-intro .standfirst {
	font-size: 18px;
	line-height: 1.5;
	margin: 0 0 22px;
	color: var(--grey-2, #6b6862);
}

.mag-issue-cta {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin-bottom: 12px;
}

.mag-issue-intro .fine {
	margin: 0;
	font-size: 13.5px;
	color: var(--grey-2, #6b6862);
}

/* Back issues: a row of covers. */
.mag-backissues {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
	gap: 26px 22px;
}

.mag-backissues a {
	display: block;
	text-decoration: none;
}

.mag-backissues .c {
	display: block;
	margin-bottom: 10px;
	transition: transform 0.18s ease;
}

.mag-backissues .c img {
	width: 100%;
	height: auto;
	display: block;
	box-shadow: 0 8px 20px rgba(23, 22, 20, 0.16);
}

.mag-backissues a:hover .c {
	transform: translateY(-4px);
}

.mag-backissues .t {
	display: block;
	font-family: var(--display, inherit);
	font-weight: 800;
	font-size: 14.5px;
	line-height: 1.3;
}

@media (max-width: 767px) {
	.mag-issue-grid {
		grid-template-columns: minmax(0, 1fr);
		gap: 28px;
	}

	.mag-issue-cover {
		max-width: 220px;
	}

	.mag-issue-cover img {
		transform: none;
	}

	.mag-backissues {
		grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
	}
}

/* ---------------------------------------------------------------------------
   Magazine band — let the cover be its own shape
   ---------------------------------------------------------------------------
   style.css sets `.mag-band .cover{aspect-ratio:3/4}`, and the theme's base
   rule makes every image `object-fit:cover`. A 3/4 box is 0.750 wide-to-tall;
   the covers are 900x1273, which is 0.707 — A4 trim. So the box was wider than
   the artwork in proportion, and `cover` took the difference off the top and
   bottom edges. Roughly 23px of a 280px cover, split between the two ends.

   That is exactly what went missing: Richard, 12 Sep — "cover is just a little
   squished... this one had just a bit more black above the logo and below the
   scan code". It was not scaled wrongly, it was cropped.

   Fixed by not declaring a ratio at all. The width/height attributes on the
   <img> give the browser the real one, so the space is still reserved before
   the file loads and nothing shifts — and a future cover on a different trim
   gets its own shape instead of being trimmed to this one.

   `.mag .cover` is the same box in the sidebar rail -- every article and the
   Subscribe page -- and was cropping the artwork in exactly the same way.
   Richard only saw it on the homepage; there is no reason to fix one and
   leave the other.
   -------------------------------------------------------------------------*/
.mag-band .cover,
.mag .cover {
	aspect-ratio: auto;
}

.mag-band .cover img,
.mag .cover img {
	width: 100%;
	height: auto;
	object-fit: contain;
}

/* ---------------------------------------------------------------------------
   The sign-up in the in-article slot
   ---------------------------------------------------------------------------
   `.inread` is a centring flex row built for a 300x250 creative, so a fallback
   inside it shrinks to its content. The sign-up should use the column instead:
   it is a form, not a banner.

   Only the zone stretches. `justify-content:center` on `.blogkit-ad-zone` is
   left alone, so a booked creative still sits in the middle of the measure.
   -------------------------------------------------------------------------*/
.inread .blogkit-ad-zone {
	flex: 1 1 100%;
	min-width: 0;
}

.blogkit-ad-zone .blogkit-ad__fallback {
	flex: 1 1 100%;
	min-width: 0;
}

/* One column in the body copy. The article measure is ~720px, and splitting
   that in two leaves the email field and its button fighting for ~330px. */
.inread .nl-inline {
	grid-template-columns: minmax(0, 1fr);
}

/* ---------------------------------------------------------------------------
   The inline sign-up's field and button
   ---------------------------------------------------------------------------
   These were browser defaults — Arial, a grey bevelled button, a 2px inset
   border — everywhere `.nl-inline` rendered. The design only ever styled these
   controls as `.nl-band input` / `.nl-band button`, and `.nl-inline` is not
   inside a `.nl-band`; when the full-width band came out of single.php and
   category.php on 12 Sep there was nothing left to inherit from. It was wrong
   on the category pages too, not just here.

   Values are the design's own, taken from `.nl-band` — a white field rather
   than cream, because the panel behind it is already cream.
   -------------------------------------------------------------------------*/
.nl-inline-form input[type="email"] {
	padding: 14px 16px;
	border: 1.5px solid var(--black, #0B0B0C);
	background: #fff;
	font-family: var(--body, inherit);
	font-size: 14px;
	color: var(--black, #0B0B0C);
}

.nl-inline-form input[type="email"]:focus {
	outline: 2px solid var(--red, #E84A3C);
	border-color: transparent;
}

.nl-inline-form button {
	padding: 14px 26px;
	background: var(--red-ui, #C63528);
	color: #fff;
	font-family: var(--display, inherit);
	font-weight: 800;
	font-size: 13px;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	border: none;
	cursor: pointer;
	white-space: nowrap;
	transition: background 0.15s;
}

.nl-inline-form button:hover {
	background: #A93120;
}

/* ---------------------------------------------------------------------------
   No drop cap on the sign-up
   ---------------------------------------------------------------------------
   `.art-body p:first-of-type::first-letter` gives the article's opening
   paragraph its 76px red initial. The sign-up's blurb is the first (and only)
   <p> among its own siblings, so once the form moved inside the body copy the
   rule caught it too: "The stories that matter..." rendered with a drop cap.
   -------------------------------------------------------------------------*/
.art-body .nl-inline p::first-letter {
	font-family: inherit;
	font-weight: inherit;
	font-size: inherit;
	line-height: inherit;
	color: inherit;
	float: none;
	padding: 0;
}

/* ---------------------------------------------------------------------------
   Give the ad zone a definite width
   ---------------------------------------------------------------------------
   `.blogkit-ad-zone` is a flex item inside `.ad-mobile` / `.ad-desktop-only`,
   so it sized to its content. That is harmless for an image, which brings its
   own intrinsic width, and fatal for AdSense: `<ins class="adsbygoogle">` has
   none, so the chain resolved to zero and Google reported
   "No slot size for availableWidth=0" and refused to fill.

   `justify-content:center` is already on the zone, so widening it keeps booked
   creatives centred — and in fact centres them properly on desktop, where
   `.ad-desktop-only` has no justify-content of its own and was leaving a
   shrink-to-fit zone at flex-start.
   -------------------------------------------------------------------------*/
.blogkit-ad-zone {
	width: 100%;
	min-width: 0;
}
