/*
 * The right page: the sections of the issue, the cards, the chapter headers,
 * the contents, the subscribe card and the footer.
 */

/*
 * The column's margins, on whatever sits directly in it.
 *
 * `<main>` was added between the column and its sections so the site header and
 * the site footer could sit outside it and become `banner` and `contentinfo` —
 * HTML-AAM gives <header> and <footer> those roles only when they are not
 * inside main. That put one box between the column and everything in it, so the
 * rule has to name both levels; `.prom-main` itself is a bare wrapper and takes
 * none, which keeps the geometry byte-identical to what was measured before it
 * existed.
 */
.prom-page > *,
.prom-main > * {
	padding-left: var(--gut);
	padding-right: var(--pad);
}

.prom-main {
	padding-left: 0;
	padding-right: 0;
}

/* ---------- The opening ---------- */

.opening {
	padding-top: var(--seam-chapter);
	padding-bottom: var(--seam-chapter);
}

.opening__from {
	margin: 0 0 .8em;
	font-family: var(--serif);
	font-style: italic;
	font-size: 1rem;
	color: var(--ink-3);
}

/*
 * A deck, not a second headline. The cover states the story at display size on
 * the other half of the spread; this repeats it a step down, the way a standfirst
 * sits under a headline in print. At 3.6rem it was the same size as the cover
 * line and filled the page on its own.
 */
.opening__standfirst {
	max-width: 26ch;
	margin: 0 0 1em;
	font-family: var(--serif);
	font-size: clamp(1.7rem, 3.4cqi, 2.7rem);
	line-height: 1.08;
	letter-spacing: -.012em;
	font-variation-settings: "opsz" 72;
}

.opening__actions {
	display: flex;
	flex-wrap: wrap;
	/* Row gap tighter than column gap: wrapped actions are a list, not sections. */
	gap: 14px 28px;
	margin: 0;
}

/* ---------- Chapters ---------- */

.chapter-section {
	padding-top: var(--seam-chapter);
	padding-bottom: var(--seam-chapter);
}

/*
 * The chapter head wraps rather than running its "all of …" link past the right
 * edge, which it did at every width under 1200 — measured off-screen on the
 * front page at 1100, 820 and 390.
 */
.chapter-head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 10px 18px;
	margin-bottom: calc(var(--seam-chapter) * .6);
}

.chapter-head__all {
	display: inline-flex;
	align-items: center;
	flex: 0 1 auto;
	min-width: 0;
	min-height: 44px;
	margin-left: auto;
	white-space: nowrap;
	color: var(--ink-3);
	transition: color var(--move);
}

/*
 * "All of Prominent Fashion and Beauty" does not fit a narrow column on one
 * line, and nowrap made it run off the edge rather than wrap. Below the fold's
 * two-column width it sits on its own line, left-aligned, and wraps.
 *
 * This rule was written and did nothing: .chapter-head__all was declared twice
 * with the media query between them, so the second declaration's nowrap won on
 * source order and the link ran 96px past a 390px screen — inside .site, which
 * clips, so nothing overflowed the document and no check saw it. One rule now,
 * and the media query comes after it.
 */
@media (max-width: 900px) {
	.chapter-head__all {
		flex-basis: 100%;
		margin-left: 0;
		white-space: normal;
	}
}

.chapter-head__no {
	font-family: var(--serif);
	font-style: italic;
	font-size: 1.9rem;
	color: var(--ink-3);
}

.chapter-head__name {
	margin: 0;
	font-family: var(--sans);
	font-size: var(--label-lead);
	font-weight: 300;
	letter-spacing: .2em;
	text-transform: uppercase;
	line-height: 1.4;
}

.chapter-head__rule {
	flex: 1;
	height: 1px;
	background: var(--rule);
}


/* ---------- Cards ---------- */

.cards {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
	gap: clamp(20px, 3cqi, 40px);
}

/*
 * The card is its own container.
 *
 * `container-type` is a property, not an at-rule: CSSTidy deletes @container
 * blocks but keeps this and keeps the cqi units that read from it, which is why
 * the theme can size from a card without owning a rule the caching plugin will
 * throw away. Measured through both of W3TC's minifiers by css-check.php.
 */
.card {
	container-type: inline-size;
}

.card__frame {
	position: relative;
	aspect-ratio: 4 / 5;
	overflow: hidden;
	background: var(--paper-3);
	margin-bottom: 14px;
}

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

.card__title {
	margin: 0 0 .35em;

	/*
	 * The floor was 1.02rem, and 1.02rem is exactly what the design spec §3.2
	 * gives BODY TEXT. Because the cqi source is `.site`, that floor held
	 * unchanged from 320 all the way to 960 — every phone and every tablet — so
	 * at 390 a story headline measured 16.32px against a contents-list row at
	 * 17.60px. The headline introducing a story was 7% smaller than a line of
	 * the index beside it, and 1.02x the body copy it introduces. The front
	 * page read as a list of rubrics on a phone and as a magazine on a desktop.
	 *
	 * 1.24rem is 19.84px: 1.13x the largest thing it competes with on a phone,
	 * against 1.23x at 1280.
	 *
	 * The second defect was the source of the query unit, and it inverted the
	 * whole scale. The grid is repeat(auto-fit, minmax(min(220px, 100%), 1fr)),
	 * so a card gets NARROWER as the window widens and another column fits,
	 * while 1.7cqi read from `.site` got LARGER. Measured: a 459.2px card at a
	 * 1120px window carried 19.84px; a 290px card at 1512 carried 21.6px. A card
	 * 58% narrower took type 9% larger, and at 1920 the front page's 385px grid
	 * and its 243px grid read the same 21.6px because neither of them was ever
	 * being asked.
	 *
	 * Now the card is the container (see `.card` above) and the slope is fitted
	 * to the widths the grid actually produces — 19.84px in a 240px card,
	 * 24px in a 460px one, which is where the cap takes over.
	 */
	font-size: clamp(1.24rem, .956rem + 1.89cqi, 1.5rem);
	line-height: 1.1;
	letter-spacing: -.004em;
	transition: color var(--move);
}

.card__rubric {
	color: var(--ink-3);
}

/* ---------- Contents ---------- */

.contents {
	padding-top: var(--seam-section);
	padding-bottom: var(--seam-section);
	border-top: 1px solid var(--rule);
}

.contents__title {
	margin-bottom: 1em;
	font-size: 1.6rem;
}

.contents__list {
	margin: 0;
	padding: 0;
	list-style: none;
}

/*
 * Number, section, leader dots, blurb.
 *
 * Every track that can hold text is minmax(0, …). A bare `auto` or `1fr` track
 * is floored at its content's minimum width, and the blurb is a nowrap string
 * of up to eight words from the term description — so the row demanded 465px
 * inside a 390px phone and `.site`, which clips, quietly cut the contents list
 * off mid-word. Nothing overflowed the document, so no check saw it.
 */
.contents__row a {
	display: grid;
	grid-template-columns: 3ch minmax(0, auto) minmax(0, 1fr) minmax(0, auto);
	align-items: baseline;
	gap: 12px;
	min-height: 44px;
	padding: 13px 0;
	border-bottom: 1px solid var(--rule);
}

.contents__no {
	font-family: var(--serif);
	font-style: italic;
	color: var(--ink-3);
}

.contents__name {
	min-width: 0;
	overflow: hidden;
	font-size: 1.1rem;
	white-space: nowrap;
	text-overflow: ellipsis;
	transition: color var(--move), font-style var(--move);
}

/* Leader dots: a repeating gradient, 1px every 7px. */
.contents__leader {
	height: 1px;
	align-self: center;
	background-image: repeating-linear-gradient(90deg, var(--rule) 0 1px, transparent 1px 7px);
}

.contents__blurb {
	min-width: 0;
	font-size: var(--label);
	letter-spacing: .2em;
	text-transform: uppercase;
	color: var(--ink-3);
	/* One line, as a contents leader should be — but truncated, not overflowing. */
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}

/*
 * On a phone the row is the section name and nothing else. Leader dots between
 * two items that each want more room than the screen has are decoration at the
 * cost of the thing they decorate, and a blurb ellipsised to three characters
 * says less than no blurb at all.
 */
@media (max-width: 640px) {
	.contents__row a {
		grid-template-columns: 3ch minmax(0, 1fr);
	}

	.contents__leader,
	.contents__blurb {
		display: none;
	}
}

@media (hover: hover) and (pointer: fine) {
	.contents__row a:hover .contents__name {
		font-style: italic;
		color: var(--acc);
	}
}

/* ---------- Subscribe ---------- */

.subscribe {
	/*
	 * No padding of its own: `.subscribe__inner` is a bordered panel that
	 * already carries clamp(28px, 5cqi, 56px) on every side. Adding the
	 * section's padding on top of the panel's, and then the footer's on top of
	 * that, stacked three paddings into one seam — 86.2px above a 21px footer
	 * label on a phone, 4.08x its line box, and the worst gap on nearly every
	 * view at every width. The panel's own inset is the section's spacing.
	 */
	padding-top: 0;
	padding-bottom: 0;
	margin-top: var(--seam-section);
}

