/*
 * Catalog single post — article head, two-column layout, contents rail,
 * tag row, author box, Older/Newer pair and comments.
 *
 * Marker class: .nou-catalog-single
 * Depends on:   assets/css/catalog.css       (shell, pagehead, section, chip)
 *               assets/css/catalog-home.css  (the card frame the hero borrows)
 *               assets/css/catalog-page.css  (pathbar, prose, form, field, btn)
 *
 * Ported from design-lab/css/wf-c-single.css, light mode only, with the lab's
 * `--nou-*` placeholders resolved to real theme.json tokens — the same mapping
 * table as the head of assets/css/catalog.css.
 *
 * WHAT IS DELIBERATELY ABSENT FROM THIS FILE, because it already exists:
 *
 *   the body copy        .nou-catalog-prose      assets/css/catalog-page.css
 *   the breadcrumb       .nou-catalog-pathbar    assets/css/catalog-page.css
 *   the hero's frame     .nou-catalog-card__*    assets/css/catalog-home.css
 *   the chips            .nou-catalog-chip       assets/css/catalog.css
 *   the comment fields   .nou-catalog-field      assets/css/catalog-page.css
 *   the submit button    .nou-catalog-btn        assets/css/catalog-page.css
 *
 * The last two are reached by adding those classes to core's comment form in
 * inc/catalog-single.php rather than by restating the rules here. A site with
 * two kinds of text input has one kind too many, and two sets of rules to
 * maintain.
 */

/* ================================================================== *
 * FLOW-LAYOUT RESETS
 *
 * Core gives every child after the first in a flow container a block-gap top
 * margin (`:where(.is-layout-flow) > * { margin-block-start: 40px }`,
 * specificity 0). The three containers below are grids owned by this file, and
 * there a stray 40px on the second child shifts a grid item down inside its
 * area instead of being absorbed as a gap. Cleared once here, the same way
 * assets/css/catalog.css clears it for the shell.
 * ================================================================== */

.nou-catalog-article > *,
.nou-catalog-article__rail > *,
.nou-catalog-comments > *,
.nou-catalog-comment > * {
	margin-block: 0;
}

/* ================================================================== *
 * ARTICLE HEAD
 * ================================================================== */

/*
 * The title is NOT `.nou-catalog-title`.
 *
 * That class runs to 58px, which is right for a one-word page title — "Blog",
 * "About". An article headline is six to twelve words, and monospace has no
 * narrow letterforms to fall back on: every character takes a full cell, so at
 * 58px the same headline becomes four lines. 40px is the ceiling that keeps the
 * mono character of the design while landing in two.
 *
 * The blinking caret of `.nou-catalog-title` is intentionally not inherited
 * either: a caret says "this line is still being typed", which is true of a
 * section label and false of a finished article.
 */
.nou-catalog-single__title {
	max-width: 22ch;
	margin: 0;
	font-family: var(--wp--preset--font-family--mono);
	font-size: clamp(27px, 3.4vw, 40px);
	font-weight: var(--wp--custom--font-weight--medium);
	letter-spacing: var(--wp--custom--tracking--snug);
	line-height: 1.16;
	color: var(--wp--custom--neutral--900);
	text-wrap: balance;
}

/*
 * Meta row: date, read time and author on the left, the category chip pushed to
 * the right edge. Same size, family and tracking as the pathbar directly above
 * it, so the two rows read as one block of orientation rather than two
 * unrelated strips.
 */
.nou-catalog-single__meta {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 10px 14px;
	margin-top: clamp(18px, 2.4vw, 26px);
	font-family: var(--wp--preset--font-family--mono);
	font-size: 11px;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: var(--wp--custom--neutral--600);
}

/*
 * `:root .nou-catalog-pagehead > *` (catalog.css) resets margin-block to 0 on
 * every direct child (0,3,0), which kills the gap above — the meta row is a
 * direct child of the pagehead here, so its margin-top (0,1,0) never lands and
 * the row sits flush under the title. Restore it with a selector that outweighs
 * the reset, the same fix the pathbar uses in catalog-page.css.
 */
:root .nou-catalog-pagehead > .nou-catalog-single__meta {
	margin-top: clamp(18px, 2.4vw, 26px);
}

