/*
Theme Name: MMO Culture Modern
Template: goodlife-wp
Description: MMO Culture's modern theme — sidebar/bottom-nav shell, light+dark themes, card-based layout, per the Claude Design handoff.
Version: 1.0.0
Text Domain: mmoculture-modern
*/

/* Dark is the theme's default: these are the dark values, and the light palette
   is the override under [data-theme="light"] below. Done this way round rather
   than defaulting to light and switching with JS, so a reader with JavaScript
   disabled — or one who sees the page before the bootstrap in functions.php runs
   — still gets dark rather than a flash of the wrong theme. */
:root {
	--bg: #1a1a1a;
	--card: #232323;
	--ink: #f4f4f4;
	--mut: #9d9d9d;
	--bd: #323232;
	--soft: #282828;
	--acc: #a385ff;
	/* The pointer state for controls that are already filled with --acc, where
	   there is nothing left to change but the accent itself: the copy button,
	   the comment submit and the interstitial's continue. It moves away from the
	   page — lighter here, darker in light mode — so the control reads as
	   raised under the pointer in both palettes rather than lighter in one and
	   washed out in the other. */
	--accStrong: #b9a3ff;
	--accSoft: #2c2340;
	/* The accent as a shadow colour, for the one control that has to be found
	   rather than merely seen: the interstitial's continue. Only the light theme
	   paints it — dark suppresses the glow, because the deeper purple it fills
	   that button with already separates from the panel on its own. The dark
	   value is kept, and kept at the higher alpha the dark accent needs to
	   register at all, so the base rule has something to resolve and the glow
	   comes back correct if dark ever wants it. */
	--accGlow: rgba(163,133,255,0.45);
	--amber: #f5c15a;
	--shadow: 0 1px 2px rgba(0,0,0,0.4);
	/* The pointer state for the cards. Deeper and wider than the resting shadow
	   so the card reads as lifted rather than merely re-tinted — on a dark
	   surface a background change of any size the palette allows is close to
	   invisible, which is why the hover is carried by elevation.

	   Two layers rather than one: a close contact shadow that keeps the card's
	   edge defined, and a wide ambient one carrying the height. A single 24px
	   blur dark enough to read had to be opaque enough to arrive as a hard
	   grey band under the card — split in two, each layer is lighter than that
	   one was and the falloff is gradual, so the same lift lands softly. */
	--shadow-hover: 0 2px 6px rgba(0,0,0,0.28), 0 12px 32px rgba(0,0,0,0.32);
	/* Cast upward, for surfaces that rise from the bottom edge. */
	--shadow-up: 0 -4px 20px rgba(0,0,0,0.45);
	--font-ui: 'Plus Jakarta Sans', Arial, sans-serif;
	--font-mono: 'DM Mono', 'Courier New', monospace;
	--sidebar-w: 268px;
	--rail-w: 312px;
	/* Height of the mobile bottom nav. Everything that has to sit clear of it
	   reads this rather than repeating the number, so the bar can be resized in
	   one place. The safe-area inset is folded in here so devices with a home
	   indicator get a taller bar; the nav adds the same inset to its own bottom
	   padding, keeping the icons and labels above the indicator. */
	--bottom-nav-h: calc(64px + env(safe-area-inset-bottom, 0px));
	/* Height of the sticky mobile header. The titlebar below it reads this to
	   park itself directly underneath instead of sliding out of sight behind
	   it, so the two have to agree — hence one number for both. */
	--mobile-header-h: 56px;
	/* Desktop height of the featured block. Given rather than derived because the
	   two side cards fill it as 1fr rows — without a definite height they would
	   size to their own content and the hero spanning both would follow, so the
	   block's height would drift with whatever the headlines do. */
	--featured-h: 576px;
	/* Narrowest layout the theme is designed for. Below this the page scrolls
	   sideways rather than compressing further: at 320px the paired featured
	   cards and the bottom nav's five tabs both lose more than they gain from
	   shrinking. */
	--min-w: 360px;

	/* Spacing: 8px grid. --space-half is the only sub-step, reserved for
	   tight intra-component spacing (icon gaps, badge padding). */
	--space-half: 4px;
	--space-1: 8px;
	--space-2: 16px;
	--space-3: 24px;
	--space-4: 32px;
	--space-5: 40px;

	/* Line height scales inversely with type size: a modular ratio is right for
	   font sizes but wrong here, because leading is a function of size and
	   measure. Large type needs proportionally less of it, small type more.
	   Values are chosen to land on or near the 4px sub-grid at each token's
	   intended size. */
	--lh-flat: 1;        /* fixed-height centred controls; padding owns the box */
	--lh-display: 1.12;  /* 32px+ display        36 -> 40px */
	--lh-heading: 1.25;  /* 19-26px headings     23 -> 29px */
	--lh-snug: 1.35;     /* 14-15px UI titles    15 -> 20px */
	--lh-ui: 1.45;       /* 11-13px meta/labels  11 -> 16px */
	--lh-body: 1.65;     /* reading copy         19 -> 31px */
}

/* Light, for readers who have chosen it with the toggle. */
:root[data-theme="light"] {
	--bg: #e8ecf1;
	--card: #fbfcfd;
	--ink: #16181d;
	--mut: #6d7480;
	--bd: #dfe4ea;
	--soft: #eef1f5;
	--acc: #7c3aed;
	--accStrong: #6d28d9;
	--accSoft: #efe9ff;
	--accGlow: rgba(124,58,237,0.32);
	--amber: #f5a524;
	--shadow: 0 1px 2px rgba(22,24,29,0.05);
	--shadow-hover: 0 2px 6px rgba(22,24,29,0.06), 0 12px 32px rgba(22,24,29,0.10);
	--shadow-up: 0 -4px 20px rgba(22,24,29,0.10);
}

.mmoc-body, .mmoc-body *, .mmoc-body *::before, .mmoc-body *::after {
	box-sizing: border-box;
}

.mmoc-body {
	background: var(--bg);
	color: var(--ink);
	font-family: var(--font-ui);
	line-height: var(--lh-ui);
	margin: 0;
	text-wrap: pretty;
	/* Floor for the whole layout — see --min-w. Everything else is inside the
	   body, so this is the one place it needs stating. */
	min-width: var(--min-w);
}

/* The fixed bars size to the viewport, not to the body, so on a narrower screen
   they would sit at 320px while the content they belong to is 360px wide and
   scrolled — the nav would drift out of line with the page under it. Giving them
   the same floor keeps the whole chrome on one width. */
.mmoc-bottom-nav,
.mmoc-anchor-ad {
	min-width: var(--min-w);
}

/* :where() keeps this at (0,1,0) so it still outranks the parent theme's bare
   `h1 { line-height: 1.15 }` while staying a baseline that component title
   classes below can override. Without it this rule scored (0,1,1) and silently
   beat every .mmoc-*__title, pinning them all to the heading value. */
.mmoc-body :where(h1, h2, h3) {
	font-family: var(--font-ui);
	font-weight: 800;
	line-height: var(--lh-heading);
	letter-spacing: -0.02em;
	margin: 0;
	color: var(--ink);
	text-wrap: pretty;
}

.mmoc-body a {
	text-decoration: none;
	color: inherit;
}

.mmoc-body img {
	max-width: 100%;
	display: block;
}

/* The parent theme ships `body p { font-size: 16px; line-height: 1.6em }` and
   `ul { line-height: 1.6 }`, which outrank the inherited value from every
   container below and were silently overriding their type — the article body
   read 16px/25.6px instead of its own 19px, and every list snapped to 1.6.
   Re-assert inheritance so each block's scale actually reaches its text.
   :where() keeps this at (0,1,0) so component classes below still win. */
.mmoc-body :where(p, ul, ol, li, dl, dt, dd, blockquote, figcaption, td, th) {
	font-size: inherit;
	line-height: inherit;
}

.mmoc-eyebrow {
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	line-height: var(--lh-ui);
	color: var(--acc);
}

.mmoc-meta {
	font-size: 12px;
	line-height: var(--lh-ui);
	color: var(--mut);
}

/* No background, by decision: an unfilled slot should read as empty space, not
   as a grey box waiting for something. The reserved min-heights below still hold
   the layout open so a late-filling ad does not shift the page — they just do it
   invisibly now. The radius stays because it clips the creative that lands in
   the box, not because anything is painted behind it. */
.mmoc-ad {
	background: transparent;
	border-radius: 14px;
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--mut);
	font-family: var(--font-mono);
	font-size: 12px;
	overflow: hidden;
}

.mmoc-ad--home_top { min-height: 250px; }

/* Site-wide leaderboard band. Full-bleed and above the shell, so it clears the
   sidebar rather than sitting inside the content column. Dark in both themes —
   it reads as ad chrome, not as page surface. */
.mmoc-topad {
	background: #0b0c10;
	display: flex;
	justify-content: center;
	padding: var(--space-2);
}

.mmoc-topad .mmoc-ad {
	width: 100%;
	max-width: 970px;
	border-radius: 12px;
}

@media (max-width: 899px) {
	.mmoc-topad {
		padding: var(--space-1);
	}

	/* Mobile creatives are 320x100 / 300x100 — reserving 250px of height here
	   would push the whole page below the fold. */
	.mmoc-topad .mmoc-ad--home_top {
		min-height: 100px;
		max-width: 320px;
	}
}
/* MREC on a phone, 728x90 leaderboard from the shell breakpoint up. The
   reserved height changes with the shape, or a 90px-tall leaderboard would sit
   in a 250px box with a band of empty page under it. */
.mmoc-ad--feed_inline { min-height: 250px; }

@media (min-width: 900px) {
	.mmoc-ad--feed_inline {
		min-height: 90px;
		/* Same width/max-width pair as top_stories, and for the same reason:
		   .mmoc-page__main is a flex column, where auto margins on the cross
		   axis collapse the box to its content width instead of centring a
		   full-width one. This also lets the box shrink below 728 rather than
		   overflow — the column is only 452px wide at 1120px, where the rail
		   appears. */
		width: 100%;
		max-width: 728px;
		/* Both axes named because this slot renders into two different
		   formatting contexts: .mmoc-page__main is a flex column, where
		   align-self is the inline axis, and the archive grid centres on
		   justify-self instead. Naming only one left the archive units
		   flush to the left of a 772px row. Each property is inert in the
		   context the other applies to. */
		align-self: center;
		justify-self: center;
	}
}

.mmoc-ad--feed_end { min-height: 250px; }

/* Desktop-only leaderboard above the Fresh Codes section. Hidden below the
   shell's 899px breakpoint, where a 728px-wide unit has nowhere to sit. */
.mmoc-ad--codes_top { min-height: 90px; }

@media (max-width: 899px) {
	.mmoc-ad--codes_top { display: none; }
}
/* Above Top Stories: a 728x90 leaderboard, desktop only. Below 899px the
   featured_mrec inside the featured block holds this position instead — a
   728-wide unit has nowhere to sit on a phone, which is why the slot declares no
   mobile size at all. */
.mmoc-ad--top_stories {
	min-height: 90px;
	/* Centres the 728 unit in the wider content column instead of leaving it
	   hanging on the left. align-self, not auto margins: .mmoc-page__main is a
	   flex column, and auto margins on the cross axis there collapse the box to
	   its content width instead of centring a full-width one. */
	width: 100%;
	max-width: 728px;
	align-self: center;
}

@media (max-width: 899px) {
	.mmoc-ad--top_stories { display: none; }
}

/* The mobile counterpart, a grid item of the featured block so it can follow the
   lead story directly. Both it and the band above are deferred, so theme.js
   requests whichever one the current breakpoint actually displays and the hidden
   one never fetches an ad no one can see. */
.mmoc-ad--featured_mrec { min-height: 250px; }

.mmoc-featured .mmoc-ad--featured_mrec {
	grid-column: 1 / -1;
}

@media (min-width: 900px) {
	.mmoc-ad--featured_mrec { display: none; }
}

/* Reserved boxes match the size each slot declares in inc/ads.php — a 300x600
   half page reserving 250px told the reader the wrong thing and would shift the
   page by 350px when the ad filled. Width is capped too, and centred with
   align-self because .mmoc-rail is a flex column where auto margins on the cross
   axis collapse the box to its content instead. */