.subscribe__inner {
	position: relative;
	padding: clamp(28px, 5cqi, 56px);
	border: 1px solid var(--rule-2);
	text-align: center;
}

.subscribe__inner::before {
	content: "";
	position: absolute;
	inset: 7px;
	border: 1px solid var(--rule);
	pointer-events: none;
}

.subscribe__title {
	margin: 0 0 .5em;
	font-size: clamp(1.5rem, 3cqi, 2.2rem);
}

.subscribe__blurb {
	max-width: 44ch;
	margin: 0 auto 1.6em;
	color: var(--ink-2);
}

.subscribe__form {
	display: flex;
	flex-wrap: wrap;
	align-items: end;
	justify-content: center;
	gap: 20px;
}

.subscribe__label {
	flex: 0 0 100%;
	font-family: var(--sans);
	font-size: var(--label-lead);
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--ink-3);
}

.subscribe__field {
	flex: 1 1 260px;
	min-height: 44px;
	padding: 8px 0;
	font: inherit;
	color: inherit;
	background: none;
	border: 0;
	border-bottom: 1px solid var(--rule-2);
}

.subscribe__submit {
	min-height: 44px;
	padding: 11px 20px;
	font-family: var(--sans);
	font-size: var(--label);
	letter-spacing: .16em;
	text-transform: uppercase;
	border-bottom: 1px solid var(--rule-2);
}

/* ---------- Mailchimp for WordPress ---------- */

/*
 * THE PLUGIN DELIVERS; THE MAGAZINE DRESSES IT.
 *
 * `subscribe_provider = mc4wp` renders the plugin's own shortcode inside
 * `.subscribe`, so Mailchimp for WordPress keeps the submission — its nonce,
 * its validation, its API call, its double opt-in and its consent checkbox —
 * and none of that is reimplemented from the outside where a plugin update
 * would break it.
 *
 * What the magazine keeps is the composition. These follow MC4WP's real output:
 * a `.mc4wp-form` wrapping `.mc4wp-form-fields`, plain `input` elements rather
 * than classed ones, and `.mc4wp-alert` for what it says back. Only the
 * plugin's own class names and bare element selectors are used, so nothing here
 * depends on the owner's form markup being written a particular way — which
 * matters, because in MC4WP the form's markup is a field the owner edits.
 */
.subscribe__mc4wp .mc4wp-form-fields {
	display: flex;
	flex-wrap: wrap;
	align-items: end;
	justify-content: center;
	gap: 20px;
}

.subscribe__mc4wp label {
	flex: 0 0 100%;
	font-family: var(--sans);
	font-size: var(--label-lead);
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--ink-3);
}

.subscribe__mc4wp input[type="email"],
.subscribe__mc4wp input[type="text"] {
	flex: 1 1 260px;
	width: 100%;
	min-height: 44px;
	padding: 8px 0;
	font: inherit;
	color: inherit;
	background: none;
	border: 0;
	border-bottom: 1px solid var(--rule-2);
}

.subscribe__mc4wp input[type="submit"],
.subscribe__mc4wp button[type="submit"] {
	min-height: 44px;
	padding: 11px 20px;
	font-family: var(--sans);
	font-size: var(--label);
	letter-spacing: .16em;
	text-transform: uppercase;
	color: inherit;
	background: none;
	border: 0;
	border-bottom: 1px solid var(--rule-2);
	cursor: pointer;
}

/*
 * The consent checkbox, where the owner has added one. A flex row rather than
 * the plugin's stacked default, and NOT uppercased: it is a sentence a reader
 * has to actually read before agreeing to it.
 */
.subscribe__mc4wp input[type="checkbox"] + span,
.subscribe__mc4wp label:has( input[type="checkbox"] ) {
	flex: 0 0 100%;
	font-family: inherit;
	letter-spacing: normal;
	text-transform: none;
	color: var(--ink-2);
}

/*
 * What it says back — the plugin's own alert, in the magazine's voice.
 *
 * `--acc` is the magazine's accent, and it is the token that exists. The first
 * version of this rule said `var(--claret, inherit)`: a name nobody has ever
 * defined in this theme, so the fallback took it and an ERROR rendered in the
 * same ivory as a success. A reader who mistyped their address was told so in
 * the colour of good news. `css-check.php` passes a rule whose custom property
 * does not exist, because the browser does too — silently.
 */
.subscribe__mc4wp .mc4wp-alert {
	margin-block-start: 16px;
	font-family: var(--sans);
	font-size: var(--label);
	letter-spacing: .08em;
}

.subscribe__mc4wp .mc4wp-error {
	color: var(--acc);
}

/* ---------- Contact Form 7 ---------- */

/*
 * The theme creates three of these forms on setup, so their markup is the
 * theme's problem whether or not the theme wrote it. Unstyled, they rendered as
 * grey browser boxes with a default Send button on the contact, advertising and
 * submissions pages — three of the six pages the theme ships.
 *
 * These follow CF7's real output: a <p> per field holding a <label>, a <br>,
 * and a .wpcf7-form-control-wrap around the control. Only CF7's own class names
 * are used, so nothing here depends on the shortcode's markup being rewritten.
 */
.wpcf7 {
	max-width: 42rem;
	margin-top: var(--seam-section);
}

.wpcf7-form p {
	margin: 0 0 22px;
}

.wpcf7-form label {
	display: block;
	font-family: var(--sans);
	font-size: var(--label);
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--ink-3);
}

.wpcf7-form-control-wrap {
	display: block;
	margin-top: 8px;
}

.wpcf7-form-control {
	width: 100%;
	min-height: 48px;
	padding: 10px 0;
	font: inherit;
	font-size: 1.05rem;
	letter-spacing: 0;
	text-transform: none;
	color: var(--ink);
	background: none;
	border: 0;
	border-bottom: 1px solid var(--rule-2);
	border-radius: 0;
	appearance: none;
}

textarea.wpcf7-form-control {
	/*
	 * Six lines, not the ten Contact Form 7 writes into `rows`. Ten measured
	 * 331px on a 412px phone — a third of the screen given to an empty box,
	 * with the Send button pushed off it. `height`, not `min-height`: the rows
	 * attribute sets a height, so a minimum below it changes nothing. Dragging
	 * the corner still works, because that writes an inline height.
	 */
	height: 6lh;
	min-height: 0;
	padding: 12px 0;
	resize: vertical;
}

@media (max-width: 800px) {
	textarea.wpcf7-form-control {
		height: 5lh;
	}
}

.wpcf7-form-control::placeholder {
	color: var(--ink-3);
}

.wpcf7-form-control:focus {
	border-bottom-color: var(--acc);
}

/* The one control that is a button, not a field. */
.wpcf7-submit {
	width: auto;
	min-height: 48px;
	padding: 0 24px;
	font-family: var(--sans);
	font-size: var(--label);
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--paper);
	background: var(--ink);
	border: 0;
	cursor: pointer;
}

@media (hover: hover) and (pointer: fine) {
	.wpcf7-submit:hover {
		background: var(--acc);
		color: var(--acc-ink);
	}
}

/* Acceptance checkboxes are not full-width fields. */
.wpcf7-acceptance .wpcf7-list-item {
	margin: 0;
}

.wpcf7-acceptance .wpcf7-form-control {
	width: auto;
	min-height: 0;
	padding: 0;
	border: 0;
}

.wpcf7-list-item-label {
	font-size: var(--label);
	letter-spacing: 0;
	text-transform: none;
	color: var(--ink-2);
}

/* What CF7 says back. */
.wpcf7-not-valid-tip {
	margin-top: 8px;
	font-family: var(--sans);
	font-size: var(--label);
	letter-spacing: 0;
	text-transform: none;
	color: var(--acc);
}

/*
 * What the form says back, at the size of the form.
 *
 * Selectors matched to the plugin's, not shorter. Contact Form 7 writes
 * `.wpcf7 form .wpcf7-response-output`, three classes deep, and a bare
 * `.wpcf7-response-output` loses to it — so the theme's declarations sat in the
 * stylesheet doing nothing at all while the plugin drew the element.
 *
 * Measured on a live install with the plugin active, this is what it drew:
 *
 *   border: 2px solid #00a0d2, going #46b450 on success and #dc3232 on
 *   failure — WordPress-admin blue, green and red, in a London fashion
 *   magazine set in Instrument Serif;
 *   margin: 2em 0.5em 1em — the half-em sides are why the message measured
 *   603px inside a 620px form and lined up with nothing;
 *   font-size 15.20px against a field's 16.80px — a sentence about the form,
 *   set smaller than the form.
 *
 * A left rule rather than a box: it aligns with the fields, which in this
 * theme are rules and not boxes, and carries the accent when something is
 * wrong. The text colour is left inherited — measured at 16.74:1 in every
 * state, so there is nothing there to fix.
 */
.wpcf7 form .wpcf7-response-output {
	margin: 22px 0 0;
	padding: 2px 0 2px 16px;
	font-family: var(--sans);
	font-size: 1.05rem;
	line-height: 1.5;
	border: 0;
	border-left: 2px solid var(--rule-2);
}

