/* ==========================================================================
   Site chrome corrections — header layout.

   The header template's own CSS lives in Bricks page settings, which is a
   single opaque blob shared by every page. Corrections go here instead, in a
   versioned file that greps, diffs and reviews like the rest of the code.
   Rules are written to out-specify the template's without !important where
   possible; where the template itself uses !important (its narrow-screen nav
   rules do), this matches it.

   Owner feedback 2026-08-02: the masthead was three stacked rows — brand,
   then the search field, then the search button — and the wordmark sat too
   far in from the left edge.
   ========================================================================== */

/* The brand aligns EXACTLY with the content column (owner, 2026-08-03).

   .head-in is a flex ITEM of .site-head and carries no flex-grow, so it was
   sizing to its content and its auto margins were centring that block — the
   wordmark floated ~190px in. flex/width make it fill its column first.

   The inset is .wrap's own 20px, no more and no less. An earlier pass halved
   it to 10px for a deliberate leftward shift; the owner has since ruled the
   brand must sit flush with the page grid (the homepage skins are pinned to
   the same 1080/20 geometry in home-skins.css), so 20px it is — change one
   and the header visibly detaches from the page again. */
.site-head .head-in {
	flex: 1 1 auto;
	width: 100%;
	padding-inline: 20px;
}

/* One row: brand | nav | search. The template lets .head-in wrap, which is
   what let the search form fall to its own line — and once wrapped, the
   field and the button wrapped again against each other. */
.site-head .head-in {
	flex-wrap: nowrap;
	column-gap: 20px;
}

/* The nav takes the middle and the search sits at the end, so the search
   stops being a block of its own and becomes part of the navigation line. */
/* The nav keeps its natural width and simply sits after the brand. It must
   NOT be the flexible element: when it was, the search form's stretch ate the
   whole row and the nav computed to 0px wide with all six links still in it. */
.site-head .main-nav {
	margin-left: 0;
	flex: 0 1 auto;
	min-width: 0;
}

.site-head .main-nav ul {
	flex-wrap: nowrap;
	white-space: nowrap;
}

.site-head .search {
	margin-left: auto;
	flex: 0 0 auto !important;
	width: auto !important;
	display: flex;
	align-items: center;
	flex-wrap: nowrap;
	gap: 6px;
}

/* Bricks lays its forms out as a stack: .form-group is flex-basis:100%, so
   inside a row it absorbs the whole line. That is what put the button under
   the input AND, once the row stopped wrapping, what squeezed the nav to zero
   width. Both groups must size to their own content instead — !important
   because Bricks' own rule is a form-scoped selector we cannot out-specify
   from here without a longer chain than is worth maintaining. */
.site-head .search .form-group {
	margin: 0 !important;
	flex: 0 0 auto !important;
	width: auto !important;
	max-width: none !important;
	padding: 0 !important;
}

/* Bricks styles form inputs through a form-scoped rule that beats this one on
   specificity, so the field kept its intrinsic ~124px regardless of what was
   set here. That 124px is 3.5px too wide to sit beside the wordmark at 375px,
   which is the whole reason the search kept falling to its own line on
   mobile — so the width has to actually take. */
.site-head .search input[type="text"] {
	width: 9.5em !important;
	padding: 4px 8px !important;
	line-height: 1.4;
}

.site-head .search button {
	padding: 4px 10px;
	line-height: 1.4;
	white-space: nowrap;
}

/* Bricks' submit button carries a loading spinner span that is empty until a
   submit is in flight; left as an inline-block it adds width to every render. */
.site-head .search button .loading {
	display: none;
}

/* ==========================================================================
   Header interaction (owner, 2026-08-03: "currently it's very plain").

   The reference is 自由版's masthead bloom — petals grown from box-shadows on
   two pseudo-elements, sprung open by a hover. Here the bloom grows from the
   brand's own tick (the 10px mark between 茉莉花 and 新闻网), which is the one
   ornament the wordmark already has, so the effect reads as the mark opening
   rather than something bolted on.

   Everything is drawn from the ten :root tokens, so dark mode re-colors the
   whole interaction for free; nothing here names a literal color. All motion
   is transform/opacity/filter — no layout property animates, so hover cannot
   shift the row — and every effect collapses under prefers-reduced-motion.
   ========================================================================== */

/* The tick becomes a petal: one corner unrounded, tilted at rest. On brand
   hover it rights itself and warms from accent to flag — a small motion that
   happens even before the pointer finds the bloom. */
.site-head .brand { position: relative; }

.site-head .brand .tick {
	background: var(--accent);
	border-radius: 50% 50% 50% 0;
	transform: rotate(-18deg);
	transition: transform .45s cubic-bezier(.2, 1.45, .4, 1),
	            background-color .3s ease;
}

.site-head .brand:hover .tick {
	background: var(--flag);
	transform: rotate(27deg) scale(1.18);
}

/* The bloom: two shadow-petal clusters over the tick, closed to nothing at
   rest. The overshoot curve is 自由版's own (.2,1.45,.4,1) — the petals spring
   slightly past their place and settle, which is what makes it read as a
   flower opening instead of a fade-in. */
.site-head .brand .tick::before,
.site-head .brand .tick::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 50%;
	pointer-events: none;
	opacity: 0;
	transform: scale(0);
	transition: transform .7s cubic-bezier(.2, 1.45, .4, 1),
	            opacity .4s ease;
}

.site-head .brand .tick::before {
	background: var(--accent);
	box-shadow: 13px -5px 0 var(--accent),
	            -12px -7px 0 var(--accent),
	            5px -14px 0 var(--flag),
	            -6px 12px 0 var(--flag),
	            11px 9px 0 var(--accent);
}

.site-head .brand .tick::after {
	background: var(--flag);
	box-shadow: -3px -15px 0 var(--flag),
	            15px 3px 0 var(--accent),
	            -14px 5px 0 var(--accent),
	            2px 15px 0 var(--flag);
}

.site-head .brand:hover .tick::before {
	opacity: .95;
	transform: scale(1) rotate(18deg);
	transition-delay: .05s;
}

.site-head .brand:hover .tick::after {
	opacity: .7;
	transform: scale(1.25) rotate(-24deg);
	transition-delay: .1s;
}

/* The wordmark answers the bloom with a glow, not a color change: the two
   texts keep --ink so the header never flickers on pass-over. */
.site-head .brand .brxe-text-basic {
	transition: text-shadow .35s ease;
}

.site-head .brand:hover .brxe-text-basic {
	text-shadow: 0 0 16px color-mix(in srgb, var(--accent) 35%, transparent);
}

/* Nav links: an underline that grows from the left on hover and stays under
   the current page. Drawn as a scaled pseudo-element, not text-decoration,
   so it can animate; inset to the link's own 12px padding so it underlines
   the label, not the hit area. */
.site-head .main-nav a {
	position: relative;
	transition: color .25s ease;
}

.site-head .main-nav a::after {
	content: "";
	position: absolute;
	left: 12px;
	right: 12px;
	bottom: 3px;
	height: 2px;
	background: var(--accent);
	transform: scaleX(0);
	transform-origin: left center;
	transition: transform .28s ease;
}

.site-head .main-nav a:hover::after,
.site-head .main-nav a[aria-current="page"]::after {
	transform: scaleX(1);
}

/* The search field wakes on focus with the same accent. */
.site-head .search input[type="text"] {
	transition: border-color .25s ease, box-shadow .25s ease;
}

.site-head .search input[type="text"]:focus {
	border-color: var(--accent);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
	outline: none;
}

/* Motion is decoration here, never information: the current page keeps its
   static underline, the tick keeps its petal shape, and everything animated
   simply stops. */