.mmoc-ad--rail_top {
	min-height: 600px;
	/* width with max-width, not max-width alone: align-self centres the box but
	   also makes it size to its content on the cross axis, and the only child is
	   an absolutely-positioned caption — so the box collapsed to 0 wide. */
	width: 100%;
	max-width: 300px;
	align-self: center;
}
.mmoc-ad--rail_sticky {
	min-height: 600px;
	/* width with max-width, not max-width alone: align-self centres the box but
	   also makes it size to its content on the cross axis, and the only child is
	   an absolutely-positioned caption — so the box collapsed to 0 wide. */
	width: 100%;
	max-width: 160px;
	align-self: center;
	/* Not actually sticky, despite this declaration: `.mmoc-ad { position:
	   relative }` further down the file matches with the same specificity and
	   wins on source order, so this box computes to relative and `top` offsets
	   it 80px down the rail instead of pinning it. Left as found — making it
	   stick is an ad-behaviour change, not a styling fix, and it would then need
	   an offset that clears the sticky article titlebar, whose height varies
	   with the headline. */
	position: sticky;
	top: 80px;
}
.mmoc-ad--post_intro, .mmoc-ad--post_mid { min-height: 200px; margin: var(--space-3) 0; }

/* MREC inside the article body, repeated on the cadence set by
   mmoculture_modern_insert_body_ads(). It sits inside .mmoc-article__body, so
   the body's own `> * + *` rule spaces it like any other block there and no
   top margin is set here.

   Shown at every width, unlike the mobile-only slot this replaced: Ad Inserter
   blocks 2-4 used to carry the desktop in-article units and they are now
   suppressed, so hiding this above 899px would leave the desktop reader with
   none. min-height matches the creative the slot serves at each width, so the
   reserved box does not shift when the ad arrives. */
.mmoc-ad--post_body { min-height: 250px; }

/* Every in-column article slot becomes a 728x90 leaderboard from the shell
   breakpoint up, matching feed_inline — the article column and the front page's
   content column are the same track, so a unit that fits one fits the other.

   Centred with auto margins rather than align-self: all three of these sit in
   block containers (#mmoc-article and .mmoc-article__body are both display:
   block), unlike feed_inline and top_stories, which are flex children of
   .mmoc-page__main and centre on the cross axis instead.

   post_body sets only the horizontal margins, because .mmoc-article__body's
   `> * + *` rule owns its top margin — writing the shorthand here would drop
   the spacing between the ad and the paragraph above it. */
@media (min-width: 900px) {
	.mmoc-ad--post_body {
		min-height: 90px;
		width: 100%;
		max-width: 728px;
		margin-left: auto;
		margin-right: auto;
	}

	.mmoc-ad--post_intro, .mmoc-ad--post_mid {
		min-height: 90px;
		width: 100%;
		max-width: 728px;
		margin: var(--space-3) auto;
	}
}
.mmoc-ad--anchor { min-height: 54px; max-height: 100px; }
.mmoc-ad--extra_square { min-height: 200px; }

/* The interstitial's own box, so the panel is the size of the creative it is
   waiting for rather than collapsing to nothing. */
.mmoc-ad--interstitial {
	min-height: 480px;
	max-width: 320px;
	width: 100%;
	align-self: center;
}

/* In-feed slots. The label sits behind the ad unit, so the container has to be
   the positioning context and the unit has to sit on top of it. */
.mmoc-ad {
	position: relative;
}

.mmoc-ad__unit {
	position: relative;
	z-index: 1;
}

.mmoc-ad__label {
	/* Centred in the reserved box and out of the way: it is a caption for an
	   empty slot, never something to click or select. */
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	text-align: center;
	padding: 0 var(--space-2);
	pointer-events: none;
}

/* The house creative for slots the ad stack is not filling. Same absolute box
   as the caption, one layer above it, so the caption is only ever seen if a
   slot declares a size with no file in assets/ads/.

   object-fit: contain, not cover: these are exact-size creatives standing in
   for exact-size inventory, and cropping one would show a shape the slot never
   sells. In a box narrower than the creative it letterboxes, which is what a
   real ad does there too. */
.mmoc-ad__house {
	position: absolute;
	inset: 0;
	z-index: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	pointer-events: none;
}

.mmoc-ad__house img {
	max-width: 100%;
	max-height: 100%;
	width: auto;
	height: auto;
	object-fit: contain;
}

/* Both go the moment the ad stack puts something in the unit, so a filled slot
   never has a caption or a house ad sitting behind the creative. Cheaper and
   more reliable than watching for it in script, and it reverses by itself if
   the slot is later emptied. */
.mmoc-ad:has(.mmoc-ad__unit > *) .mmoc-ad__label,
.mmoc-ad:has(.mmoc-ad__unit > *) .mmoc-ad__house {
	display: none;
}

/* Spans the archive grid rather than taking one cell of two. */
.mmoc-grid .mmoc-ad--feed-slot {
	grid-column: 1 / -1;
}

/* The two in-feed cadences, each hidden where it is not the one in use. The
   phone slots sit after articles 1, 3, 5 …; the desktop ones after 2, 6, 10 —
   see mmoculture_modern_feed_ad(). Both sets are rendered on every page and one
   of them is always display: none, which is free: theme.js only activates the
   units that are still displayed, so a slot hidden here costs no ad request.

   Written as two max-/min-width queries rather than one base rule plus an
   override so neither has to restore .mmoc-ad's display: flex. */
@media (min-width: 900px) {
	.mmoc-ad--feed-slot--narrow {
		display: none;
	}
}

@media (max-width: 899px) {
	.mmoc-ad--feed-slot--wide {
		display: none;
	}
}

.mmoc-shell {
	display: block;
}

@media (min-width: 900px) {
	.mmoc-shell {
		display: grid;
		grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
	}
}

.mmoc-sidebar {
	display: none;
}

@media (min-width: 900px) {
	.mmoc-sidebar {
		display: flex;
		flex-direction: column;
		background: var(--card);
		border-right: 1px solid var(--bd);
		padding: var(--space-3) var(--space-2);
		position: sticky;
		top: 0;
		height: 100vh;
		overflow-y: auto;
	}
}

.mmoc-sidebar__logo {
	padding: 0 var(--space-1) var(--space-3);
	display: block;
}

/* Both wordmarks, for the same reason the breadcrumb needs one: the parent's
   `a { outline: 0 }` leaves the home link with nothing to show when it is
   tabbed to. No hover state — a wordmark that lights up reads as a control. */
.mmoc-sidebar__logo:focus-visible,
.mmoc-mobile-header__logo:focus-visible {
	outline: 2px solid var(--acc);
	outline-offset: 2px;
	border-radius: 8px;
}

.mmoc-sidebar__logo img {
	width: 168px;
}

/* The wordmark is a dark PNG, so it needs inverting on the dark default and
   leaving alone in light. */
.mmoc-sidebar__logo img {
	filter: invert(1) brightness(1.9);
}

:root[data-theme="light"] .mmoc-sidebar__logo img {
	filter: none;
}

.mmoc-sidebar__nav {
	display: flex;
	flex-direction: column;
	gap: var(--space-half);
}

/* Prefixed for the same reason as the interstitial button above: without it
   `.mmoc-body a { color: inherit }` wins and every inactive sidebar link renders
   at --ink, as bright as the active one, losing the muted/current distinction the
   bottom nav has. */
.mmoc-body .mmoc-navlink {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	padding: var(--space-1) var(--space-2);
	min-height: 40px;
	border-radius: 11px;
	font-size: 15px;
	font-weight: 600;
	line-height: var(--lh-snug);
	color: var(--mut);
	transition: background-color .18s ease, color .18s ease;
}

/* Prefixed too, so it stays above the base rule rather than relying on the two
   tying on specificity and this one happening to come later in the file. */
.mmoc-body .mmoc-navlink.is-active {
	background: var(--accSoft);
	color: var(--acc);
}

/* --mut to --ink over a --soft row: the same pair the bottom nav and the header
   controls use, so a pointer picks a link out of the column without dressing it
   up as the current one. */
.mmoc-body .mmoc-navlink:hover,
.mmoc-body .mmoc-navlink:focus-visible {
	background: var(--soft);
	color: var(--ink);
}

/* The active link needs saying separately or the rule above takes it over — the
   two tie at (0,3,0) and this one sits later — and the current page would drop
   its accent for a plain row the moment the pointer crossed it. Same arrangement
   as .mmoc-bottom-nav__item.is-active:hover. */
.mmoc-body .mmoc-navlink.is-active:hover,
.mmoc-body .mmoc-navlink.is-active:focus-visible {
	background: var(--accSoft);
	color: var(--acc);
}

/* Inset, like the bottom nav's: the row is only 40px tall inside a padded
   column, and an outset ring would collide with the link above it. */
.mmoc-body .mmoc-navlink:focus-visible {
	outline: 2px solid var(--acc);
	outline-offset: -2px;
}

.mmoc-navlink__icon svg,
.mmoc-theme-toggle__icon svg {
	width: 20px;
	height: 20px;
}

/* An inline SVG sits on the text baseline, so its box carries a couple of pixels
   of descender space below the glyph — a 20px icon in a 24px box. The glyph then
   renders ~2px above the centre of the label beside it, and align-items: center
   on the row cannot correct it: it is centring the box, which is already
   centred. Block-level icons have no baseline and no phantom space, so the glyph
   and the label share a centre line. Applied to every icon paired with text or
   centred in a control. */
.mmoc-navlink__icon svg,
.mmoc-theme-toggle__icon svg,
.mmoc-bottom-nav__icon svg,
.mmoc-mobile-header__search svg,
.mmoc-sheet__close svg,
.mmoc-more-sheet__item svg,
.mmoc-adjacent__dir svg {
	display: block;
}

.mmoc-theme-toggle--mobile .mmoc-theme-toggle__icon svg {
	width: 18px;
	height: 18px;
}

/* The toggle carries both icons; aria-pressed (set by theme.js) picks which
   one shows, so the swap needs no JS of its own. */
.mmoc-theme-toggle .mmoc-icon--sun,
.mmoc-theme-toggle[aria-pressed="true"] .mmoc-icon--moon {
	display: none;
}

.mmoc-theme-toggle[aria-pressed="true"] .mmoc-icon--sun {
	display: block;
}

.mmoc-theme-toggle {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	padding: var(--space-1) var(--space-2);
	min-height: 40px;
	border-radius: 11px;
	border: none;
	background: none;
	font-family: var(--font-ui);
	font-size: 15px;
	font-weight: 600;
	color: var(--mut);
	cursor: pointer;
	margin-top: auto;
	text-align: left;
	transition: background-color .18s ease, color .18s ease;
}

/* The toggle is the last row of the sidebar column, so it takes the navlink's
   state rather than an icon button's — it is a row, not a round control. The
   --mobile variant below is a 36px square on --card; --soft still reads against
   that, and the class it sets loses to this one's extra pseudo-class anyway. */
.mmoc-theme-toggle:hover,
.mmoc-theme-toggle:focus-visible {
	background: var(--soft);
	color: var(--ink);
}

.mmoc-theme-toggle:focus-visible {
	outline: 2px solid var(--acc);
	outline-offset: 2px;
}

.mmoc-mobile-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	/* Fixed height rather than padding-driven: the titlebar sticks to the
	   bottom of this bar, so its height has to be a number both can use. The
	   border is inside it — box-sizing is border-box. */
	height: var(--mobile-header-h);
	padding: 0 var(--space-2);
	background: var(--bg);
	position: sticky;
	top: 0;
	z-index: 50;
	border-bottom: 1px solid var(--bd);
}

@media (min-width: 900px) {
	.mmoc-mobile-header {
		display: none;
	}
}

.mmoc-mobile-header__logo img {
	width: 104px;
}

/* The wordmark is a dark PNG, so it needs inverting on the dark default and
   leaving alone in light. */
.mmoc-mobile-header__logo img {
	filter: invert(1) brightness(1.9);
}

:root[data-theme="light"] .mmoc-mobile-header__logo img {
	filter: none;
}

/* 36px, not the 44px this used to be: the header is now 56px tall and a 44px
   control left it no breathing room. The 44px touch target is preserved by the
   header's own height — the control is centred in a 56px bar with nothing else
   to hit. */
.mmoc-theme-toggle--mobile {
	width: 36px;
	height: 36px;
	min-height: 0;
	border-radius: 10px;
	background: var(--card);
	justify-content: center;
	margin-top: 0;
	padding: 0;
}

/* The header's trailing controls. Without this wrapper the header's
   space-between would spread three children across the bar and float the search
   control into the middle. */
.mmoc-mobile-header__actions {
	display: flex;
	align-items: center;
	gap: var(--space-1);
}