.wpcf7 form.sent .wpcf7-response-output {
	border-left-color: var(--rule-2);
}

.wpcf7 form.spam .wpcf7-response-output,
.wpcf7 form.aborted .wpcf7-response-output,
.wpcf7 form.invalid .wpcf7-response-output,
.wpcf7 form.unaccepted .wpcf7-response-output,
.wpcf7 form.failed .wpcf7-response-output {
	border-left-color: var(--acc);
}

.wpcf7-spinner {
	margin-left: 12px;
}

/* ---------- Footer ---------- */

.footer {
	padding-top: var(--seam-quiet);
	padding-bottom: 24px;
	border-top: 1px solid var(--rule);
}

.footer__cols {
	display: grid;
	grid-template-columns: 1.5fr 1fr 1fr;
	gap: clamp(20px, 3cqi, 44px);
}

@media (max-width: 900px) {
	.footer__cols {
		grid-template-columns: 1fr;
	}
}

.footer__label {
	margin: 0 0 .9em;
	font-family: var(--sans);
	font-size: var(--label-lead);
	font-weight: 300;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--ink-3);

	/*
	 * "The magazine" broke after THE and set as two lines beside two headings
	 * that did not, so the three columns started at three different baselines.
	 * A two-word column heading is one line.
	 */
	text-wrap: nowrap;
}

.footer__blurb {
	max-width: 40ch;
	color: var(--ink-2);
}

.footer__list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.footer__list a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	padding: 10px 0;
	transition: color var(--move);
}

/*
 * The magazine's own pages, in the second register — §1.8/§16.
 *
 * The same rule the menu panel applies to the same links: furniture face, label
 * size, the quieter ink, and on a phone two to a row. The footer was 1,102px
 * tall at 390 and 526px of it was thirteen identical rows.
 */
.footer__col--pages .footer__list a {
	font-family: var(--sans);
	font-size: var(--label);
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--ink-2);
}

@media (max-width: 900px) {
	.footer__col--pages .footer__list {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		column-gap: 20px;
	}
}

/*
 * The mark at the foot of the page.
 *
 * It is the branding system's mark now, not a wordmark this file draws itself
 * (§A8, §A19) — so these rules size what `Branding\mark()` printed. The three
 * `.footer .brand__…` rules in plate.css set the mark at line height, which is
 * right in the bar and in the panel and wrong here, where it is the largest
 * piece of type on the page; the extra class is what outranks them.
 */
.footer__wordmark {
	margin: var(--seam-block) 0 20px;
}

.footer .brand--footer .brand__wordmark {
	display: block;
	width: 100%;
}

.footer .brand--footer .brand__wordmark svg {
	display: block;
	width: 100%;
	height: auto;
}

/*
 * An uploaded logotype is a drawing with its own proportions, so it is given a
 * height and keeps them. Stretching one to the width of the page — which is
 * what the wordmark does, because letterforms can be tracked out and a
 * photograph of a monogram cannot — would distort the owner's own file.
 */
/*
 * THE FOOTER'S SIZE IS THE FOOTER'S, NOT THE BAR'S.
 *
 * This used to be one fixed clamp, and the only size an owner could reach was
 * the bar's `--logo-h` — which the rule above overrides here anyway. So the mark
 * at the foot of the page, which is the largest piece of type on it and the
 * publication signing off, could not be set at all. `--foot-mark-max` is written
 * by `Branding\tokens()` from `Footer → Footer logotype size`; the fallback is
 * the clamp this theme shipped with, so a site that never opens the setting is
 * unchanged.
 */
.footer .brand--footer .brand__img {
	width: auto;
	height: auto;
	max-width: 100%;
	max-height: var(--foot-mark-max, clamp(48px, 7.5vw, 104px));
}

.footer__wordmark text {
	font-family: var(--serif);
	font-weight: 500;
	font-variation-settings: "opsz" 96;
	fill: var(--ink);
}

.footer__wordmark--foil text {
	fill: url(#prom-foil);
}

/*
 * The owner can switch the fill off, and the mark has to follow.
 *
 * `Branding\wordmark()` adds `brand__wordmark--foil` from the theme's own foil
 * flag, and the footer has a second control that says outline or plain. When
 * the two disagree the footer's is the one about this element.
 */
.footer__wordmark--ink .brand__wordmark--foil text {
	fill: var(--ink);
}

.footer__wordmark--outline .brand__wordmark--foil text,
.footer__wordmark--outline text {
	fill: none;
	stroke: var(--rule-2);
	stroke-width: 1;
}

.footer__wordmark--outline text {
	fill: none;
	stroke: var(--rule-2);
	stroke-width: 1;
}

.footer__bottom {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: 16px;
	padding-top: 16px;
	border-top: 1px solid var(--rule);
	font-family: var(--sans);
	font-size: var(--label);
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--ink-3);
}

/* ---------- Notices ---------- */

.notice {
	padding-top: var(--seam-section);
	padding-bottom: var(--seam-section);
}

.notice__title {
	font-size: clamp(1.8rem, 3.6cqi, 3rem);
}

.notice__text {
	max-width: 46ch;
	color: var(--ink-2);
}

.notice__actions {
	display: flex;
	gap: 28px;
}

/*
 * The magazine's accounts, at the foot of the page.
 *
 * Set as words in the furniture face rather than as icons: an icon set is
 * another request and another label to write, and the names read as part of
 * the magazine. 44px of height each, like every other target here.
 */
.footer__social {
	margin: var(--sp-50, 34px) 0 0;
}

.footer__social-list {
	display: flex;
	flex-wrap: wrap;
	gap: 0 var(--sp-50, 34px);
	margin: 0;
	padding: 0;
	list-style: none;
}

.footer__social-link {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	font-family: var(--sans);
	font-size: var(--label);
	font-weight: 400;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--ink-2);
	text-decoration: none;
	border-bottom: 1px solid transparent;
}

@media (hover: hover) and (pointer: fine) {
	.footer__social-link:hover {
		color: var(--ink);
		border-bottom-color: var(--rule);
	}
}

/* ---------- The menu ---------- */

/*
 * The bar used to be a strip of section links that dropped items as the column
 * narrowed, and on a 756px page most of them were already gone. Now the strip
 * is a courtesy and the button is the navigation.
 */

/*
 * SEARCH, THEN MENU, WITH ROOM BETWEEN THEM — §1.8/§6.
 *
 * Two uppercase words tracked at .16em, 10px apart, read as one string:
 * measured at 1280 the gap between the end of SEARCH and the start of MENU was
 * 10px against a 2.25px letter gap inside each word, so "SEARCH MENU" was four
 * times closer together than the parts of either word were far apart. They are
 * two controls and the rhythm has to say so.
 *
 * 28px between them, and 14px between the word MENU and its plate — so the
 * label belongs to the plate it names, and the two controls are clearly apart.
 * Below the spread the words are clipped away and the two glyphs sit 2px apart,
 * which is right: there the objects are 44 and 46px and their own edges are the
 * separation.
 */
.page-top__tools {
	display: flex;
	align-items: center;
	gap: 28px;
	flex: 0 0 auto;
}

/*
 * ---------- APPEARANCE, IN THE HEADER ROW — §1.9/§3 ----------
 *
 * The third control of the utility group: Appearance, Search, Menu, in that
 * order, on one visual axis with the logotype. Drawn as the search glyph is —
 * a hairline mark in a 44px target, no ground of its own — because these two
 * are peers and the trigger's filled plate is the one object that is not.
 *
 * WHICH MARK IS SHOWN IS THE STATE — §1.9.2/§7.
 *
 *   Auto     a screen on a stand: the device, which is what Auto follows
 *   Light    the sun
 *   Dark     the moon
 *
 * It was one circle at three fills — open, half, solid — and three fills of one
 * shape is a code a reader has to be taught. The owner's word for it was that it
 * is unreadable, which is the third time this magazine has been told so about
 * this control. Three DIFFERENT shapes, and ones the rest of the web already
 * uses, is the answer. `Helpers\mode_icon()` draws them, and the menu panel's
 * radio group draws the same three from the same function.
 *
 * All three are in the document and CSS shows one, so the control is correct in
 * the first painted frame rather than after a module has run. fold.js adds
 * `is-system` / `is-light` / `is-dark` and rewrites the accessible name.
 */
.page-top__mode {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 10px;
	min-height: var(--tap);
	padding: 0;
	font-family: var(--sans);
	font-size: var(--label);
	font-weight: 500;
	letter-spacing: .16em;
	text-transform: uppercase;

	/*
	 * `--ink-2`, NOT `inherit`.
	 *
	 * Search takes `--ink-2` from the rule it shares with the section links, and
	 * this took whatever the bar happened to be carrying. On the spread, where
	 * the header sits on the page's own paper and neither `--over` nor `--paper`
	 * applies, that came out `rgb(242,236,227)` beside Search's
	 * `rgb(173,165,157)` — two peers a thumb's width apart in two weights of
	 * ink, one reading as primary and one as secondary.
	 *
	 * Over a cover both are rebound to the measured token together; here they
	 * agree because they name the same one.
	 */
	color: var(--ink-2);
	border: 0;
	border-radius: var(--edge);
	background: none;
	transition: color var(--move-quick);
}