@media ( prefers-reduced-motion: reduce ) {
	.site-head .brand .tick,
	.site-head .brand .tick::before,
	.site-head .brand .tick::after,
	.site-head .brand .brxe-text-basic,
	.site-head .main-nav a,
	.site-head .main-nav a::after,
	.site-head .search input[type="text"] {
		transition: none;
	}

	.site-head .brand:hover .tick {
		transform: rotate(-18deg);
	}

	.site-head .brand:hover .tick::before,
	.site-head .brand:hover .tick::after {
		opacity: 0;
		transform: scale(0);
	}
}

/* Narrow screens: the single row is the goal, not a rule to die for. Below
   the template's own 700px breakpoint the nav already drops to its own line
   (with !important), so the search joins the brand row rather than becoming
   a third one. */
@media ( max-width: 700px ) {
	.site-head .head-in {
		flex-wrap: wrap;
		padding-inline: 8px;
	}

	/* Two rows below 700px, not three: the wordmark and the search share the
	   first, and the nav — which the template already forces onto its own line
	   with !important — takes the second. */
	.site-head .search {
		order: 2;
		column-gap: 4px;
	}

	.site-head .search input[type="text"] {
		width: 7em !important;
	}
}


/* ==========================================================================
   文学城 SKIN — THE HEADER HALF

   HAZARD H2, resolved. A `.mh.mh-skin-wxc` scope lives inside the page's
   layout element and cannot reach the Bricks header, but 文学城 art-directs
   the header too: the reference is a legacy fixed-pixel page whose shell is
   1000px and whose search control is an exact 88x26 asset. home.js therefore
   stamps `html[data-mh-skin]` (the theme toggle already writes data-mh-theme
   the same way) and this block is the one documented exception that reads it.

   Nothing here is a colour change for its own sake. Each rule exists because
   the spec pins a measurement the site's own chrome contradicts.
   -------------------------------------------------------------------------- */

/* THE SHELL. home-skins.css pins the 文学城 layout to a 1000px legacy shell,
   40px narrower than the site's 1080 wrap. Left alone, the brand would sit
   20px outside the page content the owner asked twice to have it aligned
   with, so the header adopts the same shell while this skin is active. */
html[data-mh-skin="wxc"] .site-head .head-in {
	max-width: 1100px;   /* measured: 170px margins at a 1440 viewport */
	padding-inline: 0;
}

/* 宋体, not the site's UI sans — the same single stack the skin body uses.
   Restated rather than shared because chrome.css cannot see the skin's
   custom properties: they are declared on .mh, which is not an ancestor. */
html[data-mh-skin="wxc"] .site-head,
html[data-mh-skin="wxc"] .site-head input,
html[data-mh-skin="wxc"] .site-head button {
	/* The reference's real chrome stack, measured off the live page. This
	   REPLACES the Arial/SimSun serif stack inferred a round earlier — that
	   inference was wrong and the measurement corrects it. */
	font-family: "Microsoft YaHei", Tahoma, Verdana, STHeiTi, SimSun, sans-serif;
}

/* Utility scale: 12px/18px is the reference's small header text. */
html[data-mh-skin="wxc"] .site-head .nav a,
html[data-mh-skin="wxc"] .site-head .search input[type="text"] {
	font-size: 12px;
	line-height: 18px;
}

/* THE SEARCH BUTTON IS 88x26, AND IT IS TWO-TONE. The original is an image
   whose lower half is a much darker red — not a flat button and not a smooth
   gradient, so the stop sits hard at 50%. Square, unshadowed: every rounded
   corner or shadow here is what makes a legacy page read as a modern one. */