/* Same box as the theme toggle beside it — the two read as one pair. */
.mmoc-mobile-header__search {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	padding: 0;
	border: 0;
	border-radius: 10px;
	background: var(--card);
	/* Same --mut as the theme toggle it sits beside — the pair is one set of
	   header affordances, and --ink made this one read as the loud sibling. */
	color: var(--mut);
	cursor: pointer;
}

.mmoc-mobile-header__search:hover {
	color: var(--ink);
}

/* Matching .mmoc-theme-toggle__icon svg next to it rather than the bottom nav's
   22px — these two sit side by side and are read together. */
.mmoc-mobile-header__search svg {
	width: 18px;
	height: 18px;
}

/* The control carries both marks and aria-expanded picks which one shows, the
   same arrangement .mmoc-theme-toggle uses for its moon and sun — so the swap to
   a dismiss needs no JS beyond the attribute the button already sets. */
.mmoc-mobile-header__search .mmoc-icon--close,
.mmoc-mobile-header__search[aria-expanded="true"] .mmoc-icon--search {
	display: none;
}

.mmoc-mobile-header__search[aria-expanded="true"] .mmoc-icon--close {
	display: block;
}

/* The field expanded in place. It is collapsed rather than absent so the form
   stays where it is in the bar and in the tab order; the logo and the theme
   toggle stand down to give it the row, and the dismiss stays put so the
   control that opened the field is the control that closes it.

   Scoped to the mobile range because .mmoc-mobile-header is display: none above
   it, but stated anyway: the inline field must never appear beside the
   titlebar's own search on a desktop-width window. */
@media (max-width: 899px) {
	/* Prefixed with the header because the base .mmoc-search { display: flex }
	   sits further down the file: at equal specificity that one would win and
	   the field would start out expanded, pushing the logo and controls out of
	   the bar. */
	.mmoc-mobile-header .mmoc-search--inline {
		display: none;
	}

	.mmoc-mobile-header.is-searching .mmoc-search--inline {
		display: flex;
		/* Takes whatever the row has left rather than the rail width the base
		   rule gives every other copy of this field. */
		flex: 1 1 auto;
		min-width: 0;
		margin-left: 0;
	}

	.mmoc-mobile-header.is-searching .mmoc-search--inline input {
		width: 100%;
		/* The parent stylesheet sets every input to 11px, which is fine for a
		   corner affordance and far too small for the bar that has just taken
		   over the header. */
		font-size: 15px;
		/* Match the 36px dismiss beside it exactly: the base rule's vertical
		   padding would otherwise carry the field 3px past the control and the
		   pair would sit visibly uneven. */
		height: 36px;
		min-height: 0;
		padding-top: 0;
		padding-bottom: 0;
		border-radius: 10px;
	}

	.mmoc-mobile-header.is-searching .mmoc-mobile-header__logo,
	.mmoc-mobile-header.is-searching .mmoc-theme-toggle--mobile {
		display: none;
	}
}

@media (min-width: 900px) {
	.mmoc-mobile-header .mmoc-search--inline {
		display: none;
	}
}

.mmoc-mobile-header__search:focus-visible {
	outline: 2px solid var(--acc);
	outline-offset: 2px;
}

/* Shell column holding main + the site footer. min-width: 0 so a wide table or
   code block inside cannot push the grid track past its share and squeeze the
   sidebar. */
.mmoc-content {
	min-width: 0;
	display: flex;
	flex-direction: column;
}

/* Puts the footer at the bottom of the column rather than directly under short
   content, on templates that do not fill the viewport. Desktop only: the
   sidebar is already 100vh there so the page cannot get shorter than this, while
   on mobile the leaderboard and header sit above the shell and 100vh here would
   add a screen of scroll to every short page. */
@media (min-width: 900px) {
	.mmoc-content {
		min-height: 100vh;
	}
}

.mmoc-region {
	min-width: 0;
	flex: 1 0 auto;
}

.mmoc-footer {
	text-align: center;
	padding: var(--space-3) var(--space-2);
	color: var(--mut);
	font-size: 13px;
}

@media (max-width: 899px) {
	/* Room for the fixed bottom nav plus the anchor ad stacked on top of it. */
	.mmoc-footer {
		padding-bottom: calc(var(--bottom-nav-h) + 120px);
	}
}

.mmoc-anchor-ad {
	display: none;
	position: fixed;
	bottom: var(--bottom-nav-h);
	left: 0;
	right: 0;
	z-index: 90;
}

.mmoc-anchor-ad.is-visible {
	display: flex !important;
	align-items: center;
}

@media (min-width: 900px) {
	.mmoc-anchor-ad.is-visible,
	.mmoc-anchor-ad {
		display: none !important;
	}
}

.mmoc-anchor-ad .mmoc-ad {
	flex: 1;
	border-radius: 0;
}

.mmoc-anchor-ad__dismiss {
	position: absolute;
	right: 8px;
	top: 50%;
	transform: translateY(-50%);
	width: 28px;
	height: 28px;
	border-radius: 999px;
	border: none;
	background: var(--card);
	color: var(--ink);
	cursor: pointer;
	transition: background-color .18s ease;
}

/* Already at --ink, so the fill is what is left to move. The transform above is
   the button's centring, not a state — hence background-color alone in the
   transition, or it would slide out of position on hover. */
.mmoc-anchor-ad__dismiss:hover,
.mmoc-anchor-ad__dismiss:focus-visible {
	background: var(--soft);
}

.mmoc-anchor-ad__dismiss:focus-visible {
	outline: 2px solid var(--acc);
	outline-offset: 2px;
}

.mmoc-bottom-nav {
	display: none;
}

@media (max-width: 899px) {
	.mmoc-bottom-nav {
		display: flex;
		position: fixed;
		bottom: 0;
		left: 0;
		right: 0;
		height: var(--bottom-nav-h);
		/* The 22px icon and its 11px label stack to 46px; at the old 54px that
		   left about 4px above and below, so both read as touching the bar's
		   edges. An 8px step each side gives the stack room inside the 64px
		   bar. box-sizing is border-box here, so the height already covers
		   this padding and the top border. */
		padding-top: var(--space-1);
		padding-bottom: calc(var(--space-1) + env(safe-area-inset-bottom, 0px));
		background: var(--card);
		border-top: 1px solid var(--bd);
		z-index: 100;
	}
}

.mmoc-bottom-nav__item {
	flex: 1;
	min-height: 44px;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--space-half);
	color: var(--mut);
	font-size: 11px;
	font-weight: 700;
	background: none;
	border: none;
	font-family: var(--font-ui);
	cursor: pointer;
}

/* The Search tab used to be a <button> among four <a>s, and looked it: the
   parent stylesheet's `.mmoc-body a { color: inherit }` outranks a single class
   here, so the links picked up --ink from the bar while only the button honoured
   the --mut above — the button was right and the links were the bug. Prefixing
   with .mmoc-body puts every tab, link or button, on the same scale. Size,
   weight and spacing were already shared and are unchanged. */
.mmoc-body .mmoc-bottom-nav__item {
	color: var(--mut);
}

.mmoc-body .mmoc-bottom-nav__item.is-active {
	color: var(--acc);
}

/* Same treatment on the pointer/keyboard states, which the parent theme's own
   a:hover would otherwise take over for the links only. */
.mmoc-body .mmoc-bottom-nav__item:hover,
.mmoc-body .mmoc-bottom-nav__item:focus-visible,
/* The More tab while its sheet is open. --ink rather than the accent, so it
   reads as pressed without competing with whichever tab is actually current. */
.mmoc-body .mmoc-bottom-nav__item[aria-expanded="true"] {
	color: var(--ink);
}

.mmoc-body .mmoc-bottom-nav__item.is-active:hover,
.mmoc-body .mmoc-bottom-nav__item.is-active:focus-visible {
	color: var(--acc);
}

.mmoc-body .mmoc-bottom-nav__item:focus-visible {
	outline: 2px solid var(--acc);
	outline-offset: -2px;
	border-radius: 8px;
}

.mmoc-bottom-nav__icon svg {
	width: 22px;
	height: 22px;
}

/* Bottom sheet. The More nav is the only one left — search now expands in
   place in the header, next to the control that opens it — but the chrome stays
   factored out under .mmoc-sheet rather than folded into .mmoc-more-sheet, so a
   second sheet does not have to reinvent it.

   It rises from the bottom edge and stops on top of the nav, so it appears
   where it was summoned from.

   display stays none outside the mobile range: the sheet has no trigger there
   (the bottom nav is hidden), and leaving it laid out would let a
   desktop-width window paint it over the footer. */
.mmoc-sheet {
	display: none;
}

@media (max-width: 899px) {
	.mmoc-sheet {
		display: block;
		position: fixed;
		left: 0;
		right: 0;
		/* Sits on the nav rather than over it, so the reader keeps the tabs and
		   can see which one is open. */
		bottom: var(--bottom-nav-h);
		/* Above the anchor ad (90), below the nav (100). */
		z-index: 95;
		background: var(--card);
		border-top: 1px solid var(--bd);
		/* Only the leading corners round — the trailing edge meets the nav. */
		border-radius: 16px 16px 0 0;
		box-shadow: var(--shadow-up);
		padding: var(--space-1) var(--space-2) var(--space-2);
		/* Parked one sheet-height down, which for a sheet anchored above the nav
		   means fully behind the nav and off-screen. Kept in flow and hidden
		   with visibility instead of display so the slide can animate; the
		   delayed visibility lets it play on the way out too. */
		transform: translateY(100%);
		visibility: hidden;
		transition: transform .24s ease, visibility 0s linear .24s;
	}

	.mmoc-sheet.is-open {
		transform: translateY(0);
		visibility: visible;
		transition: transform .24s ease, visibility 0s;
	}

	.mmoc-sheet__head {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: var(--space-2);
		margin-bottom: var(--space-2);
	}

	.mmoc-sheet__title {
		font-size: 17px;
		font-weight: 700;
		line-height: var(--lh-heading);
		margin: 0;
	}

	/* 36px, the same box as the header controls that open these sheets. */
	.mmoc-sheet__close {
		display: flex;
		align-items: center;
		justify-content: center;
		flex: 0 0 auto;
		width: 36px;
		height: 36px;
		padding: 0;
		border: 0;
		border-radius: 50%;
		background: var(--soft);
		color: var(--mut);
		cursor: pointer;
	}

	.mmoc-sheet__close svg {
		width: 18px;
		height: 18px;
	}

	.mmoc-sheet__close:hover {
		color: var(--ink);
	}

	.mmoc-sheet__close:focus-visible {
		outline: 2px solid var(--acc);
		outline-offset: 2px;
	}

	/* Grab-handle: reads as a sheet, and marks the top edge as the thing that
	   moved rather than a panel that blinked into place. Decorative. */
	.mmoc-sheet::before {
		content: '';
		display: block;
		width: 36px;
		height: 4px;
		margin: 0 auto var(--space-2);
		border-radius: 999px;
		background: var(--bd);
	}

	/* More nav: the nav items the five-slot bar cannot show, as full-width rows
	   so the icon column lines up with the labels beside it. */
	.mmoc-more-sheet__list {
		display: flex;
		flex-direction: column;
	}

	.mmoc-more-sheet__item {
		display: flex;
		align-items: center;
		gap: var(--space-2);
		padding: var(--space-2) var(--space-half);
		font-size: 16px;
		font-weight: 600;
		line-height: var(--lh-snug);
	}

	.mmoc-more-sheet__item + .mmoc-more-sheet__item {
		border-top: 1px solid var(--bd);
	}

	.mmoc-more-sheet__item svg {
		width: 20px;
		height: 20px;
		flex: 0 0 auto;
		color: var(--mut);
	}

	/* The sheet is phone-only, so this is for the tablet-with-a-pointer case
	   rather than the common one. Inset by the row's own padding so the fill
	   lines up with the rows above and below it. */
	.mmoc-more-sheet__item:hover {
		background: var(--soft);
		border-radius: 8px;
	}

	.mmoc-more-sheet__item:focus-visible {
		outline: 2px solid var(--acc);
		outline-offset: -2px;
		border-radius: 8px;
	}
}

/* .is-open has to be named too: it carries its own transition at two classes,
   which outranks a lone .mmoc-sheet here however late it sits, so without this
   the guard only ever suppressed the slide on the way out. */
@media (prefers-reduced-motion: reduce) {
	.mmoc-sheet,
	.mmoc-sheet.is-open {
		transition: none;
	}
}