/*
 * On the spread the mark carries the state's NAME beside it — Auto, Light,
 * Dark — because there is room and a word is not a picture somebody has to
 * learn. Below the spread the word is clipped away with Search's and Menu's and
 * the three marks stand alone, which is the row the owner asked for: "можно
 * использовать только icons, если значения понятны и есть accessible labels".
 * The accessible name carries the whole sentence at both sizes.
 */
.page-top__mode .page-top__glyph {
	display: inline-flex;
}

.page-top__mode[hidden] {
	display: none;
}

.page-top__mode .page-top__glyph {
	line-height: 0;
}

/*
 * One mark at a time. Written as `display` rules rather than by drawing the SVG
 * from script: a control whose picture arrives with the module is a control that
 * is wrong for the first few hundred milliseconds of every page.
 *
 * The default before fold.js has run is the screen — Auto — which is the state
 * the server has already put on `<html>` for a reader who has chosen nothing.
 */
.page-top__mode .mode-icon {
	display: none;
}

.page-top__mode .mode-icon--system,
.page-top__mode.is-system .mode-icon--system,
.page-top__mode.is-light .mode-icon--light,
.page-top__mode.is-dark .mode-icon--dark {
	display: block;
}

.page-top__mode.is-light .mode-icon--system,
.page-top__mode.is-dark .mode-icon--system {
	display: none;
}

@media (hover: hover) and (pointer: fine) {
	.page-top__mode:hover {
		color: var(--acc);
	}
}

/*
 * ---------- THE LIST OF THREE — §1.9.2/§8 ----------
 *
 * A CHOICE, NOT A CYCLE
 *
 * The trigger opened nothing before: it stepped Auto → Light → Dark → Auto, and
 * a reader could only learn what the next press did by making it. "Не
 * использовать icon-only cycle, который заставляет пользователя угадывать
 * следующее состояние."
 *
 * So: a small panel under the trigger, titled, with the three states set out —
 * each with its own mark AND its own word, at every width. The trigger may be
 * icon-only on a phone; the list never is.
 *
 * Drawn as the magazine's other surfaces are: square corners, one hairline rule,
 * the paper of the edition in force. It is `position: absolute` against
 * `.page-top__appearance` rather than a `popover`, because W3 Total Cache's
 * CSSTidy has been measured deleting rules it does not recognise and
 * `:popover-open` is exactly that shape of selector — a panel that opens and
 * never closes is a worse failure than a panel positioned by hand.
 */
.page-top__appearance {
	position: relative;
	display: inline-flex;
}

.appearance-pop {
	position: absolute;
	top: calc(100% + 10px);
	right: 0;
	z-index: 70;
	min-width: 172px;
	padding: 12px 0 6px;
	border: 1px solid var(--rule);
	border-radius: var(--edge);
	background: var(--paper);
	box-shadow: 0 12px 32px rgba(0, 0, 0, .16);
}

.appearance-pop[hidden] {
	display: none;
}

.appearance-pop__title {
	margin: 0 16px 8px;
	font-family: var(--sans);
	font-size: var(--label-fine, .72rem);
	font-weight: 500;
	letter-spacing: var(--label-track, .26em);
	text-transform: uppercase;
	color: var(--ink-3, var(--ink-2));
}

.appearance-pop__list {
	display: flex;
	flex-direction: column;
}

/*
 * Icon AND word, and the word is not clipped at any width — that is the whole
 * point of the panel. The row is a 44px target like every other control in the
 * group.
 */
.appearance-pop__option {
	display: flex;
	align-items: center;
	gap: 12px;
	min-height: var(--tap);
	padding: 8px 16px;
	font-family: var(--sans);
	font-size: var(--label);
	font-weight: 500;
	letter-spacing: .16em;
	text-transform: uppercase;
	text-align: left;
	color: var(--ink-2);
	border: 0;
	background: none;
	transition: color var(--move-quick), background-color var(--move-quick);
}

.appearance-pop__option .mode-icon {
	flex: 0 0 auto;
}

.appearance-pop__option.is-on {
	color: var(--ink);
}

/*
 * The state in force wears the accent rule at its start — the same mark a
 * current section link wears in the row below, so "you are here" is one idea
 * across the whole header.
 */
.appearance-pop__option.is-on::before {
	content: "";
	position: absolute;
	left: 0;
	width: 3px;
	height: 20px;
	background: var(--acc);
}

.appearance-pop__option {
	position: relative;
}

@media (hover: hover) and (pointer: fine) {
	.appearance-pop__option:hover {
		color: var(--ink);
		background-color: var(--sheet, rgba(0, 0, 0, .04));
	}
}

/*
 * ---------- THE TRIGGER, DRAWN AS PROMINENT'S — §1.8/§2 ----------
 *
 * WHAT WAS BORROWED, AND WHAT IS BEING GIVEN BACK
 *
 * 1.6.0 took the mechanic from the theme this magazine came from and took its
 * FORM with it: a 46px filled CIRCLE with three 2px slabs across it. The
 * mechanic was worth having — an object on the photograph rather than a glyph
 * laid over it, so a picture cannot swallow the control, and the same object
 * becomes the close — and it is kept. The circle was not ours.
 *
 * This magazine has no round furniture. Its rules are straight, its plates are
 * square, its corners are square, and `--edge: 0` says so once for the whole
 * product. The two round things it does draw — the season stamp and the
 * end-of-story seal — are round because a stamp and a seal are round. A
 * navigation control is neither.
 *
 * SO: A PLATE, NOT A DISC.
 *
 *   form     a 46px square with square corners, the shape of every other
 *            surface in the magazine
 *   backing  the measured ground, as before — but now with a keyline in the
 *            measured ink at 34%, so the plate has an EDGE on a photograph
 *            whose tone happens to match its fill. The fill-only disc had none,
 *            and a cream disc on a cream sky is a cream rectangle of nothing.
 *   stroke   three rules at 1.5px, not 2px slabs: the hairline register the
 *            chapter rules, the credit rail and the contents leaders are all
 *            set in
 *   hover    the keyline comes to full strength and the middle rule draws back
 *            to two thirds — the mark opens, in place, with no scale and no
 *            shadow. §17: "не должно быть избыточных bounce, scale everywhere".
 *   press    the shared accent film, the same as every other control
 *   motion   `--move`, the same as every other control
 *
 * The COLOUR was already ours and stays: the tone engine fills the plate with
 * the token the sampler chose for the `nav` slot on the region of the
 * photograph the button is actually over, and the rules take `--on-nav-*`,
 * measured to read on that fill.
 */
.page-top__menu {
	display: inline-flex;
	align-items: center;
	gap: 14px;
	min-height: 44px;
	padding: 0;
	font-family: var(--sans);
	font-size: var(--label);
	font-weight: 500;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--ink);
	border: 0;
	background: none;
}

.page-top__menu-rules {
	display: grid;
	place-content: center;
	gap: 5px;
	width: 46px;
	height: 46px;
	border-radius: var(--edge);

	/*
	 * On the page's own paper the plate is the edition's ink; over a photograph
	 * the two properties below are rebound to the measured pair. `--ink` and
	 * `--paper` rather than a fixed colour so the Ivory and Noir editions each
	 * get their own, and so an owner's palette reaches this too.
	 */
	background: var(--trigger-ground, var(--ink));
	color: var(--trigger-ink, var(--paper));

	/*
	 * The keyline. `currentColor` is the plate's own rules, so the edge is
	 * always the colour measured to read on this plate's own fill, whatever the
	 * photograph under it turned out to be.
	 */
	box-shadow: inset 0 0 0 var(--hair) color-mix(in oklab, currentColor 34%, transparent);
	transition: box-shadow var(--move);
}

.page-top__menu-rules i {
	display: block;
	width: 18px;
	height: 1.5px;
	background: currentColor;

	/*
	 * The morph into a cross. `transform` and `opacity` only — no layout, so
	 * nothing on the page moves when the menu opens, which is §9's "page не
	 * прыгает" and this project's CLS budget.
	 */
	transition: transform var(--move), opacity var(--move-quick), width var(--move);
}

/*
 * The same button closes it, and it says so.
 *
 * Anymag's does this and it is the reason its menu reads as one control rather
 * than two: the thing you pressed to open it is still under your thumb, and it
 * is now an x. `aria-expanded` is already on the button for assistive
 * technology, so the drawing follows the state rather than a second class.
 */
.page-top__menu[aria-expanded="true"] .page-top__menu-rules i:nth-child(1) {
	transform: translateY(7px) rotate(-45deg);
}

.page-top__menu[aria-expanded="true"] .page-top__menu-rules i:nth-child(2) {
	opacity: 0;
}

.page-top__menu[aria-expanded="true"] .page-top__menu-rules i:nth-child(3) {
	transform: translateY(-7px) rotate(45deg);
}

@media (prefers-reduced-motion: reduce) {
	.page-top__menu-rules i {
		transition: none;
	}
}