/*
 * The separator is drawn, not typed. A literal `·` in the markup is read out
 * between every value by a screen reader; a pseudo-element is not in the
 * accessibility tree at all.
 *
 * neutral 400 is below the 4.5:1 floor this design otherwise holds to, and that
 * is allowed here for the same reason as the `/` in the pathbar: it is a
 * separator generated by CSS, and the structure it implies is already carried
 * by the elements themselves. WCAG 1.4.3 does not apply to it.
 */
.nou-catalog-single__meta > * + *:not(.nou-catalog-chip)::before {
	content: "\00b7";
	margin-right: 14px;
	color: var(--wp--custom--neutral--400);
}

.nou-catalog-single__meta a:not(.nou-catalog-chip) {
	color: var(--wp--custom--neutral--700);
	text-decoration: none;
	transition: color 160ms var(--wp--custom--easing--base);
}

.nou-catalog-single__meta a:not(.nou-catalog-chip):hover {
	color: var(--wp--custom--accent--strong);
}

/* Everything before the chip is data about the article; the chip classifies it. */
.nou-catalog-single__meta .nou-catalog-chip {
	margin-left: auto;
}

/* --- Hero figure ------------------------------------------------- */

.nou-catalog-single__figure {
	margin: clamp(28px, 4vw, 48px) 0 0;
}

/*
 * Same pagehead reset (catalog.css, 0,3,0) flattens the figure's top margin —
 * it is a direct child of the pagehead too, so the hero would sit flush under
 * the meta row without this. Outweigh the reset, matching the meta and pathbar.
 */
:root .nou-catalog-pagehead > .nou-catalog-single__figure {
	margin-top: clamp(28px, 4vw, 48px);
}

/*
 * 12:5, not the card's 16:10 — the one place this page overrides the card, and
 * the reason is width, not a change of language.
 *
 * A card is about 350px wide, so 16:10 gives a 219px image that sits inside the
 * grid. The hero is the full 1120px column; at 16:10 it would be 700px tall,
 * and with the pinned header (about 62px) plus the pathbar, title and meta row
 * (about 210px) that is 972px before a single word of the article — so on a
 * 900px viewport the reader sees a picture and nothing else. 12:5 brings it to
 * 467px and leaves the opening paragraph on screen.
 *
 * The border, the radius, the neutral placeholder and `object-position: top`
 * are all inherited from `.nou-catalog-card__frame` / `__media` in
 * assets/css/catalog-home.css. Only the ratio is restated.
 */
.nou-catalog-single__figure .nou-catalog-card__media {
	aspect-ratio: 12 / 5;
}

.nou-catalog-single__figcaption {
	margin-top: 12px;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 11px;
	letter-spacing: 0.05em;
	color: var(--wp--custom--neutral--600);
}

/* ================================================================== *
 * TWO-COLUMN LAYOUT
 * ================================================================== */

/*
 * 232px for the rail, measured rather than guessed: at 210px four of the six
 * contents entries wrapped to two lines at 1440px, because monospace cannot
 * condense and a heading like "Static sections and JSON templates" needs about
 * 225px at 11.5px.
 *
 * `minmax(0, 1fr)` for the body column, not `1fr`. The default of `1fr` is
 * `minmax(auto, 1fr)`, and `auto` sizes to content — one long line inside a
 * <pre> would widen the column and push the rail out of the shell. Setting the
 * minimum to 0 lets the column shrink, which is also what makes the <pre>'s own
 * `overflow-x` fire.
 */
.nou-catalog-article {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 232px;
	gap: clamp(32px, 5vw, 72px);
	align-items: start;
}

/*
 * And again on the grid item itself. A grid item's default `min-width` is
 * `auto`, which sizes to content regardless of what the track allows, so
 * without this the <pre> still wins. Both places are needed; neither is
 * redundant.
 */
.nou-catalog-article__body {
	min-width: 0;
}

/*
 * STICKY IS ON THE GRID ITEM, NOT ON THE NAV INSIDE IT — this is where the
 * port diverges from design-lab/css/wf-c-single.css, which put it on `.wf-c-toc`
 * and therefore never actually stuck.
 *
 * A sticky element travels inside its containing block. For a child of the rail
 * that containing block is the rail box, and with `align-items: start` the rail
 * is exactly as tall as its content — no room to travel. The grid ITEM's
 * containing block is its grid area, which spans the whole row and is therefore
 * as tall as the article. So the item sticks and the nav rides along.
 *
 * 96px = the pinned header plus breathing room, and it is the same figure as
 * the `scroll-margin-top` below so a heading clicked in the rail lands level
 * with the rail's own top edge.
 */