.mmoc-titlebar {
	grid-column: 1 / -1;
	position: sticky;
	top: 0;
	z-index: 45;
	/* Share the content region's track so the bar lines up with the cards
	   below it instead of stretching the full viewport on wide screens. */
	width: 100%;
	max-width: 1280px;
	margin: 0 auto;
	padding: var(--space-3) var(--space-4) var(--space-2);
	background: var(--bg);
	border-bottom: 1px solid var(--bd);
	display: flex;
	/* Without this the pills stretch to the h1's height instead of keeping
	   their own 36px pill height. */
	align-items: center;
	flex-wrap: wrap;
	gap: var(--space-2);
	row-gap: var(--space-2);
}

@media (max-width: 899px) {
	.mmoc-titlebar {
		padding: var(--space-2);
	}

	/* On this layout the wordmark sits directly above the bar, so "Home" says
	   nothing the reader cannot already see and costs the section nav a row.
	   Hidden the .screen-reader-text way rather than with display: none, so the
	   page keeps its h1 for assistive tech and the document outline. */
	.mmoc-titlebar--home .mmoc-titlebar__main {
		position: absolute;
		width: 1px;
		height: 1px;
		padding: 0;
		margin: -1px;
		overflow: hidden;
		clip: rect(0, 0, 0, 0);
		white-space: nowrap;
		border: 0;
	}

	/* The mobile header is sticky at top: 0 with a higher z-index, so a titlebar
	   also stuck at 0 slid underneath it and vanished. Parking it at the header's
	   height keeps the section nav on screen, directly below the bar. */
	.mmoc-titlebar {
		top: var(--mobile-header-h);
	}

	/* The mobile header's search control opens the sheet, so the bar's own field
	   would be a second way to do the same thing in the space the section nav
	   needs. The search page's own full-width field is untouched: it lives in
	   the content column, not in here. */
	.mmoc-titlebar .mmoc-search {
		display: none;
	}

	/* The titlebar's own share of making its pill row swipeable: flex-basis 100%
	   claims the bar's full width, and min-width: 0 lets the row shrink below its
	   contents — a nowrap flex row's min-content is the sum of its pills, so
	   without this it refuses to shrink and overflows the bar instead of
	   scrolling inside it. The swiping itself is .mmoc-pills--slide. */
	.mmoc-titlebar .mmoc-pills {
		flex: 1 1 100%;
		min-width: 0;
	}

}

/* Article header: the bar carries breadcrumb + title + byline, so it can't
   stick (it would pin most of the viewport) and needs no rule under it — the
   hero starts the content column immediately below.

   Its own grid replaces the base bar's wrapping flex row: the info column and
   the search sit side by side on one row and cannot wrap apart. The columns
   mirror .mmoc-page — same minmax(0, 1fr) + var(--rail-w) tracks, same
   var(--space-3) gap — and the two share a max-width and horizontal padding, so
   the info block lines up with the hero below it and the search lines up with
   the rail beside it. */
.mmoc-titlebar--article {
	position: static;
	border-bottom: 0;
	padding-bottom: 0;
	display: grid;
	gap: var(--space-3);
	/* Centred against the info column, which is a three-part stack whose height
	   is whatever the headline wraps to. The consequence, accepted rather than
	   overlooked: the field sits at a different height on every article —
	   roughly level with the title on a one-line headline, lower on two. This
	   was `start` for exactly that reason and was changed on request. */
	align-items: center;
	/* One column below the shell breakpoint only — the two desktop blocks further
	   down add the second track. Here the search takes the first row rather than
	   landing between the byline and the hero, which would split the header in
	   two; on a phone there is no width to put it beside anything. */
	grid-template-columns: minmax(0, 1fr);
}

.mmoc-titlebar--article .mmoc-titlebar__main {
	min-width: 0;
}

.mmoc-titlebar--article .mmoc-breadcrumb {
	margin-bottom: var(--space-half);
}

/* The grid track sets the width now, so the field just fills its cell instead
   of carrying the rail width itself and being pushed over by an auto margin. */
.mmoc-titlebar--article .mmoc-search {
	margin-left: 0;
	width: 100%;
	order: -1;
}

.mmoc-titlebar--article .mmoc-search input {
	width: 100%;
}

/* Sticky from the shell breakpoint up, so the headline, breadcrumb and search
   stay reachable through a long article. Deliberately not sticky below it: the
   bar is 158px on a two-line headline and more on three, which is a fifth of a
   phone's viewport spent on chrome, and the mobile layout already has the
   bottom nav for navigation.

   The three declarations undone here are the ones that made a static bar read
   as part of the page rather than a rule above it — a bar that scrolls over
   content needs its own bottom edge and an opaque background (inherited from
   .mmoc-titlebar) or the text runs underneath it. */
@media (min-width: 900px) {
	.mmoc-titlebar--article {
		position: sticky;
		top: 0;
		border-bottom: 1px solid var(--bd);
		padding-bottom: var(--space-2);
	}
}

/* Between the shell breakpoint and the rail's, the bar is still two columns —
   just with a search track of its own rather than the rail's width. Reserving
   the full 312px here would leave the headline about 330px and wrap it to five
   lines in a bar that now stays on screen.

   Single column with the search ordered first is what this band used to do, and
   it put the field on its own row above the breadcrumb — reading as the top of
   the page rather than as part of the header row, which is the "search is stuck
   at the top" this replaces. There is no vertical centring available to a
   full-width row: align-items only has an effect once something sits beside it. */
@media (min-width: 900px) and (max-width: 1119px) {
	.mmoc-titlebar--article {
		/* Proportional rather than fixed, because this band spans a 568px content
		   column at 900px and a 787px one at 1119px. A flat 240px track took 42%
		   of the narrow end and wrapped the headline to five lines; the same 240
		   is only 30% at the wide end. The clamp keeps the field usable at the
		   bottom and stops it growing past the rail width it becomes at 1120. */
		grid-template-columns: minmax(0, 1fr) clamp(150px, 28%, 240px);
	}

	.mmoc-titlebar--article .mmoc-search {
		order: 0;
	}
}

/* At the rail's own breakpoint the search track stops being a proportion and
   becomes the rail's width exactly, so the info column equals the article body
   below it and the field equals the aside beside it — the header's two columns
   line up with the page's two columns rather than merely resembling them. */
@media (min-width: 1120px) {
	.mmoc-titlebar--article {
		grid-template-columns: minmax(0, 1fr) var(--rail-w);
	}

	.mmoc-titlebar--article .mmoc-search {
		order: 0;
	}
}

/* Section titlebars ("Home", "Redeem Codes") take a compact heading. The
   article variant is excluded: its own .mmoc-article__title sets 36px (25px
   under 900px), and the extra element selector here scored higher, silently
   pinning article headlines to 26px — smaller than the same story's teaser on
   the home page, and leaving that component's own sizes dead. */
.mmoc-titlebar:not(.mmoc-titlebar--article) h1 {
	font-size: 26px;
}

.mmoc-pills {
	display: flex;
	align-items: center;
	gap: var(--space-1);
	flex-wrap: wrap;
	overflow-x: auto;
}

/* One swipeable row on phones rather than wrapping into two. Wrapping costs a
   whole extra row of height above content that has not started yet — on the
   search page it pushed the results down the screen. Shared by the home section
   nav and the search filters so the two behave alike.

   The scrollbar is hidden because the partly-visible last pill is the
   affordance. Desktop keeps the wrapping row, where there is width for it. */
@media (max-width: 899px) {
	.mmoc-pills--slide {
		flex-wrap: nowrap;
		overflow-x: auto;
		-webkit-overflow-scrolling: touch;
		scrollbar-width: none;
		/* Keeps a pill scrolled into view clear of the row's edge. */
		scroll-padding-inline: var(--space-1);
	}

	.mmoc-pills--slide::-webkit-scrollbar {
		display: none;
	}
}

.mmoc-pill {
	white-space: nowrap;
	padding: var(--space-1) var(--space-2);
	border-radius: 999px;
	background: var(--card);
	border: 0;
	font-size: 14px;
	font-weight: 600;
	line-height: var(--lh-flat);
	color: var(--ink);
	transition: background-color .18s ease, color .18s ease;
}

.mmoc-pill.is-active {
	background: var(--acc);
	color: #fff;
}

/* --accSoft rather than --soft: a pill sits on --bg as a --card capsule, and the
   step between those two is small enough in dark mode to miss entirely. Landing
   on the muted accent also previews where the pill is going — the active state
   below is the same hue filled in. */
.mmoc-pill:hover,
.mmoc-pill:focus-visible {
	background: var(--accSoft);
	color: var(--acc);
}

/* Restated for the active pill, which ties with the rule above at (0,2,0) and
   would otherwise lose the filled state to it whenever the pointer crossed the
   pill the reader is already on. */
.mmoc-pill.is-active:hover,
.mmoc-pill.is-active:focus-visible {
	background: var(--acc);
	color: #fff;
}

.mmoc-pill:focus-visible {
	outline: 2px solid var(--acc);
	outline-offset: 2px;
}

.mmoc-search {
	margin-left: auto;
	/* Without this the form's line box is taller than the input, so the titlebar
	   centres the form rather than the field the reader sees. */
	display: flex;
	/* Anchor for the leading icon, which overlays the field rather than sitting
	   beside it so the input keeps owning the form's full width. */
	position: relative;
	align-items: center;
}

.mmoc-search__icon {
	position: absolute;
	left: var(--space-2);
	width: 18px;
	height: 18px;
	color: var(--mut);
	/* Clicks fall through to the field underneath. */
	pointer-events: none;
}

/* The field shares the titlebar row with the section pills, and used to be the
   one thing in it that did not belong: 40px against their 30px, 11px text
   against their 14px, and the only surface in the row carrying a border while
   the pills and cards around it are a --card fill with --shadow. It now takes
   that same treatment, at a control height the theme already uses elsewhere
   (36px: the mobile header buttons, the sheet close). */
.mmoc-search input {
	/* The parent goodlife stylesheet puts a 24px bottom margin on every input,
	   which pushes the field off the titlebar's centre line. */
	margin: 0;
	width: var(--rail-w);
	padding: var(--space-1) var(--space-2);
	/* Clear the icon: gutter + icon + one grid step. */
	padding-left: calc(var(--space-2) + 18px + var(--space-1));
	/* Fixed rather than min-height: the vertical padding above pushes the line
	   box past 36 and the field would sit 3px off the control size it is meant
	   to match. */
	height: 36px;
	padding-top: 0;
	padding-bottom: 0;
	/* Fully rounded, like the pills it sits with. The larger copies override
	   this: they stand alone rather than in that row. */
	border-radius: 999px;
	border: 0;
	background: var(--card);
	box-shadow: var(--shadow);
	color: var(--ink);
	font-size: 14px;
	font-family: var(--font-ui);
}

/* A hairline so the field reads as a control rather than a panel. --card is one
   step off --bg in dark — #232323 on #1a1a1a — and at 36px that difference was
   too slight to find the field against the titlebar. --bd is the token that
   already separates every other surface in the chrome, so the edge matches the
   card and sheet borders rather than introducing a value of its own.

   box-sizing is border-box, so the 36px control height is unchanged and the
   field still lines up with the pills beside it.

   Desktop only, where the field sits inside the titlebar. The mobile header's
   copy is left as it was — it expands to fill a bar that carries its own edge. */
@media (min-width: 900px) {
	.mmoc-search input {
		border: 1px solid var(--bd);
	}
}

/* States, which the field had none of while every other control in the chrome
   gained them. The theme's hover idiom is --mut going to --ink, so that is what
   the icon does; the ring on focus is the same one #scroll_totop and the nav
   use. A text field matches :focus-visible on click as well as on Tab, so this
   covers both. */
.mmoc-search:hover .mmoc-search__icon,
.mmoc-search:focus-within .mmoc-search__icon {
	color: var(--ink);
}

/* .mmoc-body prefix to outrank the parent stylesheet's
   `input[type="search"]:focus { background:#fff; color:#080808 }`, which is a
   near-invisible shift in light mode and turns the field white with near-black
   text in dark mode the moment it is focused. */
.mmoc-body .mmoc-search input:focus,
.mmoc-body .mmoc-search input:focus-visible {
	background: var(--card);
	color: var(--ink);
	outline: 2px solid var(--acc);
	outline-offset: 2px;
}