@media (hover: hover) and (pointer: fine) {
	/*
	 * THE MARK OPENS; THE PLATE DOES NOT MOVE.
	 *
	 * 1.6.0 grew the disc by 6% on hover, which is the one gesture §17 names —
	 * "scale everywhere" — and on a control pinned to the header's right edge a
	 * scale is also 1.4px of movement towards the screen's corner.
	 *
	 * Instead the plate's keyline comes to full strength and the middle rule
	 * draws back to two thirds of its length. Nothing moves, nothing resizes,
	 * and the change is in the mark itself rather than in the box around it.
	 * Inverting the fill was the other candidate and is wrong for the same
	 * reason it always was: it would swap the two measured colours for each
	 * other and hand the reader the pair the sampler had already rejected.
	 */
	.page-top__menu:hover .page-top__menu-rules {
		box-shadow: inset 0 0 0 var(--hair) currentColor;
	}

	.page-top__menu:hover .page-top__menu-rules i:nth-child(2) {
		width: 12px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.page-top__menu-rules {
		transition: none;
	}
}

/*
 * A PRESS HAS TO LAND ON THE PLATE, NOT ON THE BOX BEHIND IT.
 *
 * base.css puts the accent film on the control itself, and the control here is
 * a transparent `<button>` whose only visible object is this child. While the
 * plate was a CIRCLE the film still showed in the four corners the circle did
 * not cover — measured as a pass by accident. Square it, and the plate covers
 * the button exactly: verify.mjs came back "1 of 9 draw nothing:
 * .page-top__menu 0%/0" on four views, which is a control that acknowledges a
 * thumb by navigating and in no other way.
 *
 * `currentColor` for the same reason `.action--solid` uses it: the plate's ink
 * is by construction the colour that reads on the plate's own ground, wherever
 * the sampler put it.
 */
.site .page-top__menu:active .page-top__menu-rules,
.site .menu-panel__close:active span[aria-hidden] {
	background-image: linear-gradient(
		color-mix(in oklab, currentColor 18%, transparent),
		color-mix(in oklab, currentColor 18%, transparent)
	);
}

/*
 * ---------- The narrow bar's two controls ----------
 *
 * WHAT THE OWNER REJECTED
 *
 * On a 390px phone the bar carried two boxed words — SEARCH, and a bordered
 * [≡ MENU] — set in 16%-tracked uppercase. Measured on this build at 390px:
 * the pair took 214px of a 358px bar, the logotype was left 92px, and the
 * result reads as a plugin's toolbar rather than as a magazine's masthead.
 *
 * §A6: a compact hamburger, integrated with the masthead, with the logo
 * clearly visible and a touch target that is still 44px. So below the spread
 * the words become their glyphs, the box around the menu goes, and the space
 * they were using goes back to the mark.
 *
 * The words are still in the markup and are still the accessible name — this
 * is `clip-path`, not `display: none`, so the button announces "Search" and
 * "Menu" exactly as it did.
 */
.page-top__glyph {
	display: none;
	align-items: center;
	justify-content: center;
	line-height: 0;
}

@media (max-width: 1120px), (pointer: coarse), (pointer: none), (hover: none) {
	.page-top__glyph {
		display: inline-flex;
	}

	/*
	 * The same values as `.screen-reader-text` in critical.css, plus the two
	 * that make it stay inside the control.
	 *
	 * Without `inset: 0` an absolutely positioned box with no offsets sits at
	 * its STATIC position — which here is after the glyph, inside a 44px
	 * button, so the 1px box landed 50 and 70px outside its own control.
	 * verify.mjs's clipping check caught it on eight fixtures at two widths:
	 * `page-top__word +70px`. It is one pixel and invisible either way, and it
	 * is also the kind of thing that means a focus ring is drawn in the wrong
	 * place the day somebody makes the word focusable.
	 */
	.page-top__word {
		position: absolute;
		inset: 0;
		width: 1px;
		height: 1px;
		margin: 0;
		padding: 0;
		overflow: hidden;
		clip-path: inset(50%);
		white-space: nowrap;
		border: 0;
	}

	.page-top__search,
	.page-top__mode,
	.page-top__menu {
		position: relative;
		display: inline-flex;
		align-items: center;
		justify-content: center;
		min-height: 44px;
		padding: 0;
		border: 0;
		background: none;
		color: var(--ink);
	}

	.page-top__search,
	.page-top__mode {
		width: 44px;
		border-bottom: 0;
	}

	/*
	 * ON A PHONE THE DISC IS THE WHOLE CONTROL.
	 *
	 * This used to be a 44px square with `background: none` and three 1px
	 * hairlines in `currentColor` — "a control a thumb can hit and an eye can
	 * ignore", which was written about a bar on the magazine's own paper and is
	 * the wrong idea entirely over a photograph. The owner reported the
	 * hamburger as lost on the picture twice, and the original Anymag says why:
	 * its trigger is a filled circle, so there is nothing for a photograph to
	 * swallow.
	 *
	 * The word MENU is already clipped away here, so the disc IS the button and
	 * the 46px circle is the 44px target with two pixels to spare.
	 */
	.page-top__menu {
		width: 46px;
	}

	.page-top__menu-rules {
		width: 46px;
		height: 46px;
		gap: 5px;
	}

	.page-top__menu-rules i {
		width: 18px;
		height: 2px;
		background: currentColor;
	}

	/*
	 * The mark takes its own size, not the room left over.
	 *
	 * It used to be `flex: 1 1 auto` — "the mark takes the room back" — which
	 * was right when the bar was one flex row and the mark was competing with
	 * three controls for it. It is wrong now: the anchor is a grid column of
	 * its own, so there is no competition, and a stretched mark cannot be
	 * placed. A cover set to Top centre or Top right needs the mark to be its
	 * own width inside the anchor for `justify-content` to have anything to
	 * move. `1` shrinks it on a narrow screen; `0` basis is its natural size.
	 */
	.page-top__brand {
		flex: 0 1 auto;
		min-width: 0;
	}

	.page-top__tools {
		gap: 2px;
	}
}

/* ---------- The panel ---------- */

/*
 * A class with `display: grid` beats the browser's own `[hidden]{display:none}`,
 * so the closed panel stayed in the layout and swallowed every click on the
 * page beneath it. Stated explicitly.
 */
.menu-panel[hidden] {
	display: none;
}

/*
 * The panel is a child of the column, so `.prom-page > *` at the top of this
 * file was padding it — measured at 390 as a sheet running 20..371 inside a
 * 390px overlay, and at 1440 as one ending 49px short of the screen. A
 * full-screen overlay with the page's own margins on it is not a full-screen
 * overlay, and it is why the close disc could not land on the trigger's pixels.
 * Same specificity trick as `.prom-page > .page-top` in critical.css.
 */
.prom-page > .menu-panel {
	padding-right: 0;
	padding-left: 0;
}

.menu-panel {
	position: fixed;
	inset: 0;
	z-index: 90;
	display: grid;
	justify-items: end;
	background: rgba(8, 7, 7, .46);
	opacity: 0;
	transition: opacity var(--move);
}

.menu-panel.is-open {
	opacity: 1;
}

.menu-panel__sheet {
	--focus: var(--acc);

	display: flex;
	flex-direction: column;
	gap: clamp(22px, 4vh, 40px);
	width: min(560px, 100%);
	height: 100%;

	/*
	 * THE PANEL'S TOP-RIGHT CORNER IS THE HEADER'S TOP-RIGHT CORNER.
	 *
	 * `--trigger-y` down and `--bar-edge` in, the two numbers the bar row uses,
	 * so the close disc — the last item in the head row — lands on exactly the
	 * pixels the trigger occupied. Measured on 1.6.0 it did not: the disc moved
	 * from (320,8) to (305,20) on a phone and from (1370,15) to (1301,44) at
	 * 1440, so opening the menu moved the control out from under the thumb that
	 * had just pressed it. In the original Anymag the button does not go
	 * anywhere at all, and that is the mechanic being adapted.
	 *
	 * The left and bottom keep the panel's own generous margin: this is a sheet
	 * of the magazine, not a toolbar.
	 */
	padding: var(--trigger-y) var(--bar-edge) clamp(20px, 4vw, 44px) clamp(20px, 4vw, 44px);
	overflow-y: auto;
	overscroll-behavior: contain;
	background: var(--paper);
	border-left: 1px solid var(--rule);
	transform: translateX(4%);
	transition: transform var(--move-slow);
}

.menu-panel.is-open .menu-panel__sheet {
	transform: none;
}

/*
 * Sticky, so the close stays where the trigger was however far down the panel
 * the reader has scrolled — sixteen links is more than one screen on a phone,
 * and a close button that scrolls away is a modal with no way out but Escape.
 */
.menu-panel__head {
	position: sticky;
	top: 0;
	z-index: 1;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 18px;
	background: var(--paper);
}

.menu-panel__mark {
	font-family: var(--serif);
	font-size: 1.35rem;
	letter-spacing: .04em;
}

/*
 * THE CLOSE IS THE TRIGGER, TURNED INTO A CROSS.
 *
 * In the original Anymag the button you pressed to open the menu does not go
 * anywhere: it stays in its corner, its three bars rotate into an x, and that
 * one object is the whole control. It is the reason that menu reads as
 * understandable rather than as two separate buttons, and it is the mechanic
 * this release is adapting.
 *
 * Ours cannot literally be the same DOM node — the panel is a modal dialog and
 * its close has to be inside it for the focus trap and for `aria-modal` to mean
 * anything — so it is the same OBJECT instead: the same 46px disc, the same
 * fill, the same corner, carrying a cross. Reading order and position both say
 * "the button became an x", and the accessibility tree still gets a dialog with
 * its own close button.
 *
 * The word rides beside it on the spread and is clipped away on a phone,
 * exactly as the trigger's MENU is, so the two are mirror images at both sizes.
 */
.menu-panel__close {
	display: inline-flex;
	align-items: center;
	gap: 12px;
	min-height: 46px;
	padding: 0;
	font-family: var(--sans);
	font-size: var(--label);
	font-weight: 500;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--ink);
	border: 0;
	background: none;
}