.nou-catalog-article__rail {
	position: sticky;
	top: 96px;
}

/*
 * Headings are anchor targets now (ids are added in inc/catalog-single.php), so
 * they need to clear the pinned header when one is jumped to. Without this the
 * heading lands underneath the header and the reader appears to have arrived
 * mid-paragraph.
 */
.nou-catalog-single .nou-catalog-prose :is(h2, h3) {
	scroll-margin-top: 96px;
}

/* ================================================================== *
 * CONTENTS RAIL
 * ================================================================== */

.nou-catalog-toc {
	padding-left: 18px;
	/*
	 * line--strong (neutral 300), not line--soft (neutral 150).
	 *
	 * At neutral 150 the rule measures 1.44:1 on white and effectively
	 * disappears in a screenshot, leaving the contents list looking like a
	 * cluster of words floating in the margin. The body column stops at 68ch, so
	 * this hairline is the only thing tying the rail to the right-hand edge —
	 * when it is invisible the whole layout reads as a mistake. neutral 300
	 * (1.87:1) is still a hairline and still visible at every screen size. It is
	 * decoration, so WCAG 1.4.3 does not set a floor for it; it just has to be
	 * seen to do its job.
	 */
	border-left: 1px solid var(--wp--custom--line--strong);
}

.nou-catalog-toc__label {
	margin: 0;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 10px;
	letter-spacing: var(--wp--custom--tracking--wide);
	text-transform: uppercase;
	color: var(--wp--custom--neutral--600);
}

.nou-catalog-toc__list {
	display: grid;
	gap: 9px;
	margin: 14px 0 0;
	padding-left: 0;
	list-style: none;
}

/* `position: relative` is the anchor for the current-entry rule below. */
.nou-catalog-toc__list li {
	position: relative;
	margin: 0;
}

.nou-catalog-toc a {
	display: block;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 11.5px;
	line-height: 1.45;
	letter-spacing: 0.01em;
	color: var(--wp--custom--neutral--600);
	text-decoration: none;
	transition: color 160ms var(--wp--custom--easing--base);
}

.nou-catalog-toc a:hover {
	color: var(--wp--custom--neutral--900);
}

/* A sub-entry is indented. Rank is visible without adding a marker. */
.nou-catalog-toc__list .nou-catalog-toc__sub {
	padding-left: 14px;
}

/*
 * The entry being read. The class and `aria-current` are both set by the script
 * in inc/catalog-single.php from the real scroll position — nothing is marked
 * current in the markup, because a pre-selected entry is a wrong answer for as
 * long as it takes the reader to scroll.
 */
.nou-catalog-toc a.is-current {
	color: var(--wp--custom--neutral--900);
}

.nou-catalog-toc a.is-current::before {
	content: "";
	position: absolute;
	/*
	 * -19px = the nav's 18px padding-left plus its 1px border. The accent has to
	 * land exactly on the rail's hairline; at -1px it would be a second stray
	 * line hanging between the rule and the text.
	 */
	left: -19px;
	top: 0;
	width: 1px;
	height: 100%;
	background: var(--wp--custom--accent--strong);
}

.nou-catalog-toc a:focus-visible {
	outline: 2px solid var(--wp--custom--accent--strong);
	outline-offset: 3px;
	border-radius: var(--wp--custom--radius--xs);
}

/* ================================================================== *
 * TAG ROW
 * ================================================================== */

.nou-catalog-tags {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
	margin-top: clamp(34px, 4vw, 52px);
	padding-top: clamp(20px, 2.4vw, 28px);
	border-top: 1px solid var(--wp--custom--line--soft);
}

.nou-catalog-tags__label {
	margin-right: 4px;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 10px;
	letter-spacing: var(--wp--custom--tracking--wide);
	text-transform: uppercase;
	color: var(--wp--custom--neutral--600);
}

/*
 * A chip that is a link has to answer the pointer; the static chip over a card
 * image does not. `a.nou-catalog-chip` rather than a new class, so the two stay
 * the same object with one extra state.
 */