/* Chrome's stock clear button is a fixed-size bitmap X in its own dark slate,
   which is the one colour in the field that answers to nothing in the theme.
   Replaced with the Lucide X from the nav set, drawn as a mask so it takes a
   token and scales with the field. --mut going to --ink on hover is what every
   other dismiss here does, .mmoc-sheet__close included. */
.mmoc-search input::-webkit-search-cancel-button {
	-webkit-appearance: none;
	appearance: none;
	width: 16px;
	height: 16px;
	margin-left: var(--space-1);
	cursor: pointer;
	background-color: var(--mut);
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 6 6 18'/%3E%3Cpath d='m6 6 12 12'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 6 6 18'/%3E%3Cpath d='m6 6 12 12'/%3E%3C/svg%3E") center / contain no-repeat;
	transition: background-color .18s ease;
}

.mmoc-search input::-webkit-search-cancel-button:hover {
	background-color: var(--ink);
}

/* Scales with the 64px field, which carries a 22px leading icon. */
.mmoc-search--lg input::-webkit-search-cancel-button {
	width: 20px;
	height: 20px;
}

/* The parent goodlife stylesheet also pins every placeholder to 11px uppercase,
   so the hint arrived shouting and in a different size to the text that
   replaces it. Inheriting the field's own size and dropping the case gives one
   line of type the reader can read straight through. */
.mmoc-search input::placeholder {
	font-size: inherit;
	text-transform: none;
	font-weight: 500;
	color: var(--mut);
	/* Firefox dims placeholders a second time on top of the colour. */
	opacity: 1;
}

/* Search page: the field is the page's primary control rather than a corner
   affordance, so it spans the content column at roughly double the height. The
   base rule's margin-left: auto would otherwise shrink it to its content and
   pin it right inside .mmoc-page__main's flex column. */
.mmoc-search--lg {
	margin-left: 0;
	width: 100%;
}

.mmoc-search--lg .mmoc-search__icon {
	left: var(--space-3);
	width: 22px;
	height: 22px;
}

.mmoc-search--lg input {
	width: 100%;
	padding: var(--space-2) var(--space-3);
	padding-left: calc(var(--space-3) + 22px + var(--space-2));
	/* Back to padding-driven sizing: the base pins a 36px control height, which
	   this field is not. */
	height: auto;
	min-height: 64px;
	/* Not the base pill radius: at 64px tall a fully rounded field reads as a
	   giant capsule rather than a text box. */
	border-radius: 16px;
	font-size: 18px;
}


@media (max-width: 899px) {
	.mmoc-search--lg .mmoc-search__icon {
		left: var(--space-2);
		width: 20px;
		height: 20px;
	}

	.mmoc-search--lg input {
		padding: var(--space-1) var(--space-2);
		padding-left: calc(var(--space-2) + 20px + var(--space-1));
		height: auto;
		min-height: 52px;
		font-size: 16px;
	}
}

/* --- Scroll to top ---------------------------------------------------------
   The parent theme ships a 25px square with a 2px radius and a blue hover.
   Restyled here as a circular control matching the theme's other 40px round
   affordances, with the accent purple on hover. Selectors are prefixed with
   .mmoc-body so they outrank the parent theme's plain #scroll_totop. */
.mmoc-body #scroll_totop {
	width: 40px;
	height: 40px;
	line-height: 40px;
	border-radius: 50%;
	background: var(--card);
	border: 1px solid var(--bd);
	color: var(--mut);
	box-shadow: var(--shadow);
	display: flex;
	align-items: center;
	justify-content: center;
	transition: background-color .18s ease, color .18s ease, border-color .18s ease;
}

.mmoc-body #scroll_totop:hover,
.mmoc-body #scroll_totop:focus-visible {
	background: var(--acc);
	border-color: var(--acc);
	color: #fff;
}

.mmoc-body #scroll_totop:focus-visible {
	outline: 2px solid var(--acc);
	outline-offset: 2px;
}

@media (max-width: 899px) {
	/* Clear the bottom nav and the anchor ad that sits on top of it. */
	.mmoc-body #scroll_totop {
		bottom: calc(var(--bottom-nav-h) + 64px);
	}
}

/* --- Cookie bar -------------------------------------------------------------
   The parent theme's own consent bar, restyled rather than replaced: it is
   rendered by goodlife-wp and carries the accept handler, so the markup is not
   ours to change. It shipped as a red full-bleed band with a square outlined
   button in Poppins — the theme's own surface, pill and accent bring it back
   into the palette.

   Everything is prefixed with .mmoc-body to clear the parent's rules, including
   the accent colour it injects through a long inline selector list that names
   .thb-cookie-bar among two dozen others.

   transform is deliberately untouched: the parent parks the bar at
   translateY(100%) and animates it in with an inline style, and an inline style
   beats a stylesheet — anything positional set with transform here would either
   be ignored or fight the reveal. Hence left/right/bottom insets. */
.mmoc-body .thb-cookie-bar {
	/* Above the bottom nav (100) and the anchor ad (90), below the interstitial
	   (200). At the parent's z-index of 40 the bar rendered underneath both on
	   a phone, which is most of what was wrong with it there. */
	z-index: 110;
	/* The parent sets width: 100% with left: 0; the insets below need it auto or
	   the bar overflows by whatever they add up to. */
	width: auto;
	gap: var(--space-2);
	padding: var(--space-2) var(--space-3);
	background: var(--card);
	border-top: 1px solid var(--bd);
	box-shadow: var(--shadow-up);
	color: var(--ink);
	font-family: var(--font-ui);
}

.mmoc-body .thb-cookie-bar p {
	margin: 0;
	font-size: 13px;
	line-height: var(--lh-ui);
	color: var(--mut);
}

.mmoc-body .thb-cookie-bar .thb-cookie-text a {
	color: var(--acc);
	font-weight: 700;
}

.mmoc-body .thb-cookie-bar .thb-cookie-text a:hover,
.mmoc-body .thb-cookie-bar .thb-cookie-text a:focus-visible {
	color: var(--accStrong);
}

/* The theme's own filled pill, in place of the parent's square white outline.
   flex: 0 0 auto so a long consent sentence cannot squeeze the button.

   !important on the radius alone, and only here: the parent ships
   `.btn, .button, input[type="submit"] { border-radius: 0 !important }`, and
   !important is the only thing that beats !important — no amount of specificity
   gets a rounded corner past it. Nothing else on this button is forced, and the
   theme's own controls carry .mmoc-* class names, so the scope is this one
   parent-rendered button. */
.mmoc-body .thb-cookie-bar .button {
	flex: 0 0 auto;
	margin: 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 40px;
	padding: var(--space-1) var(--space-3);
	border: 0;
	border-radius: 999px !important;
	background: var(--acc);
	color: #fff;
	font-family: var(--font-ui);
	font-size: 14px;
	font-weight: 700;
	line-height: var(--lh-flat);
	cursor: pointer;
	transition: background-color .18s ease;
}

.mmoc-body .thb-cookie-bar .button:hover,
.mmoc-body .thb-cookie-bar .button:focus-visible {
	background: var(--accStrong);
	color: #fff;
}

.mmoc-body .thb-cookie-bar .button:focus-visible {
	outline: 2px solid var(--acc);
	outline-offset: 2px;
}

@media (max-width: 899px) {
	/* A floating card sitting clear of the bottom nav rather than a band welded
	   to the bottom edge, and stacked: at 375px the sentence and the button
	   side by side left the text about 180px wide, running to four lines beside
	   a button it was already colliding with.

	   bottom stays 0 and the card is lifted with padding instead, which looks
	   like a pointless detour and is not. The parent hides this bar with
	   `transform: translateY(100%)` and only animates it away with GSAP, so a
	   reader who has already accepted — the cookie is set, the tween never runs —
	   keeps a bar that is invisible but still laid out. Anchored at bottom: 0
	   that hidden copy translates clear of the viewport; anchored 72px up, it
	   translated straight onto the bottom nav and ate every tap. */
	.mmoc-body .thb-cookie-bar {
		left: var(--space-1);
		right: var(--space-1);
		bottom: 0;
		flex-direction: column;
		align-items: stretch;
		padding: var(--space-2);
		padding-bottom: calc(var(--bottom-nav-h) + var(--space-2) + var(--space-1));
		text-align: center;
		/* The card moves to ::before; this box now reaches down behind the nav
		   and must not paint over it. */
		background: transparent;
		border: 0;
		box-shadow: none;
		/* The strip of padding over the nav would still block it while the bar
		   is on screen. None here, auto on the children below, so the nav stays
		   usable with the consent bar up. */
		pointer-events: none;
	}

	/* The visible card, stopping where the nav starts. */
	.mmoc-body .thb-cookie-bar::before {
		content: '';
		position: absolute;
		inset: 0 0 calc(var(--bottom-nav-h) + var(--space-1)) 0;
		background: var(--card);
		border: 1px solid var(--bd);
		border-radius: 16px;
		box-shadow: var(--shadow-up);
	}

	/* position: relative to sit above ::before — a positioned pseudo-element
	   paints over static in-flow siblings, so without this the card covers the
	   sentence and the button it is meant to sit behind. */
	.mmoc-body .thb-cookie-bar > * {
		position: relative;
		pointer-events: auto;
	}

	/* Full width once stacked — a centred pill in a column reads as an
	   afterthought, and this is the only action the bar has. */
	.mmoc-body .thb-cookie-bar .button {
		width: 100%;
	}
}

.mmoc-page {
	max-width: 1280px;
	margin: 0 auto;
	padding: var(--space-3) var(--space-4) var(--space-4);
	display: grid;
	gap: var(--space-3);
	grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 1120px) {
	.mmoc-page {
		grid-template-columns: minmax(0, 1fr) var(--rail-w);
	}
}

@media (max-width: 899px) {
	.mmoc-page {
		padding: var(--space-2) var(--space-2) var(--space-1);
	}
}

.mmoc-page__main {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
}

.mmoc-section {
	scroll-margin-top: 112px;
}

.mmoc-section__heading {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	margin-bottom: var(--space-2);
}

.mmoc-section__heading h2 {
	font-size: 20px;
}

/* .mmoc-body prefix because the parent stylesheet's own `.mmoc-body a { color:
   inherit }` outranks a single class, which is why this rendered near-black
   despite the accent below — the same override that was flattening the bottom
   nav. */
.mmoc-body .mmoc-see-all {
	display: inline-flex;
	align-items: center;
	gap: var(--space-half);
	font-size: 13px;
	font-weight: 700;
	color: var(--acc);
}

/* Lucide chevron-right, the same set as the nav and search icons, drawn as a
   mask so it takes currentColor and needs no markup at the five call sites. */
.mmoc-see-all::after {
	content: '';
	flex: 0 0 auto;
	width: 14px;
	height: 14px;
	background-color: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E") center / contain no-repeat;
	transition: transform .18s ease;
}

/* The link is already the accent, so the state is carried by the chevron moving
   the way it points, plus the deeper accent for readers who will not see it
   move. Prefixed to match the base rule, which needs the prefix to beat the
   parent stylesheet's `.mmoc-body a { color: inherit }`. */
.mmoc-body .mmoc-see-all:hover,
.mmoc-body .mmoc-see-all:focus-visible {
	color: var(--accStrong);
}

.mmoc-see-all:hover::after,
.mmoc-see-all:focus-visible::after {
	transform: translateX(3px);
}

.mmoc-see-all:focus-visible {
	outline: 2px solid var(--acc);
	outline-offset: 3px;
	border-radius: 4px;
}

@media (prefers-reduced-motion: reduce) {
	.mmoc-see-all::after {
		transition: none;
	}

	.mmoc-see-all:hover::after,
	.mmoc-see-all:focus-visible::after {
		transform: none;
	}
}

/* Featured block: one column of stacked cards on phones, a 2x2 grid on desktop
   with the hero holding the whole left column and two cards stacked on the
   right. */
.mmoc-featured {
	display: grid;
	gap: var(--space-2);
	/* Two columns from the smallest screen up: the hero spans both, and the two
	   cards under it pair off in one row rather than stacking into a third and
	   fourth screenful. The desktop block below re-lays the same three items as
	   a 2x2. */
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}

.mmoc-featured .mmoc-featured-card {
	grid-column: 1 / -1;
}

@media (max-width: 899px) {
	/* Paired, each card is half the width it had stacked, so a headline that
	   took two lines now takes four and the card grows taller than the image it
	   sits under. Three lines caps the worst of them without truncating most. */
	.mmoc-featured .mmoc-card__title {
		display: -webkit-box;
		-webkit-box-orient: vertical;
		-webkit-line-clamp: 3;
		overflow: hidden;
	}
}