/*
 * The same plate as the trigger — §1.8/§2.
 *
 * Same 46px square, same square corners, same keyline, same hover: the keyline
 * comes to full strength and nothing moves. It has to be the same object, in
 * the same place, or the mechanic this whole control is built on — press it,
 * and it is now an x — stops reading as one thing.
 */
.menu-panel__close span[aria-hidden] {
	display: grid;
	place-content: center;
	width: 46px;
	height: 46px;
	border-radius: var(--edge);
	background: var(--ink);
	color: var(--on-ink, var(--paper));
	font-size: 1.5rem;
	line-height: 1;
	box-shadow: inset 0 0 0 var(--hair) color-mix(in oklab, currentColor 34%, transparent);
	transition: box-shadow var(--move);
}

@media (hover: hover) and (pointer: fine) {
	.menu-panel__close:hover span[aria-hidden] {
		box-shadow: inset 0 0 0 var(--hair) currentColor;
	}
}

@media (prefers-reduced-motion: reduce) {
	.menu-panel__close span[aria-hidden] {
		transition: none;
	}
}

@media (max-width: 1120px), (pointer: coarse), (pointer: none), (hover: none) {
	/* Same values as `.screen-reader-text`; see the note on `.page-top__word`. */
	.menu-panel__close-word {
		position: absolute;
		width: 1px;
		height: 1px;
		margin: 0;
		padding: 0;
		overflow: hidden;
		clip-path: inset(50%);
		white-space: nowrap;
		border: 0;
	}
}

/*
 * THE WAY INTO THE SEARCH, NOT A SECOND SEARCH — §1.8/§3.
 *
 * This was a field, a label and a submit button of its own: a reader who
 * searched from the menu got no suggestions, no photographs and a full page
 * load, while one who searched from the header got the overlay. One search now,
 * two ways in, and this is one of them — drawn as a row, at the panel's own
 * reading size, so it reads as the first thing in the menu rather than as a form
 * embedded in it.
 */
.menu-panel__search {
	display: flex;
	align-items: center;
	gap: 14px;
	min-height: 56px;
	padding: 0 16px;
	font-family: var(--sans);
	font-size: var(--label);
	font-weight: 500;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--ink);
	border: 1px solid var(--rule-2);
	transition: color var(--move), border-color var(--move);
}

.menu-panel__search-glyph {
	display: flex;
	flex: 0 0 auto;
	line-height: 0;
	color: var(--acc);
}

@media (hover: hover) and (pointer: fine) {
	.menu-panel__search:hover {
		color: var(--acc);
		border-color: var(--acc);
	}
}

/*
 * get_search_form(), which the theme renders on the 404 page and WordPress
 * renders from the search block and widget.
 *
 * searchform.php had four classes and not one rule anywhere in the theme: the
 * field came out as a raw browser control — 13.3px Arial, white on grey, a 2px
 * inset border — in a magazine set in Bodoni and Jost. It is the same defect as
 * the logo: a template written and never looked at. So it wears the panel's
 * search dress, which is the one a reader has already seen.
 */
.search-form {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	align-items: end;
	gap: 10px;
}

.search-form__label {
	grid-column: 1 / -1;
	font-family: var(--sans);
	font-size: var(--label);
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--ink-3);
}

.search-form__field {
	min-width: 0;
	min-height: 48px;
	padding: 10px 0;
	font: inherit;
	font-size: 1.05rem;
	color: var(--ink);
	background: none;
	border: 0;
	border-bottom: 1px solid var(--rule-2);
	border-radius: 0;
	/* Safari draws a rounded, shaded capsule for type="search" otherwise. */
	appearance: none;
}

.search-form__field::placeholder {
	color: var(--ink-3);
}

.search-form__field::-webkit-search-cancel-button {
	appearance: none;
}

.search-form__submit {
	min-height: 48px;
	padding: 0 18px;
	font-family: var(--sans);
	font-size: var(--label);
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--paper);
	background: var(--ink);
	border: 0;
}

/* The two columns of links */

.menu-panel__cols {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: clamp(20px, 4vw, 40px);
}

.menu-panel__label {
	margin: 0 0 14px;
	padding-bottom: 10px;
	font-family: var(--sans);
	font-size: var(--label-lead);
	font-weight: 500;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--ink-3);
	border-bottom: 1px solid var(--rule);
}

.menu-panel__list,
.menu-panel__col > ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

.menu-panel__list li,
.menu-panel__col > ul li {
	border-bottom: 1px solid var(--rule);
}

.menu-panel__list a,
.menu-panel__col > ul a {
	display: flex;
	align-items: center;
	min-height: 52px;
	font-family: var(--serif);
	font-size: 1.14rem;
	line-height: 1.24;
	color: var(--ink);
}

@media (hover: hover) and (pointer: fine) {
	.menu-panel__list a:hover,
	.menu-panel__col > ul a:hover {
		color: var(--acc);
	}
}

/*
 * The magazine's own pages, in the second register — §1.8/§15.
 *
 * Furniture face, label size, and the quieter ink. The row keeps its 44px, so
 * this is a change of weight rather than of reach: a reader is never asked to
 * hit a smaller thing because it matters less.
 */
.menu-panel__col--pages .menu-panel__list a,
.menu-panel__col--pages > ul a {
	min-height: 44px;
	font-family: var(--sans);
	font-size: var(--label);
	font-weight: 400;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--ink-2);
}

/* Where the magazine also is. Names, not icons — see the note in the template. */
.menu-panel__social-list {
	display: flex;
	flex-wrap: wrap;
	gap: 4px 26px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.menu-panel__social-link {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	font-family: var(--sans);
	font-size: var(--label-fine);
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--ink-3);
	transition: color var(--move-quick);
}

@media (hover: hover) and (pointer: fine) {
	.menu-panel__social-link:hover {
		color: var(--acc);
	}
}

/*
 * ---------- APPEARANCE, AS A SEGMENTED CONTROL — §1.8/§5 ----------
 *
 * WHAT IT REPLACES
 *
 * A 26px half-filled disc in the header with no words on it, and a button in
 * this panel that said "Edition · Noir" and flipped between two states. The
 * owner's §5 is exact about both faults: the control was "непонятным значком"
 * beside Search, and a two-state toggle cannot express Auto — a reader could not
 * hand the decision back to their own device.
 *
 * Three named states in one frame, the middle one carrying the hairlines on both
 * sides, so it reads as one control with three positions rather than as three
 * buttons that happen to be adjacent. The chosen one is filled: the magazine's
 * own ink on its own paper, which is the same figure/ground the trigger disc and
 * `.action--solid` use, so the reader has seen this object before.
 */
.menu-panel__foot {
	margin-top: auto;
	padding-top: 20px;
	border-top: var(--hair) solid var(--rule);
}

.switch {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: 1fr;
	border: var(--hair) solid var(--rule-2);
	border-radius: var(--edge);
}

/*
 * Icon and word, in that order, laid out as a row — §1.9.2/§7.
 *
 * The same three marks the header's list draws, from the same
 * `Helpers\mode_icon()`, so a reader who learns the sun in one place has learnt
 * it in the other. `gap` rather than a margin on the glyph, so an option with
 * no icon — which cannot happen today, and could tomorrow — still centres.
 */
.switch__option {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	min-height: 48px;
	padding: 0 10px;
	font-family: var(--sans);
	font-size: var(--label);
	font-weight: 500;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--ink-2);
	background: none;
	border: 0;
	border-radius: var(--edge);
	transition: color var(--move-quick), background-color var(--move-quick);
}

.switch__option .mode-icon {
	flex: 0 0 auto;
}

/*
 * The dividers are the middle option's own edges, so there is one hairline
 * between each pair and none at the ends — where the frame already draws one.
 */
.switch__option + .switch__option {
	border-left: var(--hair) solid var(--rule);
}

.switch__option.is-on {
	color: var(--on-ink, var(--paper));
	background: var(--ink);
}

@media (hover: hover) and (pointer: fine) {
	.switch__option:not(.is-on):hover {
		color: var(--ink);
		background: var(--paper-3);
	}
}