a.nou-catalog-chip {
	text-decoration: none;
	transition: border-color 160ms var(--wp--custom--easing--base),
		color 160ms var(--wp--custom--easing--base);
}

a.nou-catalog-chip:hover {
	border-color: var(--wp--custom--accent--strong);
	color: var(--wp--custom--neutral--900);
}

a.nou-catalog-chip:focus-visible {
	outline: 2px solid var(--wp--custom--accent--strong);
	outline-offset: 2px;
}

/* ================================================================== *
 * AUTHOR BOX — core/post-author
 *
 * Two class selectors, not one. core's own stylesheet sets
 * `.wp-block-post-author { display: flex; flex-wrap: wrap }` at the same
 * specificity as a single class here, so the winner would depend on which
 * stylesheet printed last. Naming both classes settles it.
 * ================================================================== */

.wp-block-post-author.nou-catalog-author {
	display: grid;
	grid-template-columns: 52px minmax(0, 1fr);
	gap: clamp(16px, 2vw, 22px);
	margin-top: clamp(34px, 4vw, 52px);
	padding: clamp(20px, 2.6vw, 28px);
	border: 1px solid var(--wp--custom--line--soft);
	border-radius: var(--wp--custom--radius--md);
}

.nou-catalog-author .wp-block-post-author__avatar {
	margin: 0;
	line-height: 0;
}

/*
 * The avatar takes the same hairline square as everything else framed in this
 * design, rather than core's circle. It is a 52px box whatever the requested
 * size resolved to, so the two-column grid above cannot be knocked out of
 * alignment by a Gravatar that came back at another size.
 */
.nou-catalog-author .wp-block-post-author__avatar img {
	display: block;
	width: 52px;
	height: 52px;
	border: 1px solid var(--wp--custom--line--strong);
	border-radius: var(--wp--custom--radius--sm);
	object-fit: cover;
}

.nou-catalog-author .wp-block-post-author__content {
	min-width: 0;
}

.nou-catalog-author .wp-block-post-author__name {
	margin: 0;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 13px;
	font-weight: var(--wp--custom--font-weight--medium);
	letter-spacing: var(--wp--custom--tracking--snug);
	color: var(--wp--custom--neutral--900);
}

.nou-catalog-author .wp-block-post-author__name a {
	color: inherit;
	text-decoration: none;
}

.nou-catalog-author .wp-block-post-author__name a:hover {
	color: var(--wp--custom--accent--strong);
}

.nou-catalog-author .wp-block-post-author__byline {
	margin: 3px 0 0;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 10px;
	letter-spacing: var(--wp--custom--tracking--wide);
	text-transform: uppercase;
	color: var(--wp--custom--neutral--600);
}

/*
 * `:empty` is not enough — core prints the bio paragraph whenever `showBio` is
 * on, and an author with no description yields a paragraph containing nothing,
 * which would still take its top margin. `:not(:empty)` puts the margin on the
 * bio only when there is a bio.
 */
.nou-catalog-author .wp-block-post-author__bio {
	max-width: 58ch;
	margin: 0;
	font-size: 14px;
	line-height: var(--wp--custom--line-height--medium);
	color: var(--wp--custom--neutral--700);
}

.nou-catalog-author .wp-block-post-author__bio:not(:empty) {
	margin-top: 12px;
}

/* ================================================================== *
 * OLDER / NEWER
 * ================================================================== */

/*
 * The dividing line between the two cells IS the 1px gap, showing the container
 * background through it. So neither cell draws a border of its own and a double
 * rule down the middle is impossible.
 */
.nou-catalog-postnav {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 1px;
	margin-top: clamp(34px, 4vw, 52px);
	background: var(--wp--custom--line--soft);
	border: 1px solid var(--wp--custom--line--soft);
	border-radius: var(--wp--custom--radius--md);
	overflow: hidden;
}

/* Only one neighbour exists: one full-width cell, no empty half. */
.nou-catalog-postnav--single {
	grid-template-columns: minmax(0, 1fr);
}

.nou-catalog-postnav__item {
	display: block;
	padding: clamp(18px, 2.4vw, 24px);
	background: var(--wp--custom--surface--page);
	text-decoration: none;
	transition: background-color 180ms var(--wp--custom--easing--base);
}

.nou-catalog-postnav__item:hover {
	background: var(--wp--custom--neutral--50);
}