@media (min-width: 900px) {
	.mmoc-featured {
		grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
		/* A definite height split evenly, rather than rows sized by whatever the
		   side cards happen to need: it keeps the block the same height whatever
		   the headlines do, and gives the rail a number to match. */
		height: var(--featured-h);
		grid-template-rows: 1fr 1fr;
	}

	.mmoc-featured .mmoc-featured-card {
		grid-column: 1;
		grid-row: 1 / span 2;
	}

	/* If the side query comes back empty — a thin site, or every candidate
	   already used above — the hero would hold column 1 and leave the other half
	   of the block blank. Alone, it takes the full width and the block sizes to
	   its own content instead of the 576px the pair would have set.

	   Tested by the absence of side cards rather than with :only-child: the
	   mobile ad placement is a child of this grid at every breakpoint — hidden
	   here, but still counted — so the hero is never an only child. */
	.mmoc-featured:not(:has(.mmoc-card)) .mmoc-featured-card {
		grid-column: 1 / -1;
	}

	.mmoc-featured:not(:has(.mmoc-card)) {
		height: auto;
	}

	/* The side cards now fill a row taller than their own content, so they get
	   the hero's treatment — image absorbs the slack, body stays its own size. */
	.mmoc-featured .mmoc-card {
		display: flex;
		flex-direction: column;
		min-height: 0;
	}

	.mmoc-featured .mmoc-card__media {
		height: auto;
		flex: 1 1 auto;
		min-height: 0;
	}
}

.mmoc-featured-card {
	display: block;
	background: var(--card);
	border-radius: 18px;
	overflow: hidden;
	box-shadow: var(--shadow);
}

/* Spanning two rows makes the hero taller than its own content, so it becomes a
   column with the image taking up the slack — a fixed media height would leave
   the card's background showing under the body instead. */
@media (min-width: 900px) {
	.mmoc-featured .mmoc-featured-card {
		display: flex;
		flex-direction: column;
	}

	.mmoc-featured .mmoc-featured-card__media {
		height: auto;
		flex: 1 1 auto;
		/* Floor for the case where the two side cards are short. */
		min-height: 300px;
	}

	/* 36px was set for a hero spanning the whole content column. At half that
	   width it wraps to five lines and the body claims the height the image
	   should be using, so the type comes down with the measure. */
	.mmoc-featured .mmoc-featured-card__title {
		font-size: 27px;
		line-height: var(--lh-heading);
		/* Clamped for the same reason it is smaller: the row height is fixed by
		   the two cards alongside, so every line the headline takes is a line
		   taken off the image. Three is enough for the longest titles in the
		   corpus at this measure. */
		display: -webkit-box;
		-webkit-box-orient: vertical;
		-webkit-line-clamp: 3;
		overflow: hidden;
	}
}

.mmoc-featured-card__media {
	position: relative;
	height: 330px;
	background: var(--soft);
	overflow: hidden;
}

.mmoc-featured-card__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* On phones the hero is not a hero: it is a full-width card above a pair of
   half-width ones, so it takes .mmoc-card's radius and type sizes rather than
   its own larger set. Their shared media height lives with .mmoc-card__media
   further down, which is where the value it overrides is declared. */
@media (max-width: 899px) {
	/* The featured pair is half width, so a height that suits a full-width card
	   leaves them nearly square. A ratio rather than a number: they then scale
	   with the column instead of needing a value per breakpoint. */
	.mmoc-featured .mmoc-card__media {
		height: auto;
		aspect-ratio: 16 / 9;
	}

	.mmoc-featured-card {
		border-radius: 16px;
	}
}

.mmoc-pill-badge {
	position: absolute;
	top: 14px;
	left: 14px;
	background: rgba(16,17,21,0.82);
	color: #fff;
	font-size: 11px;
	font-weight: 700;
	padding: var(--space-1) var(--space-2);
	border-radius: 999px;
	display: inline-flex;
	align-items: center;
	gap: var(--space-1);
}

.mmoc-pill-badge__dot {
	width: 7px;
	height: 7px;
	border-radius: 999px;
	background: var(--amber);
}

.mmoc-featured-card__body {
	padding: var(--space-3);
}

@media (max-width: 899px) {
	.mmoc-featured-card__body {
		padding: var(--space-2);
	}
}

.mmoc-featured-card__title {
	font-size: 36px;
	line-height: var(--lh-display);
	margin: var(--space-1) 0;
}

/* The eyebrow and byline are the card's own 11px and 12px stepped up one notch,
   so the hero reads as the same component at a larger size rather than as a
   different one. */
.mmoc-featured-card__body .mmoc-eyebrow {
	font-size: 12px;
}

.mmoc-featured-card__body .mmoc-meta {
	font-size: 13px;
}

@media (max-width: 899px) {
	/* .mmoc-card__title's size and leading — see the media note above: on phones
	   this is a card among cards, not a hero. */
	.mmoc-featured-card__title {
		font-size: 15px;
		line-height: var(--lh-snug);
	}

	.mmoc-featured-card__body .mmoc-eyebrow {
		font-size: 11px;
	}

	.mmoc-featured-card__body .mmoc-meta {
		font-size: 12px;
	}
}

.mmoc-grid {
	display: grid;
	gap: var(--space-3);
}

.mmoc-grid--2up {
	grid-template-columns: 1fr;
}

@media (min-width: 560px) {
	.mmoc-grid--2up {
		grid-template-columns: 1fr 1fr;
	}
}

.mmoc-card {
	display: block;
	background: var(--card);
	border-radius: 16px;
	overflow: hidden;
	box-shadow: var(--shadow);
}

.mmoc-card__media {
	height: 158px;
	background: var(--soft);
	overflow: hidden;
}

/* Shorter on phones, and the same number for the featured hero, which is a
   full-width card among cards there. One declaration for both so they cannot
   drift apart, and placed after both base heights: media queries add no
   specificity, so a copy of this sitting earlier in the file would simply lose
   to the 158px above. At a 343px measure 140 is still a 2.45:1 band, and it buys
   back most of a thumb-scroll on the way to the stories below. */
@media (max-width: 899px) {
	.mmoc-card__media,
	.mmoc-featured-card__media {
		height: 140px;
	}
}

.mmoc-card__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.mmoc-card__body {
	padding: var(--space-2);
}

.mmoc-card__title {
	font-size: 15px;
	line-height: var(--lh-snug);
	margin: var(--space-1) 0;
}

.mmoc-list {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
}

.mmoc-list-row {
	display: flex;
	gap: var(--space-2);
	background: var(--card);
	border-radius: 14px;
	padding: var(--space-2);
	box-shadow: var(--shadow);
}

.mmoc-list-row__thumb {
	width: 100px;
	height: 76px;
	flex-shrink: 0;
	border-radius: 10px;
	overflow: hidden;
	background: var(--soft);
}

.mmoc-list-row__thumb img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.mmoc-list-row__body {
	flex: 1;
	min-width: 0;
}

.mmoc-list-row__title {
	font-size: 15px;
	font-weight: 700;
	line-height: var(--lh-snug);
	margin: var(--space-half) 0;
}

/* On phones the body column is roughly 200px wide, so a long headline runs to
   four or five lines and the row grows to twice the height of its own thumbnail.
   Two lines keeps every row the same height and the list scannable; the full
   title is one tap away. */
@media (max-width: 899px) {
	.mmoc-list-row__title {
		display: -webkit-box;
		-webkit-box-orient: vertical;
		-webkit-line-clamp: 2;
		overflow: hidden;
	}
}

/* --- Card pointer and keyboard states --- */
/* Every card on the site is a bare <a> around an image and a headline, with no
   state of its own — nothing moved on hover, so a whole grid read as static
   artwork rather than as eight links. The four shapes share one block so they
   cannot drift apart: the 2-up card, the featured hero, the list row and the
   article's prev/next pair. .mmoc-adjacent__card is declared further down with
   the article styles; only new properties are set here, so nothing depends on
   which of the two comes first.

   Elevation carries the state rather than a background change: in dark mode
   --card (#232323) is nine values off --bg (#1a1a1a), so a tint big enough to
   register there would be a different surface colour, while a shadow reads in
   both themes. */
.mmoc-card,
.mmoc-featured-card,
.mmoc-list-row,
.mmoc-adjacent__card {
	/* Named properties rather than leaning on the parent stylesheet's blanket
	   `a { transition: .25s linear }`, which every card already inherits: that
	   one is `all`, so the focus ring below would fade in instead of appearing,
	   and it reaches no further than the <a> — the images and headlines inside
	   are separate elements and carry their own transitions.

	   ease-out over .24s rather than the .18s ease the controls use: the card
	   moves, and a curve that accelerates into the travel makes 2px read as a
	   jolt. Starting at speed and settling is what makes the same distance feel
	   like a lift. The colour below stays on the shared .18s — it has no
	   distance to cover. */
	transition: transform .24s ease-out, box-shadow .24s ease-out;
}

/* :hover is gated on a real pointer. On a touchscreen it sticks after the tap
   until something else is tapped, so a reader coming back from an article finds
   one card still raised. :focus-visible is deliberately outside the gate — it is
   the keyboard's version of the same state and has to work on every device. */
@media (hover: hover) {
	.mmoc-card:hover,
	.mmoc-featured-card:hover,
	.mmoc-list-row:hover,
	.mmoc-adjacent__card:hover {
		transform: translateY(-2px);
		box-shadow: var(--shadow-hover);
	}

	/* The headline is the thing being clicked, so it takes the accent the
	   eyebrow above it already carries — the card resolves to one colour rather
	   than picking up a second. Only the title is named: the byline stays --mut,
	   and the parent stylesheet's `a:hover { color: #649fd6 }` reaches neither,
	   losing to the child's own `.mmoc-body a { color: inherit }` on source
	   order at equal specificity. */
	.mmoc-card:hover .mmoc-card__title,
	.mmoc-featured-card:hover .mmoc-featured-card__title,
	.mmoc-list-row:hover .mmoc-list-row__title,
	.mmoc-adjacent__card:hover .mmoc-adjacent__title {
		color: var(--acc);
	}

	/* A slow push into the frame the media box already clips. 1.03 rather than
	   anything larger: these are 640x360 crops shown at up to 158px tall, and
	   past a few percent the softness shows. */
	.mmoc-card:hover .mmoc-card__media img,
	.mmoc-featured-card:hover .mmoc-featured-card__media img,
	.mmoc-list-row:hover .mmoc-list-row__thumb img {
		transform: scale(1.03);
	}
}

/* Slower than the card and on the same curve, so the two read as one movement
   with the image trailing it rather than as two animations of different
   character starting together. */
.mmoc-card__media img,
.mmoc-featured-card__media img,
.mmoc-list-row__thumb img {
	transition: transform .32s ease-out;
}

/* The titles carry their own transition because the card's is a named list that
   does not include colour, and these are separate elements from the card in any
   case. */
.mmoc-card__title,
.mmoc-featured-card__title,
.mmoc-list-row__title,
.mmoc-adjacent__title {
	transition: color .18s ease;
}

/* Colour and title treatment repeated for the keyboard, plus the accent ring the
   nav and #scroll_totop use. The cards clip their contents, but an outline is
   drawn outside the border box and is not clipped by the element's own
   overflow, so the whole ring shows. */
.mmoc-card:focus-visible,
.mmoc-featured-card:focus-visible,
.mmoc-list-row:focus-visible,
.mmoc-adjacent__card:focus-visible {
	outline: 2px solid var(--acc);
	outline-offset: 2px;
	box-shadow: var(--shadow-hover);
}

.mmoc-card:focus-visible .mmoc-card__title,
.mmoc-featured-card:focus-visible .mmoc-featured-card__title,
.mmoc-list-row:focus-visible .mmoc-list-row__title,
.mmoc-adjacent__card:focus-visible .mmoc-adjacent__title {
	color: var(--acc);
}

/* The lift and the zoom are motion; the shadow, ring and accent are not, so they
   stay. Transitions go too — otherwise the colour still animates and the
   preference is only half honoured. */