/*
 * The ring is drawn INSIDE the frame, not around the segment.
 *
 * A radio group is one tab stop and the arrow keys move within it, so the thing
 * with the keyboard is one third of a bordered strip. An `outline-offset` of 0
 * would put the ring exactly on the frame's own hairline on the two end
 * segments; a negative offset draws it just inside, where it belongs to the
 * segment and is still clear of the divider. Written as an outline rather than
 * as a `:has()` on the frame: this theme has been caught losing newer selectors
 * to CSSTidy, and a focus indicator is not a thing to gamble on a minifier.
 */
.switch__option:focus-visible {
	outline: 2px solid var(--focus);
	outline-offset: -3px;
}

.menu-panel__note {
	margin: 12px 0 0;
	font-size: var(--copy-small);
	line-height: 1.5;
	color: var(--ink-3);
}

@media (max-width: 560px) {
	.menu-panel__cols {
		grid-template-columns: minmax(0, 1fr);
	}

	/*
	 * On one column the sixteen rows are a scroll and a half, and the pages are
	 * the half. Two to a row: the same links, the same targets, 200px less
	 * panel, and the sections keep the full measure they deserve.
	 */
	.menu-panel__col--pages .menu-panel__list,
	.menu-panel__col--pages > ul {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		column-gap: 20px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.menu-panel,
	.menu-panel__sheet {
		transition: none;
	}
}

/*
 * ---------- THE SEARCH OVERLAY — §1.8/§3, §1.8/§4, §1.8/§20 ----------
 *
 * WHAT IT IS
 *
 * A sheet that comes down from the top of the screen with one large field on it
 * and the archive underneath. It is the magazine's search desk: a reader asks,
 * and the answers are set as small entries with their photograph, their section
 * and their date — the shape of a contents page, not of a dropdown.
 *
 * IT COMES DOWN, IT DOES NOT COVER
 *
 * A full-screen search is a modal that has taken the whole magazine away. This
 * one is a sheet against the top edge with the page dimmed behind it, so a
 * reader can still see where they were and Escape puts them straight back. On a
 * phone it is the whole width; on a desktop it is a column of the same measure
 * as the magazine's own reading column, centred.
 *
 * NOTHING MOVES WHEN THE ANSWER ARRIVES — the layout half of §20
 *
 * The results box reserves its height in the same place whether it is empty,
 * busy or full: `min-height` on the box rather than height from its contents. So
 * the field, the hint and the sheet's edges do not move between the reader's
 * second keystroke and the eighth result, which is the layout shift a live
 * search usually ships with.
 */
.search-panel[hidden] {
	display: none;
}

/* Same reason as `.prom-page > .menu-panel` above: an overlay has no margins. */
.prom-page > .search-panel {
	padding-right: 0;
	padding-left: 0;
}

.search-panel {
	position: fixed;
	inset: 0;
	z-index: 95;
	display: grid;
	align-content: start;
	justify-items: center;
	background: rgba(8, 7, 7, .52);
	opacity: 0;
	transition: opacity var(--move);

	/*
	 * And follow the visible viewport when there is one to follow.
	 *
	 * `--seen-y` is how far a soft keyboard has pushed the visible area down
	 * the page — iOS scrolls the document to keep the caret in view — so
	 * without it the panel's own top edge is above the screen and the field is
	 * the first thing to go. Both are declared after `inset` so they win, and
	 * both are absent until search.js writes them, which means every browser
	 * without `visualViewport` gets the `inset: 0` it always had.
	 */
	top: var(--seen-y, 0);
	height: var(--seen-h, auto);
}

.search-panel.is-open {
	opacity: 1;
}

/*
 * THE FIELD DOES NOT SCROLL AWAY AND NEITHER DOES "VIEW ALL".
 *
 * The sheet was one scrolling box, so eight results pushed the field, the hint
 * and the "View all 231 results" line off the top and the bottom of a 390x844
 * screen: a reader who scrolled to the sixth suggestion could no longer see
 * what they had typed, and the one control that reaches the rest of the archive
 * was below every one of them.
 *
 * The sheet is a column with a fixed head and a scrolling middle: the row, the
 * hint and the all-results line stay where they are, and only the list of
 * suggestions moves.
 */
.search-panel__sheet {
	--focus: var(--acc);

	display: flex;
	flex-direction: column;
	width: 100%;
	max-width: 820px;

	/*
	 * `--seen-h` is what the reader can actually see, written by search.js from
	 * `visualViewport` while the panel is open — see the note there. A browser
	 * with no `visualViewport`, and every desktop, falls back to `100%`, which
	 * is what this was.
	 */
	max-height: var(--seen-h, 100%);
	padding: clamp(18px, 4vw, 34px) clamp(18px, 4vw, 40px) clamp(22px, 4vw, 38px);
	background: var(--paper);
	border-bottom: var(--hair) solid var(--rule);
	border-radius: var(--edge);
	transform: translateY(-12px);
	transition: transform var(--move-slow);
}

.search-panel__form {
	display: flex;
	flex-direction: column;
	min-height: 0;
}

.search-panel.is-open .search-panel__sheet {
	transform: none;
}

/*
 * The field, the glyph and the close on one baseline, with a single rule under
 * the whole row rather than a box around the input. It is the magazine's own
 * writing line: the same hairline the credit rail, the contents row and the
 * footer's fields are drawn with.
 */
.search-panel__row {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr) auto;
	align-items: center;
	gap: 14px;
	padding-bottom: 12px;
	border-bottom: var(--hair) solid var(--rule-2);
}

.search-panel__glyph {
	display: flex;
	line-height: 0;
	color: var(--ink-3);
}

/*
 * 1.5rem, and that is deliberate: §3 asks for "большое поле ввода", and it is
 * also the floor iOS Safari needs to leave a field alone. Under 16px it zooms
 * the whole page in on focus, which on a search overlay means the sheet is
 * suddenly wider than the screen.
 */
.search-panel__field {
	min-width: 0;
	min-height: var(--tap);
	padding: 6px 0;
	font-family: var(--serif);
	font-size: clamp(1.5rem, 4vw, 2.1rem);
	line-height: 1.2;
	color: var(--ink);
	background: none;
	border: 0;
	border-radius: var(--edge);
	appearance: none;
}

/*
 * THE FIELD'S OWN INDICATOR, NOT A RING ROUND IT.
 *
 * A text field always matches `:focus-visible` — it takes typed input, so the
 * browser cannot treat it as a pointer-only control — and this one is focused
 * the moment the sheet opens. So the default 2px ring was permanent, and it
 * turned a large open field with one rule under it into a boxed input in a
 * heavy outline: the SaaS form §1 rules out, drawn by the accessibility
 * default rather than by a decision.
 *
 * A 3px accent bar inside the field's own foot instead. It is the same colour
 * the ring was, it is the full width of the thing that has the keyboard, and
 * on ivory paper claret measures 8.20:1 against the 3:1 WCAG 2.4.11 asks. It
 * also reads as the writing line the design already uses everywhere else.
 */
.search-panel__field:focus-visible {
	outline: 0;
	box-shadow: inset 0 -3px 0 var(--focus);
}

.search-panel__field::placeholder {
	color: var(--ink-3);
	opacity: 1;
}

/* Safari draws its own grey capsule and clear button inside type="search". */
.search-panel__field::-webkit-search-cancel-button,
.search-panel__field::-webkit-search-decoration {
	appearance: none;
}

.search-panel__close {
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: 10px;
	min-height: var(--tap);
	padding: 0;
	font-family: var(--sans);
	font-size: var(--label);
	font-weight: 500;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--ink-2);
	border: 0;
	background: none;
	transition: color var(--move-quick);
}

/*
 * The overlay's close is the same plate again, at the size the sheet's own row
 * can carry: square corners, a keyline, no fill. The sheet is already the
 * magazine's paper, so a filled plate here would be a second dark object beside
 * a large field — the row wants one focus, and it is the field.
 */
.search-panel__close-mark {
	display: grid;
	place-content: center;
	width: 34px;
	height: 34px;
	font-size: 1.4rem;
	line-height: 1;
	border: var(--hair) solid var(--rule-2);
	border-radius: var(--edge);
	transition: border-color var(--move-quick), color var(--move-quick);
}

@media (hover: hover) and (pointer: fine) {
	.search-panel__close:hover {
		color: var(--acc);
	}

	.search-panel__close:hover .search-panel__close-mark {
		border-color: var(--acc);
	}
}

.search-panel__hint {
	margin: 10px 0 0;
	font-size: var(--copy-small);
	color: var(--ink-3);
}

/*
 * The reserved space. 168px is two entries' worth, which is enough that the
 * sheet has a shape before the first answer and not so much that an empty
 * search is a screen of nothing.
 */
.search-panel__results {
	flex: 1 1 auto;
	min-height: 168px;

	/*
	 * 56% of what the reader can see, not 56% of the layout viewport. With a
	 * keyboard open on a 390x844 phone the visible area is nearer 500px, and
	 * `56vh` of suggestions is 473 of it: the field above them and the "View
	 * all" line below them both went under the keys.
	 */
	max-height: min(56vh, 520px);
	max-height: min(calc(var(--seen-h, 100vh) * .56), 520px);
	margin-top: 16px;
	overflow-y: auto;
	overscroll-behavior: contain;
}