html[data-mh-skin="wxc"] .site-head .search button {
	width: 88px;
	min-width: 88px;
	height: 26px;
	padding: 0;
	border: 0;
	border-radius: 0;
	box-shadow: none;
	color: #fbf6f6;
	font-size: 14px;
	font-weight: 400;
	line-height: 26px;
	text-align: center;
	background: linear-gradient( to bottom,
		#b02222 0%, #b02222 50%, #680102 50%, #680102 100% );
}

/* The field squares off to match; 26px so field and button share a baseline. */
html[data-mh-skin="wxc"] .site-head .search input[type="text"] {
	height: 26px;
	padding: 0 6px !important;
	border-radius: 0;
	box-shadow: none;
}

/* The brand's petal bloom is this site's own flourish, not the reference's.
   A legacy portal header has no hover choreography, so 文学城 stands it down —
   the interaction stays available in the other three skins. */
html[data-mh-skin="wxc"] .site-head .brand .tick::before,
html[data-mh-skin="wxc"] .site-head .brand .tick::after {
	display: none;
}
html[data-mh-skin="wxc"] .site-head .brand:hover .tick {
	transform: none;
}


/* ==========================================================================
   小红书 SKIN — THE HEADER HALF

   Same mechanism as 文学城 above: home.js stamps html[data-mh-skin] so the
   skin can art-direct the Bricks header it cannot otherwise reach. Measured by
   the owner at 1536x960.
   ========================================================================== */

/* 72px, full width, near-opaque. The site header is already sticky; this only
   changes its height, its ground and its contents' geometry. */
html[data-mh-skin="xhs"] .site-head {
	height: 72px;
	background: rgba(10, 10, 10, .98);
	border-bottom: 0;
}
html[data-mh-skin="xhs"] .site-head .head-in {
	position: relative;
	max-width: none;
	height: 72px;
	padding-left: 32px;    /* puts the logo at x=32 */
	padding-right: 32px;
	align-items: center;   /* 32px box in a 72px header -> y=20 */
}

/* THE LOGO REPLACES THE WORDMARK.

   THE DOM IS `<a><div class="brand">…</div></a>` — the link WRAPS the brand, it
   is not inside it. A first pass used `.brand > a`, which matches nothing here,
   so the logo silently never appeared. Nor can .brand simply be absolutely
   positioned: it is the <a>'s only content, so taking it out of flow collapses
   the link's clickable area to zero.

   So the brand box IS the logo, left in flow, and the header's own padding and
   centring place it: 32px of left padding puts it at x=32, and a 32px box
   centred in a 72px header sits at y=20 — the measured position, arrived at
   rather than hardcoded. */
html[data-mh-skin="xhs"] .site-head .brand {
	flex: 0 0 auto;
	width: 68.333px;
	height: 32px;
	background: url("../img/xhs/molihua-xhs-logo.png?v=2") no-repeat center / contain;
	overflow: hidden;
}
/* Everything the capsule already says, hidden without emptying the link's
   accessible name: the text is pushed out of the box, not display:none. */
html[data-mh-skin="xhs"] .site-head .brand .brxe-text-basic,
html[data-mh-skin="xhs"] .site-head .brand .tick {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

/* The search field, at its measured geometry. 84px of right padding leaves
   room for the button that sits over its end. */
html[data-mh-skin="xhs"] .site-head .search input[type="text"] {
	width: 469.333px !important;
	height: 40px;
	padding: 0 84px 0 16px !important;
	border: 0;
	border-radius: 999px;
	background: rgba(255, 255, 255, .04);
	color: #ececec;
	font-size: 16px;
}
html[data-mh-skin="xhs"] .site-head .search button {
	height: 32px;
	padding: 0 16px;
	border: 0;
	border-radius: 999px;
	background: #ff2442;
	color: #fff;
	font-size: 14px;
}
html[data-mh-skin="xhs"] .site-head .main-nav { display: none; }

/* ---- 小红书: THE FOOTER, WHICH WAS INVISIBLE IN LIGHT MODE ----

   MEASURED IN THE BROWSER, not deduced. With the xhs skin on and the OS in light
   mode, the computed values were: page background rgb(10,10,10) — the skin
   darkens the whole page so the app shell reads right — while .site-foot inherited
   `color: rgb(26,26,24)`, the light-theme ink, and its links resolved to
   rgb(20,82,59). Near-black on near-black: a contrast ratio of about 1.04:1. The
   footer text was there and simply could not be seen.

   WHY IT HID FROM ME UNTIL I CHECKED BOTH SCHEMES. In DARK mode theme-dark.css
   supplies light ink, so the same footer measured rgb(233,231,224) and looked
   fine. The bug existed only in the light-mode + xhs combination, which is why
   reading the stylesheet would not have found it — nothing is wrong with any
   single rule. The skin re-coloured .site-head (right above) and never .site-foot.

   SO THESE ARE UNCONDITIONAL, not inside a prefers-color-scheme block. The page
   is dark whenever this skin is on, whatever the OS says, so the footer's ink must
   be too — putting them in a dark-mode query would fix only the case that already
   worked. Colours are the skin's own: #d9d9d9 secondary text and #eaeaea headings
   as used throughout skin-xhs.css, and #7fc9a4 for links, which is the value the
   site's own dark mode already resolves to. */
html[data-mh-skin="xhs"] .site-foot {
	background: #0a0a0a;
	color: #d9d9d9;
	border-top-color: rgba(255, 255, 255, .14);
}
html[data-mh-skin="xhs"] .site-foot p,
html[data-mh-skin="xhs"] .site-foot li,
html[data-mh-skin="xhs"] .site-foot .mission,
html[data-mh-skin="xhs"] .site-foot .legal,
html[data-mh-skin="xhs"] .site-foot .cp {
	color: #d9d9d9;
}
html[data-mh-skin="xhs"] .site-foot h2,
html[data-mh-skin="xhs"] .site-foot h3,
html[data-mh-skin="xhs"] .site-foot strong {
	color: #eaeaea;
}
/* Every footer link, including the three mailto addresses and the legal row.
   `.brxe-text-link` is Bricks' own class on those elements — targeted because the
   mailto links carry it and nothing else distinguishes them. */
html[data-mh-skin="xhs"] .site-foot a,
html[data-mh-skin="xhs"] .site-foot .brxe-text-link,
html[data-mh-skin="xhs"] .site-foot .brxe-text-link a {
	color: #7fc9a4;
}
html[data-mh-skin="xhs"] .site-foot a:hover,
html[data-mh-skin="xhs"] .site-foot .brxe-text-link:hover { color: #fff; }


/* ==========================================================================
   THE SKIN SWITCHER — A TOP BANNER, ONE PLACE, EVERY SKIN

   Owner, standing rule restated three times, and their chosen placement: a
   strip at the very top of the page, above the site header. The requirement is
   about the pointer, not decoration — the skin changes under the cursor, so a
   bar that moves makes the next click miss.

   home.js moves .mh-skins out of the layout element and inserts it before
   .site-head. A band of its own is why this is the clean version: it cannot
   collide with the brand, the nav or the search box the way a header-row
   insertion did, and it is in the same place on every page and in every skin by
   construction rather than by four skins agreeing. Skins may recolour it. None
   of them may move it — no per-skin geometry belongs below.
   ========================================================================== */

.mh-skins-top {
	display: flex;
	align-items: center;
	gap: 8px;
	width: 100%;
	margin: 0;
	padding: 5px 20px;
	overflow-x: auto;              /* never wraps to a second line */
	scrollbar-width: none;
	white-space: nowrap;
	background: var(--surface, #f4f4f5);
	border-bottom: 1px solid var(--rule, #e4e4e7);
	font-size: 0;                  /* the renderer's 换皮肤： label */
	line-height: 1.6;
	color: var(--muted, #6b7280);
}
.mh-skins-top::-webkit-scrollbar { display: none; }

.mh-skins-top a {
	flex: 0 0 auto;
	padding: 2px 10px;
	border: 1px solid transparent;
	border-radius: 3px;
	color: inherit;
	font-size: 13px;
	text-decoration: none;
}
.mh-skins-top a:hover { border-color: currentColor; }
.mh-skins-top a.on { border-color: currentColor; font-weight: 600; }

/* Colour only, per skin. 小红书 is near-black; 文学城 is paper. */
html[data-mh-skin="xhs"] .mh-skins-top {
	background: #0a0a0a;
	border-bottom-color: #232323;
	color: rgba(255, 255, 255, .62);
}
html[data-mh-skin="xhs"] .mh-skins-top a.on { color: #fff; }
html[data-mh-skin="wxc"] .mh-skins-top {
	background: #f8f9f5;
	border-bottom-color: #d9ded6;
	color: #4a4a4a;
}


/* ==========================================================================
   文学城 DELETES THE SITE HEADER (owner, 2026-08-03)

   For this skin only: the 茉莉花新闻网 wordmark, the page links and the dark
   toggle all go, and 站内搜索 moves up to share the top line with the skin
   switcher (home.js relocates the field and puts it back for other skins). The
   bar they used to occupy is then empty, so it is removed rather than left as a
   72px band of nothing.

   THE DEFAULT 茉莉花 SKIN IS UNTOUCHED — header, page links and dark toggle
   exactly as they were. Everything here is scoped to one attribute value.
   ========================================================================== */

html[data-mh-skin="wxc"] .site-head { display: none; }

/* NO SEARCH IN THIS SKIN (owner, 2026-08-03). It went with the header rather
   than moving to the top line: the strip is the switcher and the two accounts,
   and a search field crowded the one row the reader uses to change skins.
   Removing the relocation also removed the state it needed — there is no longer
   a node being moved between two parents on every skin change. */



/* ==========================================================================
   THE TWO ACCOUNTS, on the switcher line

   HomeRenderer emits them inside .mh-skins, so they travel with the bar to the
   top of the page and sit in the same place in every skin — the same guarantee,
   for the same pointer reason, and no per-skin geometry below.

   The glyphs are inline SVG. Not an icon font and not a remote image: this page
   makes zero external requests by design, and for a readership behind the GFW a
   blocked CDN turns a logo into a broken box.
   ========================================================================== */

/* SCOPED TO .mh-skins, NOT .mh-skins-top. The -top class is added by JavaScript
   when the bar is relocated; if that has not run — script blocked, an error
   earlier in the file, a page without the site header — the icons would have had
   no size and no layout at all. They must be correct wherever the bar is. */
/* SCOPED TO .mh-skins, NOT .mh-skins-top. The -top class is added by JavaScript
   when the bar is relocated; if that has not run — script blocked, an error
   earlier in the file, a page without the site header — the icons would have had
   no size and no layout at all. They must be correct wherever the bar sits. */
.mh-skins .mh-social {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	/* BESIDE THE SKIN LINKS, NOT AT THE FAR EDGE. margin-left:auto pushed the
	   pair to the right end of a full-width bar, where on a wide screen they sat
	   a thousand pixels from anything else at 15px and 72% opacity — present in
	   the DOM, effectively invisible to a reader, which is how the owner
	   reported them as missing. A separator carries the break instead. */
	margin-left: 4px;
	padding-left: 12px;
	border-left: 1px solid currentColor;
	flex: 0 0 auto;
}
.mh-skins .mh-social a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 24px;
	height: 24px;
	padding: 0;
	border: 0;
	border-radius: 3px;
	color: inherit;
	opacity: 1;             /* full contrast: these are 18px marks, not chrome */
	transition: opacity .18s ease, color .18s ease;
}
.mh-skins .mh-social a:hover { opacity: 1; }
.mh-skins .mh-social svg {
	width: 18px;
	height: 18px;
	fill: currentColor;
	display: block;
}
/* X is monochrome by convention; Facebook keeps its blue on hover so the two
   are told apart at 15px, where the marks alone are easy to confuse. */
.mh-skins .mh-social-fb:hover { color: #1877f2; }


/* ==========================================================================
   小红书 SEARCH — left-aligned, and no white box (owner, 2026-08-03)

   Two reports: on the desktop the field sat far from the logo instead of beside
   it as the reference has it, and on a phone it showed as a white blank band
   doing nothing. The white was Bricks' own form chrome: the <form> and its two
   .form-group wrappers carry a light ground that shows through on a #0a0a0a
   header, and on a narrow screen the wrappers wrap to their own line, so what
   the reader saw was an empty pale strip with no visible field in it.
   ========================================================================== */

/* THE FIELD SITS BESIDE THE LOGO. The base rule gives .search margin-left:auto,
   which parks it at the far end of the row; the reference puts its search
   immediately after the wordmark, so that auto has to be undone rather than
   overridden with a width. */
/* CENTRED ON THE CARDS COLUMN, NOT ON THE PAGE (owner, 2026-08-03: "if the
   cards section is 10 and the search bar is 2, then it occupies 5 and 6").

   The feed column is offset right of page centre because the nav rail sits to
   its left, so page-centre is the wrong axis. The arithmetic:

     feed starts at 16 (left pad) + 234.667 (rail) + 32 (gap) = 282.667
     feed width  = W - 282.667 - 32 (right pad)
     feed centre = 282.667 + (W - 314.667) / 2
     minus page centre (W/2)  =  282.667 - 157.333  =  +125.333px

   The W cancels: the offset is the SAME 125.333px at every viewport width
   (checked at 1280/1440/1536/1920). So this is one constant translation from
   page centre, not a per-breakpoint measurement — and if the rail or the gaps
   ever change, the two numbers above are where it comes from.

   Absolute rather than a flex margin: a margin would have to know the logo's
   width, which is a different thing that could change on its own. */
html[data-mh-skin="xhs"] .site-head .search {
	position: absolute;
	left: 50%;
	/* DERIVED, so it cannot drift from the rail. The offset of the feed column's
	   centre from the page centre reduces to (rail + lpad*2 - rpad) / 2, and with
	   lpad 16 / gap 32 / rpad 32 that is (rail + 16) / 2 — the viewport width
	   cancels, which is why one constant works at every width. At the old
	   234.667 rail this evaluated to the 125.333 that used to be hardcoded here. */
	transform: translateX(calc(-50% + (var(--mh-xhs-rail) + 16px) / 2));
	/* 900px (owner, 2026-08-03; was 469.333). It still fits the feed column at
	   every supported width — the narrowest desktop tier here is 1120px, whose
	   feed is 1120 - 314.667 = 805px, so the field is clamped by max-width:100%
	   below that rather than overflowing the column it is centred on. */
	width: 900px;
	max-width: 100%;
	margin: 0;
	flex: 0 0 auto !important;
}


/* Bricks' form grounds, made transparent. Without this the dark header carries
   a pale rectangle the width of the form. */
html[data-mh-skin="xhs"] .site-head .search,
html[data-mh-skin="xhs"] .site-head .search .form-group,
html[data-mh-skin="xhs"] .site-head .search .submit-button-wrapper {
	background: transparent !important;
	border: 0 !important;
	box-shadow: none !important;
}
/* The field itself is the only thing with a ground, and it is the reference's
   own faint fill on the header colour rather than white. */
html[data-mh-skin="xhs"] .site-head .search input[type="text"] {
	width: 100% !important;
	max-width: none;
	min-width: 0;
	height: 40px;
	padding: 0 16px !important;
	border: 0 !important;
	border-radius: 999px;
	background: rgba(255, 255, 255, .06) !important;
	color: #ececec;
	font-size: 16px;
	line-height: 40px;
}
html[data-mh-skin="xhs"] .site-head .search input[type="text"]::placeholder {
	color: rgba(255, 255, 255, .42);
}
html[data-mh-skin="xhs"] .site-head .search .form-group:first-child {
	flex: 1 1 auto !important;
	min-width: 0;
}

/* PHONES. The row is brand | field | button, and the field takes what is left
   instead of wrapping to a line of its own — a wrapped form was the blank band.
   The 40px control shrinks to 34px so the 72px header still has air. */
@media (max-width: 700px) {
	html[data-mh-skin="xhs"] .site-head .search {
		margin-left: 12px;
		max-width: none;
	}
	html[data-mh-skin="xhs"] .site-head .search input[type="text"] {
		height: 34px;
		max-width: none;
		padding: 0 12px !important;
		font-size: 14px;
		line-height: 34px;
	}
	html[data-mh-skin="xhs"] .site-head .search button {
		height: 34px;
		padding: 0 12px;
		font-size: 13px;
	}
	/* The switcher strip keeps its own full line on purpose (owner: it "always
	   occupies an entire line to keep stability"), so nothing here may pull it
	   into the header row. */
}


/* ==========================================================================
   小红书 PHONE: THE SEARCH IS REMOVED, AND NOTHING BEHIND IT CAN BE WHITE

   Owner, second report: the white area is still there and must go. My previous
   pass made the form's own grounds transparent, which was necessary but not
   sufficient — a transparent form over a white PAGE is still white. Two things
   were wrong and only one had been fixed.

   1. THE FIELD ITSELF IS GONE on a phone. It was the thing the owner described
      as "doing nothing": a 72px header carrying a logo, a field and a button
      leaves the field a few dozen pixels, which is not a usable search. The
      nav rail reaches every section, so nothing becomes unreachable.
   2. THE GROUND BEHIND IT IS DARK. .site-head is 72px with a near-black fill,
      but html/body keep the site's light background, so anything that overflows
      or wraps out of that 72px band — as the wrapped form did — is painted on
      white. Setting the document ground for this skin means there is no white
      left to leak, whatever wraps.
   ========================================================================== */

/* Belt: the document itself is dark while this skin is active, so no gap
   between or around the header, the strip and the layout can show white. */
html[data-mh-skin="xhs"],
html[data-mh-skin="xhs"] body {
	background: #0a0a0a;
}

/* THE NAV RAIL'S WIDTH LIVES HERE, ON <html>, because two stylesheets need it:
   home-skins.css sizes the grid column, and the rule below centres the search on
   the FEED column, whose position depends on it. Narrowed from 234.667 to 200px
   (owner, 2026-08-03) so every card gets wider — at 1536 the feed goes 1221.3 ->
   1256px and a five-column card 218.7 -> 225.6px. */
html[data-mh-skin="xhs"] { --mh-xhs-rail: 164px /* was 200; owner 2026-08-05: cards widen into the panel */; }

@media (max-width: 700px) {
	/* Braces: the form is removed outright rather than shrunk. */
	/* The field is removed on a phone (see above), which also unwinds the
	   absolute, feed-centred placement — there is no feed column to centre on
	   when the rail has collapsed to a scrolling row. */
	html[data-mh-skin="xhs"] .site-head .search {
		display: none !important;
		position: static;
		transform: none;
	}

	/* With the field gone the row is brand alone; keep it from stretching. */
	html[data-mh-skin="xhs"] .site-head .head-in {
		flex-wrap: nowrap;
		height: 56px;
		padding-left: 16px;
		padding-right: 16px;
	}
	html[data-mh-skin="xhs"] .site-head { height: 56px; }
}


/* ==========================================================================
   文学城: no dark mode, and no dark toggle (owner, 2026-08-03)

   The skin is always bright. Its own header is removed, so the ☾/☀ control is
   already gone from the page — but the theme toggle also writes data-mh-theme on
   <html>, and that attribute is what every dark rule keys on. Forcing the
   document's own ground light while this skin is active means a reader arriving
   from a dark 茉莉花 sees a light 文学城, which is the reference's only mode.
   ========================================================================== */

html[data-mh-skin="wxc"],
html[data-mh-skin="wxc"] body {
	background: #ffffff;
	color-scheme: only light;
}
/* Belt and braces: if the header is ever shown again in this skin, its toggle
   still must not be. */
html[data-mh-skin="wxc"] .site-head .mh-theme-toggle,
html[data-mh-skin="wxc"] .site-head [data-mh-theme-toggle] { display: none !important; }


/* ==========================================================================
   THE SWITCHER STRIP IS THE SAME SIZE EVERYWHERE (owner, 2026-08-03)

   "keep the size and location across mobile and desktop to ensure the smoothest
   switching experience." On a phone the strip was rendering smaller than on the
   desktop, which breaks the same guarantee the fixed POSITION was protecting:
   a reader who switches skins on a phone should find the next control under the
   same thumb, at the same size.

   So the strip declares its own type and box and does NOT inherit them, and no
   breakpoint below may change either. It scrolls sideways when the four labels
   plus two icons exceed the width — the one thing that must give on a narrow
   screen is the VIEWPORT of the strip, never the size of what is inside it.
   ========================================================================== */

/* ONE NAME FOR THE BAR'S FONT. Declared on :root so both the base rule and the
   per-skin rule can reference the SAME value — the previous version restated the
   stack in one place and wrote `font-family: inherit` in the other, meaning to
   say "the stack above" while actually saying "take the body's", which is
   precisely the per-skin drift this was supposed to prevent. */
:root {
	--mh-switcher-font: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
		"Source Han Sans SC", "Noto Sans CJK SC", -apple-system,
		BlinkMacSystemFont, "Segoe UI", Arial, sans-serif;
}

.mh-skins-top {
	box-sizing: border-box;
	min-height: 34px;

	/* TRUE MIDDLE (owner, 2026-08-03). Centred rather than left-aligned so the
	   bar sits in the same screen position in every skin AND at every width —
	   the point being that after a click the next control is still under the
	   cursor. Safe to centre: the three labels plus two icons measure ~253px,
	   inside a 375px phone, so the overflow-x scroll below is a fallback that
	   should never engage rather than something centring can strand. */
	justify-content: center;

	/* THE FONT IS DECLARED, NOT INHERITED, and this is why the bar looked
	   different in 小红书 on a phone. home.js moves this element OUT of the
	   layout and inserts it before .site-head, so it is a child of <body> and
	   inherits whatever the document font happens to be — which the skins change
	   (文学城 sets a YaHei stack, the default a PingFang one). An inherited font
	   cannot be "the same in every skin", so the stack is stated here and the
	   bar stops depending on its surroundings entirely. */
	font-family: var(--mh-switcher-font);
	font-size: 0;                    /* the renderer's 换皮肤： label */
	font-weight: 400;
	line-height: 1.6;
	letter-spacing: 0;
	-webkit-text-size-adjust: 100%;  /* iOS must not inflate the labels */
	text-size-adjust: 100%;
}
.mh-skins-top a { font-size: 13px; }
.mh-skins-top .mh-social a { width: 24px; height: 24px; }
.mh-skins-top .mh-social svg { width: 18px; height: 18px; }

/* Explicitly restated at every width this site defines a breakpoint for, so a
   future mobile rule cannot quietly shrink it again. */
@media (max-width: 900px) {
	.mh-skins-top { min-height: 34px; padding: 5px 20px; justify-content: center; font-weight: 400; }
	.mh-skins-top a { font-size: 13px; padding: 2px 10px; }
	.mh-skins-top .mh-social a { width: 24px; height: 24px; }
	.mh-skins-top .mh-social svg { width: 18px; height: 18px; }
}
@media (max-width: 620px) {
	/* Only the strip's own side padding tightens — the controls do not. */
	.mh-skins-top { min-height: 34px; padding: 5px 12px; justify-content: center; font-weight: 400; }
	.mh-skins-top a { font-size: 13px; padding: 2px 10px; }
	.mh-skins-top .mh-social a { width: 24px; height: 24px; }
	.mh-skins-top .mh-social svg { width: 18px; height: 18px; }
}


/* The per-skin rules above may set COLOUR on this bar and nothing else. Stated
   as a rule because it has now been broken twice in opposite directions: once by
   per-skin geometry, once by an inherited font. If a skin needs the switcher to
   look different, the answer is no. */
html[data-mh-skin] .mh-skins-top {
	/* NOT `inherit` — that resolves to the BODY's font, which every skin
	   changes, and is why 小红书 on a phone still looked different after the bar
	   was supposedly pinned. The named stack is the only correct value here. */
	font-family: var(--mh-switcher-font);
	font-size: 0;
	line-height: 1.6;
	min-height: 34px;
	justify-content: center;
}
/* `> a` — DIRECT CHILDREN ONLY. The skin labels are children of the bar; the two
   account icons are children of .mh-social inside it. Written as a bare
   descendant `a`, this rule reached the icons too, and its padding:2px 10px ate
   20px of each 24px icon box, leaving about 4px of glyph. That is why they went
   tiny across every skin the moment this rule was added.

   Fixed by STRUCTURE rather than by out-specifying it: a child selector cannot
   match an icon, so no future rule here has to remember they exist. */
html[data-mh-skin] .mh-skins-top > a {
	font-family: var(--mh-switcher-font);
	font-weight: 400;
	line-height: 1.6;
	padding: 2px 10px;
}
html[data-mh-skin] .mh-skins-top a { font-size: 13px; }


/* ==========================================================================
   THE SWITCHER, CONSOLIDATED — LAST WORD

   TWO SELECTOR SHAPES, and the distinction is the whole point:
     `.mh-skins-top > a`            the four skin labels — type, padding, border
     `.mh-skins-top .mh-social a`   the two account icons — a fixed square box
   A bare descendant `a` matches BOTH, which is the bug this pair prevents and
   which has now shipped once.

   This also supersedes the three near-identical breakpoint blocks above, which
   restated the same values at 900px and 620px against a shrink that never comes.
   That repetition is what let a stray selector slip in unnoticed; they are left
   in place only because they are inert.
   ========================================================================== */

.mh-skins-top > a {
	flex: 0 0 auto;
	padding: 2px 10px;
	border: 1px solid transparent;
	border-radius: 3px;
	font-family: var(--mh-switcher-font);
	font-size: 13px;
	font-weight: 400;
	line-height: 1.6;
	color: inherit;
	text-decoration: none;
}
.mh-skins-top > a.on { border-color: currentColor; font-weight: 600; }

/* The icons: a square box with NO padding and a glyph that fills it. Stated at a
   specificity that beats every `.mh-skins-top … a` rule in this file, because one
   of them already reached in here once. */
html[data-mh-skin] .mh-skins-top .mh-social a,
.mh-skins-top .mh-social a {
	flex: 0 0 24px;
	width: 24px;
	height: 24px;
	min-width: 24px;
	padding: 0;
	border: 0;
	border-radius: 3px;
	line-height: 1;
}
html[data-mh-skin] .mh-skins-top .mh-social svg,
.mh-skins-top .mh-social svg {
	width: 18px;
	height: 18px;
	fill: currentColor;
	display: block;
}


/* ==========================================================================
   ONE SIZE, EVERYWHERE — the switcher's final geometry

   The owner has reported the bar as too small on a phone twice, and the last two
   attempts both answered the wrong question: they PINNED the size so it would
   stop varying, which it now does, without ever making it bigger. Identical and
   too small is still too small.

   So the whole bar steps up, once, for every skin and every width. 13px text on a
   phone is genuinely small next to native UI, and this bar is the one control a
   reader is expected to hit repeatedly. 15px on a 40px row gives a hit target
   near the 44px the platforms ask for, without a breakpoint — because a size that
   changes with the viewport is the thing the owner ruled out.

   Everything below is stated at the highest specificity used anywhere in this
   file for these elements, so it is the last word regardless of source order.
   ========================================================================== */

html .mh-skins-top,
html[data-mh-skin] .mh-skins-top {
	min-height: 40px;
	padding: 6px 16px;
	gap: 10px;
}

/* The four skin labels. `> a` so this cannot reach an icon. */
html .mh-skins-top > a,
html[data-mh-skin] .mh-skins-top > a {
	padding: 4px 12px;
	font-size: 15px;
	line-height: 1.5;
	border-radius: 4px;
}

/* The two account icons: a 28px box with a 20px glyph, no padding. */
html .mh-skins-top .mh-social,
html[data-mh-skin] .mh-skins-top .mh-social {
	gap: 12px;
	padding-left: 14px;
}
html .mh-skins-top .mh-social a,
html[data-mh-skin] .mh-skins-top .mh-social a {
	flex: 0 0 28px;
	width: 28px;
	height: 28px;
	min-width: 28px;
	padding: 0;
	border: 0;
}
html .mh-skins-top .mh-social svg,
html[data-mh-skin] .mh-skins-top .mh-social svg {
	width: 20px;
	height: 20px;
}


/* ==========================================================================
   MOBILE: THE HEADER NEEDS A MARGIN (owner, 2026-08-03)

   On a phone the brand and 站内搜索 sat flush against the screen edge while the
   content below them already had one. This is the SITE HEADER, not a skin band —
   the masthead element (.mh-mast) belongs to 文学城's portal layout and a test
   forbids the other skins from touching it, which is how the first attempt at
   this landed in the wrong file.

   Applied to the shared header so every skin that shows one benefits. 文学城
   hides its header entirely and 小红书 sets its own 16px inset, so neither is
   affected: this reaches the default 茉莉花 skin, which is what was asked for.
   ========================================================================== */

@media (max-width: 700px) {
	.site-head .head-in {
		padding-inline: 14px;
		row-gap: 8px;
		padding-block: 8px;
	}
	.site-head .search { margin-top: 2px; }
}

/* ==========================================================================
   文章头图 — the article page's lead photograph (owner ruling 2026-08-04)

   Emitted by molihua-article-photo (ArticlePhotoRenderer): the ADR-0014
   key_article derivative, above .art-body. P5: an article without a stored
   photo emits no element at all, so these rules style presence only. The
   width/height attributes are on the <img>, so the box reserves its height
   before the bytes arrive and the headline never jumps.
   ========================================================================== */
.art-photo {
	margin: 18px 0 22px;
}
.art-photo img {
	display: block;
	width: 100%;
	height: auto;
	border-radius: 2px;
}
.art-photo figcaption {
	margin-top: 8px;
	font-size: 13px;
	line-height: 1.6;
	color: #767268;
}
.art-photo-credit {
	margin-left: 10px;
	color: #9b968a;
}

/* ==========================================================================
   文章页两栏 — the article canvas (owner spec, 2026-08-05, after the
   wenxuecity article page): 1022px of content — 645px of article, a 41px
   divider, a 336px sidebar carrying 同类最新 over 一周点击排行.

   .art-canvas is set on the template's own <main> by
   tools/molihua-insert-article-sidebar.php, so these rules can outrank the
   template page-CSS's `main.brxe-section.wrap { display:block; max-width:
   1080px }` (0,2,1) by specificity (0,3,1) instead of by print order —
   which <style> block the server emits last must never decide the page's
   shape. 1062 = 1022 content + the wrap's own 2x20 padding.
   ========================================================================== */
main.brxe-section.wrap.art-canvas {
	display: grid;
	grid-template-columns: minmax(0, 645px) 336px;
	column-gap: 41px;
	justify-content: center;
	max-width: 1100px;
}
/* BOTH PINNED TO ROW 1. Bricks renders more children into <main> than the
   two we placed (style carriers, wrappers), and grid auto-flow gave the
   sidebar the row AFTER them — measured 2151px down the page. Explicit rows
   make the layout independent of whatever else the builder emits. */
main.art-canvas > .art { min-width: 0; grid-column: 1; grid-row: 1; }
main.art-canvas > .art-side { grid-column: 2; grid-row: 1; min-width: 0; align-self: start; }

/* The rails. Dense title rows under a barred heading — the reference's own
   sidebar idiom, in this site's palette. P5: an empty rail emits no section,
   so nothing here styles absence. */
.art-side .art-side-h {
	margin: 0 0 6px;
	padding: 6px 10px;
	background: var(--c-accent, #2e5631);
	color: #fff;
	font-size: 15px;
	font-weight: 500;
	line-height: 1.5;
}
.art-side section + section { margin-top: 22px; }
.art-side .art-side-list {
	margin: 0;
	padding: 0;
	list-style: none;
	counter-reset: art-rk;
}
.art-side .art-side-list li {
	position: relative;
	padding: 5px 0 5px 24px;
	font-size: 14px;
	line-height: 1.55;
	border-bottom: 1px dotted #e2e0da;
}
.art-side .art-side-list li::before {
	counter-increment: art-rk;
	content: counter(art-rk);
	position: absolute;
	left: 0;
	top: 7px;
	width: 17px;
	height: 17px;
	background: #eceae3;
	color: #6f6b60;
	font-size: 11px;
	line-height: 17px;
	text-align: center;
	border-radius: 2px;
}
.art-side .art-side-list li:nth-child(-n+3)::before {
	background: var(--c-accent, #2e5631);
	color: #fff;
}

/* 同类最新 IS CHRONOLOGICAL, SO IT MUST NOT WEAR THE RANKING'S NUMERALS.
   The counter chip above says "this is a ranking" and the top-three accent
   says "these three won". Both are true of 一周点击排行 and neither is true of
   a list in the order the articles reached us: a reader who sees 1 2 3 in
   green will read the first title as the most important story in the section,
   which this rail does not claim. Dropping the chip is also what tells the two
   rails apart before either heading is read — one wears numbers, one does not.

   Scoped to .art-topic, so .art-rank keeps every rule above untouched.
   Specificity (0,3,2) beats the (0,2,2) it overrides, so this does not depend
   on print order. The freed 24px goes back to the titles, which are CJK and
   were wrapping inside a 336px column. */
.art-side .art-topic .art-side-list li { padding-left: 0; }
.art-side .art-topic .art-side-list li::before { content: none; }
.art-side .art-side-list a { color: inherit; text-decoration: none; }
.art-side .art-side-list a:hover { color: #c0392b; }
/* No box on a clicked sidebar title either (owner, 2026-08-05). */
.art-side .art-side-list a:focus,
.art-side .art-side-list a:focus-visible { outline: none; }
.art-side .art-side-list a:focus-visible { text-decoration: underline; text-underline-offset: 3px; }

/* One column when the canvas cannot hold 645+41+336: the sidebar follows
   the article rather than squeezing it. */
@media (max-width: 1061px) {
	main.brxe-section.wrap.art-canvas { display: block; }
	.art-side { margin-top: 34px; }
}

/* ==========================================================================
   NO RING ON A CLICKED LINK (owner, 2026-08-05: "a rectangular border …
   circles the whole title line — remove this")

   Safari gives a clicked link :focus and draws its default ring on it;
   engines that implement the :focus-visible split never ring a pointer
   click. The pair below makes every engine behave like the split: plain
   :focus draws nothing (author styles outrank UA styles), and the ring is
   granted back to :focus-visible alone, so keyboard navigation keeps its
   indicator everywhere. Skins that draw their own :focus-visible ring are
   more specific and keep winning.
   ========================================================================== */
a:focus { outline: none; }
a:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }

/* ==========================================================================
   「另有 X、Y 报道」 — the other outlets covering the same event
   (owner ruling 2026-08-06; ADR-0019 context)

   This replaced the 「相关报道 N」 chip. A count told the reader there was
   more without telling them whether it was worth having; for this audience
   the spread of who is carrying a story is often the story.

   Here rather than in each page's Bricks custom CSS because chrome.css is
   enqueued on every request, and the line appears in every module list —
   homepage, topic pages, 最新滚动. The page-level stylesheets are duplicated
   across a dozen pages and adding a thirteenth copy of one rule is how they
   drift.

   display:block is the whole layout: `.rows li` is a grid of
   [source | headline | time] and this span lives INSIDE the headline cell,
   so going block puts it on its own line under the title without touching
   the grid. Same trick as .flag, which is already live.

   No link styling, deliberately — the ruling was that these names are
   attribution, not navigation.
   ========================================================================== */
.rows .h .also,
.lrows .h .also,
.h .also {
	display: block;
	margin-top: 2px;
	font-size: 12px;
	line-height: 1.4;
	color: var(--ink-2);
}

/* ==========================================================================
   事件脉络 — earlier chapters of a developing story
   (owner ruling 2026-08-06; ADR-0019/0021 context)

   The article page can now carry TWO sibling blocks inside one <aside
   class="related">: 相关报道 (other outlets on THIS event) and 事件脉络 (what
   happened before it). They are deliberately not one list — a report from three
   weeks ago is not another account of today's news, and the owner ruled a
   developing story stays separate items.

   Only the SECOND heading needs anything: .related-h carries no rule of its own
   and inherits h2, which is correct for a heading that follows a rule line. A
   second heading following a list needs its own separation, and a hairline to
   say "different thing", not "more of the same".
   ========================================================================== */
.related-h-line {
	margin-top: 22px;
	padding-top: 12px;
	border-top: 1px dotted var(--rule);
}

/* ==========================================================================
   ARTICLE BODY: paragraphs that were never <p> (owner report 2026-08-07)
   ==========================================================================
   Some publishers mark paragraphs up as nested <div><span>, not <p>. 机核 is
   one: a body arrives as
       <div><div><div><span><span>…</span></span></div></div>…
   and the sanitiser keeps that structure faithfully. Every paragraph rule in
   the theme targets `p`, so those articles rendered as one unbroken wall —
   "没有该有的空行", exactly as reported.

   The durable fix is in extraction, normalising block wrappers to <p> before
   storage; that needs a worker change and a re-extraction of what is already
   published. This is the reader-facing half, and it is safe on its own: it
   gives spacing to the DIRECT block children of a body that has no paragraphs
   of its own, so a correctly-marked-up article is untouched.
   -------------------------------------------------------------------------- */

/* THE PARAGRAPHS ARE NOT THE DIRECT CHILDREN. This first targeted
   `.art-body > div`, which is a single wrapper holding all 26 of them — one
   margin on the outside of the whole article, spacing nothing. Measured on
   the page: .art-body has ONE child, that child has 26. So the rule applies
   to any div that holds text and is not merely a wrapper around one other
   div. */
.art-body:not(:has(> p)) div:not(:has(> div + div)) {
  margin-block: 1.05em;
}

.art-body:not(:has(> p)) > div,
.art-body:not(:has(> p)) > div > div:first-child { margin-top: 0; }

/* Some of those spans carry the publisher's inline styling; the body's own
   measure and colour must still win. */
.art-body > div span { font-size: inherit; line-height: inherit; color: inherit; }

/* --------------------------------------------------------------------------
   转载信息 + 限期保留 fold behind native <details> (owner, 2026-08-07):
   the facts stay in the page — printed, indexed, JS-free — behind one line.
   -------------------------------------------------------------------------- */
.attr-fold > summary,
.expiry-fold > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.attr-fold > summary::-webkit-details-marker,
.expiry-fold > summary::-webkit-details-marker { display: none; }
.attr-fold > summary::after,
.expiry-fold > summary::after {
  content: "展开 ▾";
  margin-left: auto;
  font-size: 12px;
  color: var(--mh-dim, #8a8478);
  white-space: nowrap;
}
.attr-fold[open] > summary::after,
.expiry-fold[open] > summary::after { content: "收起 ▴"; }
.attr-fold > summary .attr-h { margin: 0; display: inline-flex; gap: 8px; align-items: baseline; }
/* Print shows everything: paper cannot tap. */
@media print {
  .attr-fold > dl, .attr-fold > .attr-note, .expiry-fold > p { display: block !important; }
  .attr-fold > summary::after, .expiry-fold > summary::after { content: ""; }
}

/* --------------------------------------------------------------------------
   关于茉莉花 — the owner letter as the page (2026-08-07). Same grammar as
   every inner page: 1100px shell, serif over an ink rule, green kicker,
   green-tinted letter panel, three quiet fact columns.
   -------------------------------------------------------------------------- */
/* ------------------------------------------------------------------
   TOKEN BRIDGE. Everything below is written against --mh-*, but that family
   is defined in home-rescue.css, which is enqueued only on the front page —
   so on /about/ every --mh-* was UNDEFINED and each declaration using one was
   invalid at computed-value time. Silently: the letter lost its panel, its
   border and its serif, and every hairline computed to border-width 0. The
   page had been rendering as unstyled text for as long as it has existed.
   
   Mapping to the inner-page family (--ink/--ink-2/--rule/--accent, defined in
   the parent theme and flipped by theme-dark.css) rather than restating hex
   values, so 关于 follows the reader's light/dark choice for free.
   ------------------------------------------------------------------ */
.mh-about {
	--mh-ink: var(--ink);
	--mh-muted: var(--ink-2);
	--mh-line: var(--rule);
	--mh-green: var(--accent);
	--mh-panel: var(--surface, #fffdf8);
	--mh-serif: "Songti SC", "Noto Serif CJK SC", "Source Han Serif SC", STSong, Georgia, serif;
	--mh-sans: -apple-system, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Source Han Sans SC", sans-serif;
}

.mh-about { width: min(1100px, calc(100% - 32px)); margin: 34px auto 60px; }
.mh-about-head { border-bottom: 2px solid var(--mh-ink); padding-bottom: 16px; }
.mh-about-k { margin: 0 0 6px; font-family: var(--mh-sans); font-size: 11px; letter-spacing: .22em; color: var(--mh-green); }
.mh-about-t { margin: 0 0 8px; font-family: var(--mh-serif); font-size: 30px; font-weight: 500; letter-spacing: .03em; }
.mh-about-motto { margin: 0; font-size: 13px; color: var(--mh-muted); letter-spacing: .05em; }
.mh-about-letter { max-width: 46em; margin: 30px auto; padding: 30px 34px; background: color-mix(in srgb, var(--mh-green) 5%, var(--mh-panel)); border: 1px solid var(--mh-line); }
.mh-about-letter p { margin: 0 0 14px; font-family: var(--mh-serif); font-size: 16px; line-height: 2; }
.mh-about-greet { font-size: 18px !important; font-weight: 500; }
.mh-about-letter a { color: var(--mh-green); }
.mh-about-sign { margin-top: 22px !important; text-align: right; font-size: 15px !important; }
.mh-about-sign span { display: block; margin-top: 2px; font-family: var(--mh-sans); font-size: 12px; color: var(--mh-muted); }
.mh-about-facts { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 26px; margin-top: 8px; }
.mh-about-fact h2 { margin: 0 0 8px; padding-top: 10px; border-top: 1px solid var(--mh-ink); font-family: var(--mh-sans); font-size: 12px; letter-spacing: .18em; color: var(--mh-green); font-weight: 600; }
.mh-about-fact p { margin: 0; font-size: 13px; line-height: 1.9; color: var(--mh-ink); }
.mh-about-fact a { color: var(--mh-green); }
@media (max-width: 800px) { .mh-about-facts { grid-template-columns: 1fr; gap: 14px; } .mh-about-letter { padding: 22px 18px; } }

/* --------------------------------------------------------------------------
   手记 — the owner's notebook, under the letter on 关于茉莉花.
   
   The brief was 「feelings and thoughts, genuineness, sometimes vulnerability」
   and 「not a system」. Everything below is subtraction: no card, no avatar,
   no title, no signature, no reply, no share, no count, no 「load more」. A
   date in the margin and the words. The only ornament in the whole block is
   one hairline running down the left of the text column, which exists so the
   dates have something to hang off and so a single entry still reads as the
   start of something.
   -------------------------------------------------------------------------- */

/* Measure, not width. 46em is the letter block's measure above it, so the two
   read as one column of writing rather than two sections that happen to be on
   the same page; the date gutter hangs to its left the way a dateline does. */
/* THE SAME BOX AS THE LETTER — 46em wide, 34px padding — so the notes sit in
   one column of writing with the intro rather than in a second, wider column
   beside it. Matching the letter's box is what makes the two read as one page
   instead of two components. */
/* FULL CANVAS NOW, NOT A 46em COLUMN. The notes alone at a readable measure
   left the right half of an 1100px page empty and the notebook read as thin
   (owner, 2026-08-08). The section takes the whole width; the two-column body
   below decides how it is spent. */
.mh-notes { box-sizing: border-box; width: 100%; margin: 46px 0 48px; }

/* NOTEBOOK over 站长手记, the head from the mockup the owner approved — and the
   same mono-kicker-then-title grammar every homepage band uses. */
.mh-notes-head { display: flex; align-items: baseline; gap: 14px; padding-bottom: 12px; border-bottom: 2px solid var(--mh-ink); }
.mh-notes-k { align-self: center; margin: 0; font-family: var(--mh-sans); font-size: 10px; font-weight: 600; letter-spacing: .22em; color: var(--mh-green); white-space: nowrap; }
.mh-notes-t { margin: 0; font-family: var(--mh-serif); font-size: 24px; font-weight: 700; letter-spacing: .06em; }
.mh-notes-x { margin: 0 0 0 auto; font-family: var(--mh-sans); font-size: 11px; letter-spacing: .12em; color: var(--mh-muted); }

/* Notes left, rail right. minmax(0, 46em) keeps the writing at the measure it
   had — widening prose to fill a page is how a personal page starts reading
   like a document — and the rail takes what the measure does not want. */
.mh-notes-body { display: grid; grid-template-columns: minmax(0, 46em) minmax(0, 1fr); gap: 0 52px; align-items: start; }

.mh-notes-list { margin: 0; padding-right: 34px; }

/* No rail: one centred column of writing, which is what the page was before the
   rail and is a legitimate look — a diary does not owe the page its full width.
   Emptying the rail must not silently reintroduce a half-blank page. */
.mh-notes-body.is-solo { grid-template-columns: minmax(0, 46em); justify-content: center; }
.mh-notes-body.is-solo .mh-notes-list { padding-right: 0; }

/* 92px gutter + 16px gap = the 108px added to the measure above. */
.mh-note { display: grid; grid-template-columns: 92px minmax(0, 1fr); gap: 0 16px; }

/* Above 900px the dateline HANGS OUT into the page margin, so the note text
   keeps the letter's full measure instead of being indented 108px narrower
   than the paragraph above it. Gated on width because below ~900px that
   negative margin would push the dates off the left edge of the screen. */
@media (min-width: 900px) {
  .mh-note { margin-left: -108px; }
}

/* The hairline is the TEXT COLUMN's left border, not a row border, so it runs
   unbroken from the first note to the last while the entry separators stop at
   it. That one detail is the difference between a notebook and a table. */
.mh-note-b { border-left: 1px solid var(--mh-line); padding: 22px 0 22px 20px; }
.mh-note + .mh-note .mh-note-b { border-top: 1px solid var(--mh-line); }
.mh-note-b p { margin: 0 0 12px; font-family: var(--mh-serif); font-size: 16px; line-height: 2; }
.mh-note-b p:last-child { margin-bottom: 0; }

/* 22px top padding on both columns puts the date's baseline on the first line
   of its entry, so it reads as the opening word rather than a floating label. */
.mh-note-d { display: block; padding-top: 24px; text-align: right; }
.mh-note-md { display: block; font-family: var(--mh-serif); font-size: 15px; color: var(--mh-ink); }
.mh-note-y { display: block; margin-top: 2px; font-family: var(--mh-sans); font-size: 10px; letter-spacing: .1em; color: var(--mh-muted); }

/* ------------------------------------------------------------------
   THE RAIL. Three blocks, each rendering nothing when it has no content, so
   the page never shows a heading over a gap. No ads, no news, nothing lifted
   from the notes — the left column is what he felt, the right is what he did
   and what he is in the middle of.
   ------------------------------------------------------------------ */
.mh-notes-rail { border-left: 1px solid var(--mh-line); padding-left: 34px; }
.mh-rail-b + .mh-rail-b { margin-top: 34px; padding-top: 30px; border-top: 1px solid var(--mh-line); }
.mh-rail-h { margin: 0 0 14px; font-family: var(--mh-sans); font-size: 11px; font-weight: 600; letter-spacing: .18em; color: var(--mh-green); }

/* 此刻 — label above value, so a long book title is not squeezed into half a
   narrow column. */
.mh-rail-dl { margin: 0; }
.mh-rail-dl dt { margin: 0; font-family: var(--mh-sans); font-size: 10.5px; letter-spacing: .1em; color: var(--mh-muted); }
.mh-rail-dl dd { margin: 2px 0 12px; font-family: var(--mh-serif); font-size: 15px; line-height: 1.65; }
.mh-rail-dl dd:last-child { margin-bottom: 0; }

/* 本站小事记 — a mono date in a fixed gutter so the dates form a column and the
   lines read as a record rather than as a paragraph list. */
.mh-rail-log-l { list-style: none; margin: 0; padding: 0; }
.mh-rail-log-l li { display: grid; grid-template-columns: 3.4em minmax(0, 1fr); gap: 0 10px; align-items: baseline; padding: 7px 0; border-bottom: 1px dotted var(--mh-line); }
.mh-rail-log-l li:last-child { border-bottom: 0; padding-bottom: 0; }
.mh-rail-log-l time { font-family: var(--mh-sans); font-size: 10.5px; letter-spacing: .04em; color: var(--mh-muted); font-variant-numeric: tabular-nums; }
.mh-rail-log-l span { font-size: 13.5px; line-height: 1.7; }

/* 我记着的一句话 — set larger than the notes it sits beside, because one line
   given room is the whole point of quoting it. */
.mh-rail-q { margin: 0; }
.mh-rail-q p { margin: 0; font-family: var(--mh-serif); font-size: 17px; line-height: 1.85; }
.mh-rail-q cite { display: block; margin-top: 10px; font-style: normal; font-family: var(--mh-sans); font-size: 11px; letter-spacing: .06em; color: var(--mh-muted); }
.mh-rail-q cite::before { content: "— "; }

@media (max-width: 900px) {
  /* The rail goes under the notes and its border moves to the top, because a
     left border on a full-width block is a stray vertical line. */
  .mh-notes-body { grid-template-columns: minmax(0, 1fr); gap: 38px; }
  .mh-notes-list { padding-right: 0; }
  .mh-notes-rail { border-left: 0; border-top: 1px solid var(--mh-ink); padding-left: 0; padding-top: 26px; }
}

@media (max-width: 680px) {
  /* No room for a margin at 375px, so the dateline moves above the note and
     the vertical rule goes away rather than becoming a 4px sliver. */
  .mh-note { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .mh-note-d { display: flex; align-items: baseline; gap: 8px; padding: 18px 0 0; text-align: left; }
  .mh-note-y { margin-top: 0; }
  .mh-note-b { border-left: 0; padding: 8px 0 18px; }
  .mh-note + .mh-note .mh-note-b { border-top: 0; }
  .mh-note + .mh-note .mh-note-d { border-top: 1px solid var(--mh-line); }
}