@media (prefers-reduced-motion: reduce) {
	.mmoc-card,
	.mmoc-featured-card,
	.mmoc-list-row,
	.mmoc-adjacent__card,
	.mmoc-card__media img,
	.mmoc-featured-card__media img,
	.mmoc-list-row__thumb img,
	.mmoc-card__title,
	.mmoc-featured-card__title,
	.mmoc-list-row__title,
	.mmoc-adjacent__title {
		transition: none;
	}

	.mmoc-card:hover,
	.mmoc-featured-card:hover,
	.mmoc-list-row:hover,
	.mmoc-adjacent__card:hover {
		transform: none;
	}

	.mmoc-card:hover .mmoc-card__media img,
	.mmoc-featured-card:hover .mmoc-featured-card__media img,
	.mmoc-list-row:hover .mmoc-list-row__thumb img {
		transform: none;
	}
}

/* --- Article interstitial --- */
/* [hidden] needs stating explicitly: the display: flex below would otherwise
   override the attribute's own display: none and the overlay would sit over the
   page permanently. The attribute selector outranks the class, so this wins
   wherever it sits. */
.mmoc-interstitial[hidden] {
	display: none;
}

.mmoc-interstitial {
	position: fixed;
	inset: 0;
	z-index: 200;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: var(--space-3);
	/* Dark either way: this sits over the page, not in it, so it does not follow
	   the palette. */
	background: rgba(10,11,14,0.72);
}

/* The page behind is blurred as well as dimmed, so the panel reads as the only
   thing in focus and the article headline the reader was aiming at stops
   competing with it for attention. Kept behind @supports and paired with a
   lighter scrim: the 0.72 above is what has to do the whole job unaided where
   backdrop-filter is unavailable, and it is heavier than the blurred version
   needs. -webkit- first — Safari shipped the prefixed property and still
   matches only that one in older versions. */
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
	.mmoc-interstitial {
		background: rgba(10,11,14,0.55);
		-webkit-backdrop-filter: blur(10px) saturate(0.85);
		backdrop-filter: blur(10px) saturate(0.85);
	}
}

.mmoc-interstitial__panel {
	width: 100%;
	max-width: 360px;
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
	padding: var(--space-2);
	border-radius: 18px;
	background: var(--card);
	box-shadow: 0 12px 40px rgba(0,0,0,0.45);
}

.mmoc-interstitial__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-2);
}

/* Labelled as advertising rather than left to look like content — the panel
   interrupts a click the reader made for a different reason. */
.mmoc-interstitial__label {
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--mut);
}

/* The same 36px round dismiss the sheets use. */
.mmoc-interstitial__close {
	display: flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	width: 36px;
	height: 36px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: var(--soft);
	color: var(--mut);
	cursor: pointer;
}

.mmoc-interstitial__close svg {
	display: block;
	width: 18px;
	height: 18px;
}

.mmoc-interstitial__close:hover {
	color: var(--ink);
}

.mmoc-interstitial__close:focus-visible,
.mmoc-interstitial__continue:focus-visible {
	outline: 2px solid var(--acc);
	outline-offset: 2px;
}

/* .mmoc-body prefix, or the parent stylesheet's `.mmoc-body a { color: inherit }`
   outranks this and the label inherits --ink instead: near-white on the dark
   default, so it looks right, and near-black on the purple button in light mode,
   where it does not. */
.mmoc-body .mmoc-interstitial__continue {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-1);
	min-height: 48px;
	border-radius: 999px;
	background: var(--acc);
	color: #fff;
	font-size: 15px;
	font-weight: 700;
	/* The way out of the overlay, on a panel whose whole purpose is to hold the
	   reader's attention elsewhere — so it is given elevation the rest of the
	   panel does not have, in the accent's own colour, rather than being left
	   as a flat fill the eye can pass over. */
	box-shadow: 0 6px 20px var(--accGlow);
	transition: background-color .18s ease, box-shadow .18s ease, transform .18s ease;
}

.mmoc-interstitial__continue svg {
	display: block;
	width: 18px;
	height: 18px;
	transition: transform .18s ease;
}

/* Prefixed to stay above the base rule it overrides, which is prefixed itself
   for the colour reason noted above. */
.mmoc-body .mmoc-interstitial__continue:hover,
.mmoc-body .mmoc-interstitial__continue:focus-visible {
	background: var(--accStrong);
	box-shadow: 0 8px 26px var(--accGlow);
	transform: translateY(-1px);
}

.mmoc-interstitial__continue:hover svg,
.mmoc-interstitial__continue:focus-visible svg {
	transform: translateX(2px);
}

/* The one place the dark theme borrows the light palette's deeper purple. The
   button is the only white-on-accent fill in the theme that a reader has to find
   under time pressure, and --acc is too light to carry white text: #a385ff gives
   the label 2.85:1, under the 4.5:1 AA floor, while #7c3aed gives 5.7:1 on the
   same white.

   Only the fill changes — the halo stays --accGlow, i.e. the bright violet. A
   glow in the deeper purple barely registers against a #232323 panel, so the
   fill carries the label's legibility and the glow carries the button's.

   The hover goes darker here, against the rule stated at --accStrong for every
   other filled-accent control in dark mode. Lighter is what that rule wants, and
   lighter is exactly what costs the label its contrast again — so the lift is
   left to the transform and the widened glow, which is how the cards carry
   theirs on dark surfaces anyway. */
:root:not([data-theme="light"]) .mmoc-body .mmoc-interstitial__continue {
	background: #7c3aed;
	/* No halo in dark mode. The glow was there to lift the button off the panel,
	   but the deeper purple already separates from #232323 on its own, and a
	   violet bloom around a violet fill on a near-black panel reads as a blur
	   rather than as elevation. The light theme keeps its glow. */
	box-shadow: none;
}

:root:not([data-theme="light"]) .mmoc-body .mmoc-interstitial__continue:hover,
:root:not([data-theme="light"]) .mmoc-body .mmoc-interstitial__continue:focus-visible {
	background: #6d28d9;
	box-shadow: none;
}

@media (prefers-reduced-motion: reduce) {
	.mmoc-body .mmoc-interstitial__continue,
	.mmoc-interstitial__continue svg {
		transition: none;
	}

	.mmoc-body .mmoc-interstitial__continue:hover,
	.mmoc-body .mmoc-interstitial__continue:focus-visible {
		transform: none;
	}
}

/* The page behind must not scroll under the overlay. */
.mmoc-body.is-interstitial-open {
	overflow: hidden;
}

/* --- Right rail --- */
.mmoc-rail {
	display: none;
}

@media (min-width: 1120px) {
	.mmoc-rail {
		display: flex;
		flex-direction: column;
		gap: var(--space-3);
		min-width: 0;
	}
}

/* --- Compact language switcher --- */
/* Nothing renders this at the moment: the sidebar dropped it, and so has the
   mobile search sheet. The styles and mmoculture_modern_render_language_links()
   are kept for wherever it lands next. */

.mmoc-lang-select {
	width: 100%;
	font-family: var(--font-ui);
	font-size: 12px;
	font-weight: 600;
	color: var(--mut);
	background: var(--soft);
	border: 1px solid var(--bd);
	border-radius: 10px;
	padding: var(--space-1) var(--space-2);
	cursor: pointer;
	transition: color .18s ease, border-color .18s ease;
}

/* A select cannot take a background hover without the popup inheriting it in
   some engines, so the state is on the text and the border instead. */
.mmoc-lang-select:hover,
.mmoc-lang-select:focus-visible {
	color: var(--ink);
	border-color: var(--mut);
}

.mmoc-lang-select:focus-visible {
	outline: 2px solid var(--acc);
	outline-offset: 2px;
}

.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;
}

/* --- Archive: load more + pagination --- */
.mmoc-load-more {
	display: flex;
	justify-content: center;
	margin-top: var(--space-1);
}

.mmoc-load-more__btn {
	padding: var(--space-2) var(--space-3);
	min-height: 40px;
	border-radius: 999px;
	border: 1px solid var(--ink);
	background: transparent;
	color: var(--ink);
	font-family: var(--font-ui);
	font-size: 14px;
	font-weight: 600;
	line-height: var(--lh-flat);
	cursor: pointer;
	transition: background-color .18s ease, color .18s ease, border-color .18s ease;
}

.mmoc-load-more__btn[disabled] {
	opacity: .55;
	cursor: default;
}

/* Fills with the accent, the same thing #scroll_totop does — an outlined button
   has only its border and its fill to give. :not([disabled]) because the button
   spends the length of the fetch disabled and would otherwise light up under a
   pointer that is waiting on it. */
.mmoc-load-more__btn:hover:not([disabled]),
.mmoc-load-more__btn:focus-visible:not([disabled]) {
	background: var(--acc);
	border-color: var(--acc);
	color: #fff;
}

.mmoc-load-more__btn:focus-visible {
	outline: 2px solid var(--acc);
	outline-offset: 2px;
}

.mmoc-pagination {
	margin-top: var(--space-3);
}

.mmoc-pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 40px;
	min-height: 40px;
	padding: 0 var(--space-1);
	margin-right: var(--space-1);
	border-radius: 10px;
	background: var(--card);
	font-size: 14px;
	font-weight: 600;
	line-height: var(--lh-flat);
	color: var(--ink);
	transition: background-color .18s ease, color .18s ease;
}

.mmoc-pagination .page-numbers.current {
	background: var(--acc);
	color: #fff;
}

/* a.page-numbers, not .page-numbers: WordPress renders the current page and the
   ellipsis as spans, so naming the anchor leaves both out and no rule is needed
   to put .current back. The pills' hover pair, since these are the same shape. */
.mmoc-pagination a.page-numbers:hover,
.mmoc-pagination a.page-numbers:focus-visible {
	background: var(--accSoft);
	color: var(--acc);
}

.mmoc-pagination a.page-numbers:focus-visible {
	outline: 2px solid var(--acc);
	outline-offset: 2px;
}

/* The prev/next links carry a chevron instead of a word. display: block for the
   same reason every other icon here has it — an inline SVG sits on the text
   baseline and would render the chevron a couple of pixels above the centre of
   the 40px pill. */
.mmoc-pagination .page-numbers svg {
	display: block;
	width: 16px;
	height: 16px;
}

.mmoc-empty {
	color: var(--mut);
	font-size: 15px;
	line-height: var(--lh-body);
}

/* --- Single article --- */
.mmoc-progress {
	position: fixed;
	top: 0;
	left: 0;
	height: 3px;
	width: 0;
	background: var(--acc);
	z-index: 200;
}

.mmoc-breadcrumb {
	display: flex;
	align-items: center;
	gap: var(--space-1);
	font-size: 12px;
	font-weight: 600;
	line-height: var(--lh-ui);
	color: var(--mut);
}

.mmoc-breadcrumb a {
	color: var(--mut);
	transition: color .18s ease;
}

/* The theme's --mut to --ink again. (0,2,1) with the pseudo-class, so it clears
   both the child's own `.mmoc-body a { color: inherit }` and the parent
   stylesheet's `.breadcrumb-container a:hover { color: #080808 }`. */
.mmoc-breadcrumb a:hover,
.mmoc-breadcrumb a:focus-visible {
	color: var(--ink);
}

/* The parent stylesheet ships a bare `a { outline: 0 }`, so a link that does not
   name a ring of its own has none at all — the browser default is gone before it
   can draw. Every other control here declares one; the breadcrumb and the body
   copy are the two runs of plain text links, and they need it stated too. */
.mmoc-breadcrumb a:focus-visible {
	outline: 2px solid var(--acc);
	outline-offset: 2px;
	border-radius: 4px;
}

/* Flush with the content column: the breadcrumb and title above it and the ad
   and module surfaces below it all share this edge, so the article body carries
   no card of its own. */
.mmoc-article {
	min-width: 0;
}

.mmoc-article__hero {
	height: 328px;
	margin: 0 0 var(--space-3);
	border-radius: 16px;
	overflow: hidden;
	background: var(--soft);
}

@media (max-width: 899px) {
	.mmoc-article__hero {
		height: 208px;
	}
}

.mmoc-article__hero img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.mmoc-article__title {
	font-size: 36px;
	line-height: var(--lh-display);
	letter-spacing: -0.03em;
	margin-bottom: var(--space-1);
}

@media (max-width: 899px) {
	.mmoc-article__title {
		font-size: 25px;
	}
}

/* The headline keeps its full 36px while the bar sits in flow, and steps down
   only once the bar pins — so a long title costs the reader viewport only while
   it is actually covering the article, not on the way in. theme.js sets
   .is-stuck when the bar's top reaches 0.

   The step changes the bar's height, which shifts the content below it by the
   difference at the moment of pinning. The transition is what keeps that from
   reading as a jolt; without it the shift is instant and looks like a reflow
   bug. Mobile is untouched — the bar is static there and never gains the class
   in a way this rule can see. */