.search-panel__note {
	margin: 0;
	padding: 22px 0;
	font-family: var(--serif);
	font-style: italic;
	font-size: 1.05rem;
	color: var(--ink-3);
}

.search-panel__all {
	margin: 4px 0 0;
	padding-top: 12px;
	border-top: var(--hair) solid var(--rule);
}

.search-panel__all[hidden] {
	display: none;
}

/*
 * ---------- ONE SUGGESTION ----------
 *
 * A thumbnail, the headline, and the section and date under it. The frame is
 * `aspect-ratio` with a ground of its own, so a row is the same height before
 * its photograph has loaded as after — a list that reflows as eight images
 * arrive is a list a reader cannot click on.
 */
.search-hit {
	display: grid;
	grid-template-columns: 68px minmax(0, 1fr);
	align-items: center;
	gap: 16px;
	padding: 10px 0;
	border-bottom: var(--hair) solid var(--rule);
	transition: background-color var(--move-quick);
}

.search-hit__shot {
	aspect-ratio: 1 / 1;
	overflow: hidden;
	background: var(--paper-3);
}

/*
 * The row for an article with no photograph, or one whose file has gone. The
 * frame is not drawn empty — see the note in search.js — so the headline takes
 * the whole measure, exactly as a card with no photograph does.
 */
.search-hit--bare {
	grid-template-columns: minmax(0, 1fr);
}

.search-hit__shot img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.search-hit__words {
	min-width: 0;
}

.search-hit__title {
	display: block;
	font-family: var(--serif);
	font-size: 1.16rem;
	line-height: 1.2;
	color: var(--ink);
}

/*
 * The reader's own words inside the headline. Bold in a serif this size is a
 * visible weight change without being a different typeface, and it is drawn
 * from text nodes in search.js rather than from a string of HTML.
 */
.search-hit__title b {
	font-weight: 600;
	color: var(--acc);
}

.search-hit__meta {
	display: block;
	margin-top: 5px;
	font-family: var(--sans);
	font-size: var(--label-fine);
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--ink-3);
}

/*
 * The standfirst under the headline — §6's "optional excerpt".
 *
 * Two lines at most, and not at all on a phone: the row there is a 68px
 * photograph beside a headline, and a third line of small italic under it turns
 * a scannable list of eight into a wall. The suggestions are for recognising a
 * story, and on a small screen the headline does that on its own.
 */
.search-hit__say {
	display: none;
	margin-top: 6px;
	font-family: var(--serif);
	font-style: italic;
	font-size: .95rem;
	line-height: 1.34;
	color: var(--ink-2);

	/*
	 * Two lines, then it stops. `max-height` and `overflow` rather than
	 * `-webkit-line-clamp`: the clamp needs `display: -webkit-box`, which would
	 * fight the `display: none` this rule depends on to stay off a phone, and
	 * W3TC's CSSTidy has form for mangling vendor-prefixed display values. Two
	 * lines of 1.34 leading is 2.68em.
	 */
	max-height: 2.68em;
	overflow: hidden;
}

@media (min-width: 700px) {
	.search-hit__say {
		display: block;
	}
}

/*
 * `.is-active` rather than `:hover`, because the arrow keys move the same
 * highlight the pointer does. One state, one appearance, whichever input the
 * reader is using — §3's "Arrow Up / Arrow Down навигация".
 */
.search-hit.is-active {
	background: var(--paper-2);
}

.search-hit.is-active .search-hit__title {
	color: var(--acc);
}

.search-hit:focus-visible {
	outline: 2px solid var(--focus);
	outline-offset: -2px;
}

/*
 * The page behind does not scroll while the sheet is open.
 *
 * The same mechanic as the menu's: the root is clipped, and search.js remembers
 * the offset and puts it back on close, because `overflow: clip` alone does not
 * pin the document in Safari on a phone. The scrollbar's width is added back as
 * padding by the same handler, so nothing on the page moves sideways when the
 * bar goes — §3's "не должно быть скачка страницы".
 */
.is-searching {
	overflow: clip;
}

@media (max-width: 700px) {

	.search-panel__close-word {
		position: absolute;
		inset: 0;
		width: 1px;
		height: 1px;
		margin: 0;
		padding: 0;
		overflow: hidden;
		clip-path: inset(50%);
		white-space: nowrap;
		border: 0;
	}

	.search-hit {
		grid-template-columns: 56px minmax(0, 1fr);
		gap: 14px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.search-panel,
	.search-panel__sheet,
	.search-hit,
	.search-panel__close,
	.search-panel__close-mark {
		transition: none;
	}
}

/* ---------- The masthead, and how to reach it ---------- */

/*
 * Both print nothing until a magazine has filled them in, so these rules style
 * an element that may never appear — which is the right way round: the
 * alternative is a footer with a plausible address in it that nobody answers.
 */
.footer__contact {
	margin-top: 14px;
	font-style: normal;
	font-size: var(--copy-small);
	line-height: 1.6;
	color: var(--ink-2);
}

.footer__contact-link,
.footer__contact-line {
	display: block;
}

.footer__contact-link {
	border-bottom: 1px solid var(--rule-2);
}

/* ---------- Contributors ---------- */

/*
 * The masthead page. One person to a row, and every field is optional because
 * every field is theirs: a contributor who has written no biography gets no
 * biography, and the row closes up rather than leaving a labelled void.
 */
.contributors {
	margin: 0;
	padding: 0;
	list-style: none;
}

.contributors__person {
	padding: 22px 0;
	border-bottom: 1px solid var(--rule);
}

.contributors__name {
	display: block;
	font-family: var(--serif);
	font-size: clamp(1.24rem, .956rem + 1.89cqi, 1.5rem);
	line-height: 1.1;
}

.contributors__role {
	display: block;
	margin-top: 4px;
	font-family: var(--sans);
	font-size: var(--label);
	font-weight: 300;
	letter-spacing: var(--label-track, .3em);
	text-transform: uppercase;
	color: var(--ink-3);
}

.contributors__bio {
	margin: .6em 0 0;
	max-width: 56ch;
}

.contributors__count,
.contributors__empty {
	margin: .4em 0 0;
	font-family: var(--sans);
	font-size: var(--label-fine);
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--ink-3);
}

/* ---------- A chapter's opening story ---------- */

/*
 * §A13 asks for image-led storytelling, a clear section rhythm and no generic
 * repeated card grid. Every chapter used to be four cards in one grid, seven
 * times down the page. The first story of a chapter set in `lead` composition
 * is drawn here instead: its photograph at the chapter's full width, its
 * headline a step up from the cards under it, and its standfirst where the
 * editor wrote one.
 *
 * Which chapters get it is the owner's — Prominent Magazine → Sections carries
 * one Composition per section, and the section's own landing page reads the
 * same field. One setting, two surfaces.
 */
.lead-card {
	display: block;
	margin-bottom: clamp(20px, 3cqi, 40px);
	container-type: inline-size;
}

.lead-card__frame {
	aspect-ratio: 8 / 5;
	overflow: hidden;
	margin-bottom: clamp(12px, 1.8cqi, 22px);
	background: var(--paper-3);
}

.lead-card__frame img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform .6s cubic-bezier(.33, 0, .2, 1);
}

@media (hover: hover) and (pointer: fine) {
	.lead-card:hover .lead-card__frame img {
		transform: scale(1.02);
	}
}

.lead-card__rubric {
	display: block;
	margin-bottom: .5em;
	font-family: var(--sans);
	font-size: var(--label);
	font-weight: 300;
	letter-spacing: .28em;
	text-transform: uppercase;
	color: var(--ink-3);
}

.lead-card__title {
	margin: 0;
	font-size: clamp(1.5rem, 6cqi, 2.4rem);
	line-height: 1.04;
	letter-spacing: -.012em;
}

.lead-card__dek {
	max-width: 46ch;
	margin: .6em 0 0;
	font-family: var(--serif);
	font-size: 1.02rem;
	line-height: 1.42;
	color: var(--ink-2);
}

/*
 * A chapter whose photograph has gone keeps its rhythm: the headline is still
 * the chapter's opening, set at the opening's size, on the magazine's paper.
 * §A16 — an intentional state, not a hole where a picture should be.
 */
.lead-card--bare .lead-card__body {
	padding: clamp(18px, 3cqi, 34px);
	border-top: 2px solid var(--ink);
	border-bottom: 1px solid var(--rule);
	background: var(--paper-2);
}

/* ---------- The four compositions, on the front page ---------- */

/*
 * The same four names the Sections screen offers, so what the owner reads there
 * is what they get here. `lead` has already taken its first story out above, so
 * what is left is the run beside it.
 */
.cards--duo {
	grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
}

.cards--stack {
	grid-template-columns: 1fr;
	gap: clamp(14px, 2cqi, 26px);
}

.cards--stack .card {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr);
	align-items: center;
	gap: clamp(14px, 2.6cqi, 30px);
}

.cards--gallery {
	grid-template-columns: repeat(auto-fill, minmax(min(160px, 100%), 1fr));
	gap: clamp(10px, 1.6cqi, 18px);
}