/* Right-aligned so the two arrows point outwards from the block. */
.nou-catalog-postnav__item--next {
	text-align: right;
}

.nou-catalog-postnav--single .nou-catalog-postnav__item--next {
	text-align: left;
}

.nou-catalog-postnav__dir {
	display: block;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 10px;
	letter-spacing: var(--wp--custom--tracking--wide);
	text-transform: uppercase;
	color: var(--wp--custom--neutral--600);
}

.nou-catalog-postnav__title {
	display: block;
	margin-top: 8px;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 13px;
	line-height: 1.4;
	letter-spacing: var(--wp--custom--tracking--snug);
	color: var(--wp--custom--neutral--900);
}

.nou-catalog-postnav__item:hover .nou-catalog-postnav__title {
	color: var(--wp--custom--accent--strong);
}

.nou-catalog-postnav__item:focus-visible {
	outline: 2px solid var(--wp--custom--accent--strong);
	outline-offset: -3px;
}

/* ================================================================== *
 * COMMENTS
 * ================================================================== */

/*
 * With comments closed and none published, core still renders the wrapper and
 * every inner block returns an empty string — so the section would draw a
 * hairline under nothing at all. `:has()` checks for any of the three things
 * that make the section worth showing.
 */
.nou-catalog-comments:not(:has(.wp-block-comments-title, .wp-block-comment-template, .wp-block-post-comments-form)) {
	display: none;
}

.nou-catalog-comments {
	margin-top: clamp(48px, 6vw, 84px);
	padding-top: clamp(28px, 3.4vw, 40px);
	border-top: 1px solid var(--wp--custom--line--strong);
}

.nou-catalog-comments .wp-block-comments-title {
	margin: 0 0 clamp(22px, 2.6vw, 30px);
	font-family: var(--wp--preset--font-family--mono);
	font-size: clamp(18px, 2vw, 22px);
	font-weight: var(--wp--custom--font-weight--medium);
	letter-spacing: var(--wp--custom--tracking--tight);
	line-height: 1.2;
	color: var(--wp--custom--neutral--900);
}

.nou-catalog-comments .wp-block-comment-template {
	display: grid;
	gap: clamp(20px, 2.4vw, 28px);
	margin: 0;
	padding-left: 0;
	list-style: none;
}

/*
 * A reply thread is indented and hangs off a vertical hairline, so it is clear
 * it belongs to the comment above rather than being the next one in the list.
 * The nested list is the same block, so it is matched as a descendant of
 * itself rather than needing a class of its own.
 */
.nou-catalog-comments .wp-block-comment-template .wp-block-comment-template {
	margin-top: clamp(20px, 2.4vw, 28px);
	padding-left: clamp(16px, 2vw, 24px);
	border-left: 1px solid var(--wp--custom--line--soft);
}

.nou-catalog-comment {
	display: grid;
	grid-template-columns: 40px minmax(0, 1fr);
	gap: 14px;
	align-items: start;
}

.nou-catalog-comment__avatar {
	margin: 0;
	line-height: 0;
}

.nou-catalog-comment__avatar img {
	display: block;
	width: 40px;
	height: 40px;
	border: 1px solid var(--wp--custom--line--soft);
	border-radius: var(--wp--custom--radius--sm);
	object-fit: cover;
}

.nou-catalog-comment__body {
	min-width: 0;
}

.nou-catalog-comment__head {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: 4px 12px;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 11px;
	letter-spacing: 0.05em;
}

.nou-catalog-comment__head .wp-block-comment-author-name {
	font-weight: var(--wp--custom--font-weight--medium);
	color: var(--wp--custom--neutral--900);
}

.nou-catalog-comment__head .wp-block-comment-author-name a {
	color: inherit;
	text-decoration: none;
}

.nou-catalog-comment__head .wp-block-comment-date {
	text-transform: uppercase;
	color: var(--wp--custom--neutral--600);
}

.nou-catalog-comment__head .wp-block-comment-date a {
	color: inherit;
	text-decoration: none;
}

.nou-catalog-comment .wp-block-comment-content {
	max-width: 62ch;
	margin: 9px 0 0;
	font-size: 14px;
	line-height: var(--wp--custom--line-height--medium);
	color: var(--wp--custom--neutral--700);
}

.nou-catalog-comment .wp-block-comment-content p {
	margin: 0;
}