@media (min-width: 900px) {
	.mmoc-titlebar--article .mmoc-article__title {
		transition: font-size 160ms ease-out;
	}

	.mmoc-titlebar--article.is-stuck .mmoc-article__title {
		font-size: 28px;
	}
}

/* The size change itself stays — it is what keeps the pinned bar short. Only the
   animation between the two sizes goes. */
@media (prefers-reduced-motion: reduce) {
	.mmoc-titlebar--article .mmoc-article__title {
		transition: none;
	}
}

.mmoc-byline {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--space-1);
}

.mmoc-avatar {
	flex: 0 0 auto;
	width: 24px;
	height: 24px;
	border-radius: 50%;
	background: var(--accSoft);
	color: var(--acc);
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 11px;
	font-weight: 700;
	line-height: var(--lh-flat);
}

.mmoc-byline__text {
	font-size: 13px;
	line-height: var(--lh-ui);
	color: var(--mut);
}

.mmoc-byline__sep {
	margin: 0 var(--space-half);
}

.mmoc-byline__chips {
	margin-left: auto;
	display: flex;
	gap: var(--space-1);
}

.mmoc-chip {
	display: inline-flex;
	align-items: center;
	padding: var(--space-1) var(--space-2);
	min-height: 32px;
	border-radius: 999px;
	background: var(--soft);
	color: var(--ink);
	font-size: 12px;
	font-weight: 600;
	line-height: var(--lh-flat);
	transition: background-color .18s ease, color .18s ease;
}

/* One rule for both uses: the tag list under the article and the Share/Tweet
   pair beside it are the same chip. The pills' hover, because they are the same
   capsule at a smaller size. */
.mmoc-chip:hover,
.mmoc-chip:focus-visible {
	background: var(--accSoft);
	color: var(--acc);
}

.mmoc-chip:focus-visible {
	outline: 2px solid var(--acc);
	outline-offset: 2px;
}

.mmoc-article__body {
	font-size: 19px;
	line-height: var(--lh-body);
	color: var(--ink);
}

:root:not([data-theme="light"]) .mmoc-article__body table {
    color: #1a1a1a;
}

.mmoc-article__body > * + * {
	margin-top: var(--space-3);
}

.mmoc-article__body h2 {
	font-size: 23px;
	line-height: var(--lh-heading);
	margin-top: var(--space-4);
}

.mmoc-article__body h3 {
	font-size: 19px;
	line-height: var(--lh-heading);
	margin-top: var(--space-3);
}

/* Reading copy steps down on phones: 19px is right for the desktop measure but
   oversized on a ~343px column, where it runs to roughly 40 characters a line.
   The headings come down with it so the scale between them holds rather than the
   h2 closing on the body size. */
@media (max-width: 899px) {
	.mmoc-article__body {
		font-size: 15px;
	}

	.mmoc-article__body h2 {
		font-size: 19px;
	}

	.mmoc-article__body h3 {
		font-size: 16px;
	}
}

/* Legacy editor content marks emphasis with <strong> and <b> interchangeably,
   and the parent theme weights them differently (body strong -> 600, b -> bold).
   Pin reading-copy emphasis to one weight so the two tags look alike. */
.mmoc-article__body :where(strong, b) {
	font-weight: 700;
}

/* Most headings in the corpus are typed as <h2><strong>…</strong></h2>, which
   made them render at 600 or 700 instead of the theme's 800 — reading as a
   lighter, almost different face than a heading with no wrapper. Some also
   carry an editor-injected inline `font-weight: 400`, which drops the heading
   to body weight entirely. Let any wrapper inside a heading inherit the
   heading's own weight.

   !important is the only thing that beats an inline style, so the scope is kept
   deliberately narrow: wrappers inside an article-body heading, nowhere else.
   Only weight is touched, so italics from <em>/<i> survive. */
.mmoc-article__body h1 :where(strong, b, span, em, i),
.mmoc-article__body h2 :where(strong, b, span, em, i),
.mmoc-article__body h3 :where(strong, b, span, em, i),
.mmoc-article__body h4 :where(strong, b, span, em, i) {
	font-weight: inherit !important;
}

.mmoc-article__body img,
.mmoc-article__body iframe {
	max-width: 100%;
	border-radius: 14px;
}

.mmoc-article__body img {
	height: auto;
}

/* height: auto is right for an image and wrong for an iframe: an image has an
   intrinsic aspect ratio to scale by, an iframe has none, so `auto` there
   resolves to the CSS default iframe height of 150px. It collapsed every video
   in an article body — an aspect-ratio gives the frame the shape the image gets
   for free.

   Only oembeds reach the parent theme's .flex-video wrapper (see
   thb_remove_youtube_controls in goodlife-wp/inc/misc.php); a raw <iframe>
   pasted into the post body gets no wrapper, and around 780 published posts
   have one. Both are YouTube or Vimeo in this content, hence 16:9. */
.mmoc-article__body iframe {
	aspect-ratio: 16 / 9;
	height: auto;
}

/* Wrapped ones already have their shape from Foundation's .flex-video, which
   holds the ratio as padding-bottom on the wrapper and pins the frame to fill
   it absolutely — so the frame takes the wrapper's height and its own ratio has
   nothing left to say.

   Not merely a tidy-up: `.flex-video iframe` in the parent's app.css and
   `.mmoc-article__body iframe` here are both one class and one type, and this
   stylesheet loads second, so the rule above wins the tie and would otherwise
   put a 150px strip at the top of a correctly sized 16:9 box. Two classes here
   settles it by specificity rather than by which file happens to load last. */
.mmoc-article__body .flex-video iframe {
	aspect-ratio: auto;
	height: 100%;
}

.mmoc-article__body ul,
.mmoc-article__body ol {
	padding-left: var(--space-3);
}

.mmoc-article__body li + li {
	margin-top: var(--space-1);
}

.mmoc-article__body a {
	color: var(--acc);
	text-decoration: underline;
	transition: color .18s ease;
}

/* Already accented and already underlined, so the deeper accent is what is left
   to give. The article body is not inside the parent theme's `.post-content`
   wrapper, so its `p a:hover { background: #ddeaf6; color: #080808 }` — a pale
   blue highlight that would be unreadable on the dark default — never applies
   here. */
.mmoc-article__body a:hover,
.mmoc-article__body a:focus-visible {
	color: var(--accStrong);
}

/* The other half of the parent's `a { outline: 0 }` — see the breadcrumb. */
.mmoc-article__body a:focus-visible {
	outline: 2px solid var(--acc);
	outline-offset: 2px;
	border-radius: 4px;
}

.mmoc-article__footer {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: var(--space-2);
	margin-top: var(--space-3);
}

.mmoc-tags {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-1);
}

.mmoc-adjacent {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-2);
	margin-top: var(--space-3);
}

@media (min-width: 560px) {
	.mmoc-adjacent {
		grid-template-columns: 1fr 1fr;
	}
}

.mmoc-adjacent__card {
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
	padding: var(--space-2);
	border-radius: 14px;
	background: var(--soft);
}

.mmoc-adjacent__card--next {
	text-align: right;
}

/* Lucide chevrons in place of the &larr;/&rarr; glyphs, matching the caret on
   "See all" and the rest of the icon set — the HTML arrows came from the text
   font and sat heavier and lower than every other mark on the page.

   The card is a column flex container, so this span stretches to its full
   width; the next card pushes its row to the trailing edge to stay with the
   card's right alignment. */
.mmoc-adjacent__dir {
	display: flex;
	align-items: center;
	gap: var(--space-half);
}

.mmoc-adjacent__card--next .mmoc-adjacent__dir {
	justify-content: flex-end;
}

.mmoc-adjacent__dir svg {
	width: 14px;
	height: 14px;
	flex: 0 0 auto;
}

.mmoc-adjacent__title {
	font-size: 14px;
	font-weight: 700;
	line-height: var(--lh-snug);
	color: var(--ink);
}

.mmoc-related {
	margin-top: var(--space-4);
}

.mmoc-comments {
	margin-top: var(--space-4);
	padding-top: var(--space-3);
	border-top: 1px solid var(--bd);
}

.mmoc-comments input:not([type="submit"]),
.mmoc-comments textarea {
	width: 100%;
	max-width: 100%;
	padding: var(--space-1) var(--space-2);
	min-height: 40px;
	border: 1px solid var(--bd);
	border-radius: 10px;
	background: var(--bg);
	color: var(--ink);
	font-family: var(--font-ui);
	font-size: 15px;
	line-height: var(--lh-body);
}

.mmoc-comments .submit {
	padding: var(--space-1) var(--space-3);
	min-height: 40px;
	border: 0;
	border-radius: 999px;
	background: var(--acc);
	color: #fff;
	font-family: var(--font-ui);
	font-size: 14px;
	font-weight: 700;
	cursor: pointer;
	transition: background-color .18s ease;
}

.mmoc-comments .submit:hover,
.mmoc-comments .submit:focus-visible {
	background: var(--accStrong);
}

.mmoc-comments .submit:focus-visible {
	outline: 2px solid var(--acc);
	outline-offset: 2px;
}

/* --- Codes module (redeem-codes posts) --- */
.mmoc-codes,
.mmoc-tiers {
	margin-top: var(--space-4);
}

.mmoc-codes__table {
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
	margin-top: var(--space-2);
}

.mmoc-codes__row {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	padding: var(--space-2);
	border-radius: 14px;
	background: var(--soft);
}

.mmoc-codes__info {
	min-width: 0;
	flex: 1;
}

.mmoc-codes__code {
	display: block;
	font-family: var(--font-mono);
	font-size: 15px;
	font-weight: 500;
	letter-spacing: .05em;
	line-height: var(--lh-snug);
	color: var(--ink);
}

.mmoc-codes__reward {
	display: block;
	font-size: 12px;
	line-height: var(--lh-ui);
	color: var(--mut);
}

.mmoc-copy {
	flex: 0 0 auto;
	padding: var(--space-1) var(--space-2);
	min-height: 32px;
	border: 0;
	border-radius: 999px;
	background: var(--acc);
	color: #fff;
	font-family: var(--font-ui);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: .06em;
	line-height: var(--lh-flat);
	cursor: pointer;
	transition: background-color .18s ease;
}

.mmoc-copy:hover,
.mmoc-copy:focus-visible {
	background: var(--accStrong);
}

.mmoc-copy:focus-visible {
	outline: 2px solid var(--acc);
	outline-offset: 2px;
}

.mmoc-codes__row.is-expired .mmoc-codes__code {
	text-decoration: line-through;
	color: var(--mut);
}

.mmoc-steps {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
	margin-top: var(--space-2);
}

.mmoc-step {
	display: flex;
	gap: var(--space-2);
	padding: var(--space-2);
	border-radius: 14px;
	background: var(--soft);
}

.mmoc-step__num {
	flex: 0 0 auto;
	font-size: 26px;
	font-weight: 800;
	line-height: var(--lh-flat);
	color: var(--acc);
}

.mmoc-step__label {
	display: block;
	font-size: 15px;
	font-weight: 700;
	line-height: var(--lh-snug);
	color: var(--ink);
}

.mmoc-step__body {
	display: block;
	font-size: 14px;
	line-height: var(--lh-body);
	color: var(--mut);
}

/* --- Tier module (tips-guides posts) --- */
.mmoc-tiers__table {
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
	margin-top: var(--space-2);
}

.mmoc-tier {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	padding: var(--space-1) var(--space-2);
	border-radius: 14px;
	background: var(--soft);
}

.mmoc-tier__badge {
	flex: 0 0 auto;
	width: 32px;
	height: 32px;
	border-radius: 10px;
	color: #fff;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 15px;
	font-weight: 800;
	line-height: var(--lh-flat);
}

.mmoc-tier__names {
	font-size: 14px;
	line-height: var(--lh-ui);
	color: var(--ink);
}

/* --- 404 --- */
.mmoc-404 {
	background: var(--card);
	border-radius: 18px;
	box-shadow: var(--shadow);
	padding: var(--space-4) var(--space-3);
	text-align: center;
}

.mmoc-404__code {
	font-family: var(--font-ui);
	font-size: 48px;
	font-weight: 800;
	line-height: var(--lh-flat);
	color: var(--acc);
	margin: 0;
}

.mmoc-404__text {
	color: var(--mut);
	font-size: 15px;
	line-height: var(--lh-body);
	margin: var(--space-1) 0 var(--space-3);
}

.mmoc-404 .mmoc-pills {
	justify-content: center;
}