.nou-catalog-comment .wp-block-comment-content p + p {
	margin-top: 0.8em;
}

.nou-catalog-comment .wp-block-comment-reply-link {
	margin: 9px 0 0;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 10px;
	letter-spacing: var(--wp--custom--tracking--wide);
	text-transform: uppercase;
}

.nou-catalog-comment .wp-block-comment-reply-link a {
	color: var(--wp--custom--neutral--600);
	text-decoration: none;
	transition: color 160ms var(--wp--custom--easing--base);
}

.nou-catalog-comment .wp-block-comment-reply-link a:hover {
	color: var(--wp--custom--accent--strong);
}

/* --- Comment pagination ----------------------------------------- */

/*
 * Reuses the pager pills from assets/css/catalog-blog.css when that file is
 * loaded, and stays legible on its own when it is not: the only thing set here
 * is the row, because a threaded page of comments is a rare enough case that a
 * second set of pill rules is not worth carrying.
 */
.nou-catalog-comments .wp-block-comments-pagination {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 10px;
	margin-top: clamp(24px, 3vw, 34px);
	font-family: var(--wp--preset--font-family--mono);
	font-size: 12px;
}

/* --- Comment form ----------------------------------------------- */

/*
 * The form itself is `.nou-catalog-form` and its fields are
 * `.nou-catalog-field`, both from assets/css/catalog-page.css — the classes are
 * added to core's form in inc/catalog-single.php. What is left here is only the
 * boundary above the form and the heading, which the contact page does not have.
 */
.nou-catalog-comments .wp-block-post-comments-form {
	margin-top: clamp(34px, 4vw, 52px);
	padding-top: clamp(24px, 3vw, 34px);
	border-top: 1px solid var(--wp--custom--line--soft);
}

.nou-catalog-commentform__title {
	margin: 0 0 clamp(18px, 2.2vw, 24px);
	font-family: var(--wp--preset--font-family--mono);
	font-size: clamp(16px, 1.8vw, 19px);
	font-weight: var(--wp--custom--font-weight--medium);
	letter-spacing: var(--wp--custom--tracking--tight);
	line-height: 1.2;
	color: var(--wp--custom--neutral--900);
}

/* Narrower than the body column: a field the width of a paragraph makes the eye
 * travel the whole measure for every line typed. */
.nou-catalog-comments .comment-form {
	max-width: 62ch;
}

.nou-catalog-comments .comment-notes,
.nou-catalog-comments .comment-form-cookies-consent,
.nou-catalog-comments .logged-in-as {
	margin: 0;
	font-size: 13px;
	line-height: 1.5;
	color: var(--wp--custom--neutral--600);
}

.nou-catalog-comments .comment-form-cookies-consent {
	display: flex;
	align-items: flex-start;
	gap: 9px;
}

.nou-catalog-comments .comment-form-cookies-consent label {
	font-family: inherit;
	text-transform: none;
	letter-spacing: 0;
}

.nou-catalog-comments .comment-notes a,
.nou-catalog-comments .logged-in-as a {
	color: var(--wp--custom--neutral--900);
	text-decoration: underline;
	text-decoration-color: var(--wp--custom--accent--strong);
	text-underline-offset: 3px;
}

/* Core prints the submit input inside `.form-submit`; the button styling comes
 * from `.nou-catalog-btn`, so only the row is set here. */
.nou-catalog-comments .form-submit {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 14px 20px;
	margin: 0;
}

/* ================================================================== *
 * NARROW SCREENS
 * ================================================================== */

@media (max-width: 1024px) {
	/*
	 * One column, and the contents list moves ABOVE the article. There is no
	 * margin left to pin it to, and a contents list underneath the article is
	 * of no use to anybody — by the time it is reached, the reading is done.
	 */
	.nou-catalog-article {
		grid-template-columns: minmax(0, 1fr);
		gap: clamp(28px, 4vw, 40px);
	}

	.nou-catalog-article__rail {
		position: static;
		order: -1;
	}

	/* Once it is a box in the flow, the left rule becomes a full border. */
	.nou-catalog-toc {
		padding: 18px 20px;
		border: 1px solid var(--wp--custom--line--soft);
		border-radius: var(--wp--custom--radius--md);
	}

	/* The accent bar was aligned to a rule that no longer sits there. */
	.nou-catalog-toc a.is-current::before {
		display: none;
	}

	.nou-catalog-toc a.is-current {
		font-weight: var(--wp--custom--font-weight--medium);
	}
}

@media (max-width: 560px) {
	/* Stacked, and the second cell stops right-aligning so the two match. */
	.nou-catalog-postnav {
		grid-template-columns: minmax(0, 1fr);
	}

	.nou-catalog-postnav__item--next {
		text-align: left;
	}

	.wp-block-post-author.nou-catalog-author {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* ================================================================== *
 * REDUCED MOTION
 * ================================================================== */

@media (prefers-reduced-motion: reduce) {
	.nou-catalog-single__meta a:not(.nou-catalog-chip),
	.nou-catalog-toc a,
	a.nou-catalog-chip,
	.nou-catalog-postnav__item,
	.nou-catalog-comment .wp-block-comment-reply-link a {
		transition: none;
	}
}

/* ================================================================== *
 * COMMENT FORM — three corrections against design-lab/wf-c-single.html
 *
 * Added during review, after the template was rendered and compared with the
 * wireframe screenshot. Each one is a place where core's default markup does
 * not reach the design on its own.
 * ================================================================== */

/*
 * 1. THE SUBMIT BUTTON.
 *
 * `.form-submit` above sets the row, with a note saying the button itself
 * comes from `.nou-catalog-btn`. It does not: core prints
 * `<input type="submit" class="submit">` and there is no filter point that adds
 * a class to it without also touching every other comment form on the site. So
 * it fell through to theme.json's `styles.elements.button` — a filled pill in
 * sentence case, where every other action in this design is a mono uppercase
 * rectangle.
 *
 * The declarations are copied from `.nou-catalog-btn` rather than shared,
 * because a comma-joined selector would have to live in catalog-page.css and
 * that file has no business knowing about comment forms. White on #0066ff
 * measures 4.83:1, above the 4.5 floor.
 */
.nou-catalog-comments .form-submit input[type="submit"] {
	display: inline-flex;
	align-items: center;
	padding: 14px 24px;
	border: 1px solid transparent;
	border-radius: var(--wp--custom--radius--xs);
	background: var(--wp--custom--accent--strong);
	color: #ffffff;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 12px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	cursor: pointer;
	transition: background-color 180ms var(--wp--custom--easing--base),
		transform 200ms var(--wp--custom--easing--out);
}

.nou-catalog-comments .form-submit input[type="submit"]:hover {
	background: var(--wp--custom--accent--stronger);
	transform: translateY(-1px);
}

.nou-catalog-comments .form-submit input[type="submit"]:focus-visible {
	outline: 2px solid var(--wp--custom--accent--strong);
	outline-offset: 2px;
}

/*
 * 2. NAME AND EMAIL SHARE A ROW.
 *
 * The wireframe puts them side by side, and they are the two shortest fields on
 * the form — stacking them makes the reader scroll past four full-width boxes
 * to reach a button. `.comment-form` already carries `.nou-catalog-form`, which
 * is a one-column grid, so this only has to widen the grid and put every other
 * child back across both tracks.
 *
 * Above 600px only: at 375px two 50% fields are narrower than the text people
 * type into them.
 */
@media (min-width: 601px) {
	.nou-catalog-comments .comment-form {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.nou-catalog-comments .comment-form > *:not(.comment-form-author):not(.comment-form-email) {
		grid-column: 1 / -1;
	}
}

/*
 * 3. A LONE POST-NAVIGATION ITEM TAKES THE WHOLE BOX.
 *
 * `.nou-catalog-postnav` is a two-column bordered box, which is right when a
 * post has a neighbour on both sides. The newest and the oldest post each have
 * one, and the empty half then reads as a missing link rather than as "there is
 * nothing after this". `:has()` is the test, so no PHP has to know.
 */
.nou-catalog-postnav:not(:has(.nou-catalog-postnav__item--next)),
.nou-catalog-postnav:not(:has(.nou-catalog-postnav__item:not(.nou-catalog-postnav__item--next))) {
	grid-template-columns: minmax(0, 1fr);
}

@media (prefers-reduced-motion: reduce) {
	.nou-catalog-comments .form-submit input[type="submit"] {
		transition: none;
	}

	.nou-catalog-comments .form-submit input[type="submit"]:hover {
		transform: none;
	}
}
