/*
 * pm-v2-interactions — the shared hover/focus library.
 *
 * SOURCE OF TRUTH. The effect-to-selector mapping and the reasoning behind every
 * recipe live in `.zcode/artifacts/hover-library.md`. This file is the code half of
 * that reference: if a rule here and the mapping disagree, the mapping is wrong.
 *
 * WHAT THIS IS. A small, hand-written set of interaction recipes for the site's
 * REAL interactive containers — the primary menu, the logo, the software cards, the
 * independent calls to action, and ordinary content/meta/widget links. It is an
 * ORIGINAL adaptation of public technique, not a copy of any vendor library: no
 * Hover.css class, no CodePen source, no third-party bundle is embedded. The
 * research that fed it (see the reference) could not verify any CodePen page, so
 * nothing here claims otherwise — these are recipes written for this theme.
 *
 * WHY A SEPARATE FILE. Hover affordances were spread across eight component sheets
 * with no single owner, so a change to "how a link behaves on hover" meant editing
 * five files and hoping they agreed. This file gives every interactive-container
 * hover ONE home. The component sheets keep their geometry; they no longer own the
 * motion of a container they do not fully control.
 *
 * SCOPE RULES (hard, non-negotiable):
 *   - Everything is scoped to `.pm-v2`.
 *   - Only INTERACTIVE CONTAINERS are touched. Quick-info rows, hash/anchor content
 *     panels, `.pm-surface__description` prose boxes and other non-interactive
 *     panels are NOT styled here — a hover state on a box that does not respond to a
 *     click is a lie about the interface.
 *   - No blanket `.pm-v2 *:hover`, no global `cursor: pointer` on `div`, no
 *     JavaScript. Motion is CSS only.
 *   - Motion is for fine pointers that actually hover. Under `(hover: none)` the
 *     touch build keeps every colour/contrast affordance and drops the movement from
 *     `:hover`, `:focus-visible` AND `:active`, so a tap target never shifts under the
 *     finger.
 *   - A control that cannot be activated (native `:disabled` or the theme's link CTAs
 *     with `[aria-disabled="true"]`) does not rise: its transform/shadow are reset.
 *   - `prefers-reduced-motion` drops the NEW motion only (this file's own lifts and
 *     the menu underline's transition) across all three states. It does NOT write
 *     `transform: none` over the whole tree: GeneratePress' submenu arrow rotation and
 *     other existing transforms are not this file's to erase.
 *
 * LOAD ORDER. Enqueued LAST, after every stylesheet that can be active on the page
 * (see inc/enqueue.php), so a component's resting look is already in the cascade and
 * this file only adds the interaction on top. Its own dependency list is computed
 * from the styles that are actually enqueued for THIS request, so it never drags a
 * conditional sheet (home, card, archive, …) onto a page that should not have it.
 */

/* ==================================================== primary menu underline == */

/* Separate the main navigation surface on every template, excluding slideout.
 * GP retains sizing and box sizing; sticky-layout measures the added 1px border.
 */
.pm-v2 #site-navigation:not(.slideout-navigation) {
	border-bottom: 1px solid var(--border);
	box-shadow: var(--shadow-sm);
}

/* The ID outranks GP and tokens.css, including explicit and OS-dark states.
 * Keep native link geometry and normal text; no tinted background or link lift.
 */
html .pm-v2 #site-navigation:not(.slideout-navigation) .main-nav > ul > .menu-item > a {
	position: relative;
	background-color: transparent;
	color: var(--text);
	transition: color var(--pm-ease);
}

/* Inset by GP's existing 20px horizontal text padding; paint at the bottom. */
.pm-v2 #site-navigation:not(.slideout-navigation) .main-nav > ul > .menu-item > a::after {
	content: "";
	position: absolute;
	right: 20px;
	bottom: 0;
	left: 20px;
	height: 2px;
	background-color: currentColor;
	opacity: 0;
	transform: scaleX(0);
	transition: opacity var(--pm-ease), transform var(--pm-ease);
	pointer-events: none;
}

/* GP puts sfHover on the parent li. Hover uses blue with the existing thin line. */
html .pm-v2 #site-navigation:not(.slideout-navigation) .main-nav > ul > .menu-item:is(:hover, .sfHover) > a {
	color: var(--primary);
}

.pm-v2 #site-navigation:not(.slideout-navigation) .main-nav > ul > .menu-item:is(:hover, .sfHover) > a::after {
	opacity: 1;
	transform: scaleX(1);
}

/* Current ancestors and keyboard focus take precedence over hover. */
html .pm-v2 #site-navigation:not(.slideout-navigation) .main-nav > ul > .menu-item:is(.current-menu-item, .current-menu-ancestor, .current_page_item, .current_page_ancestor) > a,
html .pm-v2 #site-navigation:not(.slideout-navigation) .main-nav > ul > .menu-item > a:focus-visible {
	color: var(--primary);
}

.pm-v2 #site-navigation:not(.slideout-navigation) .main-nav > ul > .menu-item:is(.current-menu-item, .current-menu-ancestor, .current_page_item, .current_page_ancestor) > a::after,
.pm-v2 #site-navigation:not(.slideout-navigation) .main-nav > ul > .menu-item > a:focus-visible::after {
	height: 3px;
	background-color: var(--primary);
	opacity: 1;
	transform: scaleX(1);
}

.pm-v2 #site-navigation:not(.slideout-navigation) .main-nav > ul > .menu-item > a:focus-visible {
	outline: 2px solid var(--focus);
	outline-offset: 2px;
}

/* Keep state paint on touch/reduced motion; reset only pseudo-element motion. */
@media (hover: none), (prefers-reduced-motion: reduce) {
	.pm-v2 #site-navigation:not(.slideout-navigation) .main-nav > ul > .menu-item > a::after {
		transform: none;
		transition: none;
	}
}

/* ===================================================== independent CTA lift == */

/*
 * A lift + shadow on a call to action that stands ALONE as the page's action.
 *
 * DELIBERATELY EXCLUDED, and why:
 *   - the search submit (`.pm-searchform__submit`) sits flush inside the cohesive
 *     search pill; lifting it would break the one-control illusion the redesign built;
 *   - `.menu-toggle` is a bar in the navigation, not a floating action;
 *   - `.generate-back-to-top` is `position: fixed` and must never be given a
 *     layout-affecting transform that could un-fix or jitter it.
 *
 * The existing 6s sheen on these buttons already supplies the periodic motion; this
 * adds a SUB-1px lift on hover only — NOT a second periodic animation, which would
 * fight the sheen's timing.
 */
.pm-v2 .pm-detail__cta {
	transition: background-color var(--pm-ease), border-color var(--pm-ease), transform var(--pm-ease), box-shadow var(--pm-ease);
}

.pm-v2 .pm-detail__cta:hover,
.pm-v2 .pm-detail__cta:focus-visible {
	transform: translateY(-1px);
	box-shadow: 0 4px 12px color-mix(in srgb, var(--primary) 28%, transparent);
}

/* Pressed: the lift returns home, the shadow drops. `:active` on both pointer and
   keyboard (Enter/Space fire :active) gives the press its own honest feedback. */
.pm-v2 .pm-detail__cta:active {
	transform: translateY(0);
	box-shadow: 0 0 0 color-mix(in srgb, var(--primary) 0%, transparent);
}

/*
 * A CTA that cannot be activated invites nothing, so it must not rise. The mirror/
 * detail CTA is an ANCHOR and cannot use `:disabled`, so both spellings are covered:
 * the native `:disabled` (for a real `<button>` CTA) and the ARIA form
 * `[aria-disabled="true"]` the theme puts on its link CTAs. Only the transform and the
 * shadow are reset — the component keeps owning colour/geometry, and nothing else in
 * the tree is touched (no blanket `transform: none`).
 */
.pm-v2 .pm-detail__cta:disabled,
.pm-v2 .pm-detail__cta[aria-disabled="true"] {
	transform: none;
	box-shadow: none;
}

/* ================================================== content + meta + widget === */

/*
 * Ordinary content, meta and widget links. These are the prose/rail/footer links a
 * reader follows — they must stay clearly distinguishable from body text, so the
 * affordance is the BRAND COLOUR on hover plus a tidy underline offset.
 *
 * THE MINT HIGHLIGHT WAS REMOVED FROM THIS GROUP BY REQUEST (see the MINT LINK block
 * below for the full history). A widget item is a small label, not a paragraph: a pale
 * slab painted under 13px text read as a glitch rather than as feedback, so these keep
 * the plain, long-established colour change instead. That is still a real affordance —
 * and because the resting colour already differs from body text, nothing becomes
 * unreachable when the highlight goes.
 *
 * Scope is `.widget a` and the theme's own meta anchors — never a blanket `.pm-v2 a`
 * (that would restyle plugin chrome the theme does not own).
 */
.pm-v2 .sidebar .widget:not(.widget_pm_v2_rail):not(.widget_custom_html) a:not(:has(img)) {
	text-decoration: none;
	transition: color var(--pm-ease), text-decoration-color var(--pm-ease);
}

.pm-v2 .sidebar .widget:not(.widget_pm_v2_rail):not(.widget_custom_html) a:not(:has(img)):hover,
.pm-v2 .sidebar .widget:not(.widget_pm_v2_rail):not(.widget_custom_html) a:not(:has(img)):focus-visible {
	color: var(--primary-hover);
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 3px;
}

.pm-v2 .sidebar .widget:not(.widget_pm_v2_rail):not(.widget_custom_html) a:not(:has(img)):focus-visible {
	outline: 2px solid var(--focus);
	outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
	.pm-v2 .sidebar .widget:not(.widget_pm_v2_rail):not(.widget_custom_html) a:not(:has(img)) { transition: none; }
}

/* ======================================================= article prose links == */

/*
 * LINKS INSIDE THE ARTICLE BODY. A reader following a link OUT of the prose is the
 * one place the underline no longer suits the redesign: on a post whose body is a
 * wall of text, a permanent 1px rule under every link is visual noise, and the
 * default `a:hover { color } ` alone is a colour-only cue (WCAG 1.4.1). The recipe
 * below replaces the resting underline with a mint HIGHLIGHT that appears on
 * hover/focus — the link is still unmistakably a link (its own blue at rest), the
 * hover is a non-colour cue, and the body reads clean until a pointer or keyboard
 * lands on a link.
 *
 * THIS IS THE ORIGINAL PEN, VERIFIED. The technique is `border-bottom: 2px` plus a
 * `box-shadow: inset 0 -0.5em 0 0 <mint>` highlight, matching the CodePen the user
 * selected:
 *     https://codepen.io/BinLate/pen/WNWVjaE   (browser-verified; the ONLY CodePen
 *     of the 42 that could be read — the other 41 were connection-blocked, see
 *     `.zcode/artifacts/hover-reference-research.md`).
 * The Pen's own rule is `a:hover { box-shadow: none; border-bottom: 2px solid
 * #3cffd0; box-shadow: inset 0 -0.5em 0 0 #3cffd0; }`. The colour is the site's
 * mint accent; the rest of the site's motion rules stay in this file.
 *
 * SCOPE — the ACTUAL article prose, nothing else:
 *   - `#pm-content.entry-content` is the software detail article (single-software.php);
 *   - `.entry-content` is the ordinary blog post body (GeneratePress single.php),
 *     which reaches this file because the stylesheet loads last on every surface.
 *   So both article types are covered; pages, archives, home, cards, the rail, the
 *   menu, the footer and the article META are not: they never match this selector.
 *
 * EXCLUSIONS (a data-driven interaction must not become a link underline):
 *   - `:not(:has(img))` — an image link (the `[caption]` / `figure` anchor the author
 *     wrapped around a screenshot) is a media target, not prose. `:has()` is already
 *     an accepted, documented pattern in this theme (see footer.css). Where a browser
 *     lacks `:has()`, the `:not(...)` chain is simply dropped as a whole, so the
 *     image-link exclusion degrades to "the other exclusions still apply" — no link
 *     is ever left with the old underline visible, and no image link grows a box.
 *   - the P0 gate / `[an]` mirror anchors: `.psc-anlink`, `.psc-anlink__result`,
 *     `#psc-an-*`, `.psc-gate*` — the download controls keep their own look and must
 *     never lift on hover;
 *   - WordPress block/button CTAs (`.wp-block-button__link`, `.wp-element-button`,
 *     `.button`) — those are buttons, not prose.
 *
 * REST IS UNCHANGED except one thing: the resting `text-decoration` is removed
 * inside the prose scope, at rest, hover and visited, so the mint highlight is the
 * affordance. The hover COLOUR stays the theme's own (`--focus`), so a hovered link
 * is still legible — the mint rule is a 2px line and a low highlight, never the
 * link's text colour, exactly so contrast never depends on the mint.
 *
 * NO LAYOUT JUMP: the 2px bottom border is reserved at REST as `transparent`, so the
 * box height does not change when the visible mint border lands on hover. A multi-line
 * link keeps its box intact across line breaks via `box-decoration-break: clone`.
 */
.pm-v2 .entry-content a:not(:has(img)):not(.psc-anlink):not(.psc-anlink__result):not(.psc-gate):not([id^="psc-an-"]):not(.wp-block-button__link):not(.wp-element-button):not(.button) {
	color: var(--primary);
	text-decoration: none;
	border-bottom: 2px solid transparent;
	-webkit-box-decoration-break: clone;
	box-decoration-break: clone;
	/* Keep the site's short, uniform motion for the colour swap only; the highlight
	   is a paint, not a layout change, so it never needs a transition of its own. */
	transition: color var(--pm-ease);
}

.pm-v2 .entry-content a:not(:has(img)):not(.psc-anlink):not(.psc-anlink__result):not(.psc-gate):not([id^="psc-an-"]):not(.wp-block-button__link):not(.wp-element-button):not(.button):hover,
.pm-v2 .entry-content a:not(:has(img)):not(.psc-anlink):not(.psc-anlink__result):not(.psc-gate):not([id^="psc-an-"]):not(.wp-block-button__link):not(.wp-element-button):not(.button):focus-visible {
	color: var(--primary-hover);
	border-bottom-color: var(--primary);
	-webkit-box-shadow: none;
	box-shadow: inset 0 -0.5em 0 0 color-mix(in srgb, var(--primary-soft) 80%, transparent);
}

/*
 * THE SAME RECIPE FOR THE ARCHIVE DESCRIPTION — the SECOND and last place it belongs.
 *
 * `.pm-surface__description` is the category / tag / author introduction: real editorial
 * prose the site owner writes, often with internal links in it (surfaces.css explains why
 * that copy is shown in full rather than clamped). A link inside it is a link inside a
 * paragraph, which is precisely the case the mint highlight was chosen for — so this is
 * the one listing surface that keeps it, and the request named it explicitly.
 *
 * `:not(:has(img))` matches the article-body exclusion: a caption-wrapped screenshot
 * link is a media target, not prose. The 2px bottom border is reserved as `transparent`
 * at rest for the same no-layout-jump reason.
 */
/*
 * THE ARCHIVE DESCRIPTION keeps the mint recipe — the owner named it explicitly — but
 * NOT the brand-blue resting colour that came with it.
 *
 * WHY THE RESTING COLOUR CHANGED. This is the one surface where the description can hold
 * twenty-plus child links, and at rest every one of them was brand blue. That single
 * block therefore carried more blue than the rest of the page combined, which is exactly
 * the "blue is used everywhere" problem: blue stopped reading as an accent because the
 * child directory shouted it in unison.
 *
 * At rest the links are body-coloured, medium-weight, and carry a QUIET UNDERLINE.
 *
 * WHY THE UNDERLINE IS NOT OPTIONAL. The first version of this rule dropped the resting
 * underline along with the blue, on the reasoning that a directory needs no underline.
 * That broke the one rule the recipe must not break: with neither a distinct colour nor
 * a rule, a link is identifiable ONLY by hovering it — a colour-only affordance in
 * reverse, and invisible to touch users entirely. Measured after that change: link
 * `rgb(26,29,33)/500` against paragraph `rgb(92,102,112)/400`. Distinguishable, but only
 * to someone who already knows which is which.
 *
 * The underline is therefore restored at rest and drawn on the text colour at low
 * opacity — present enough that the link is obvious without hovering, light enough that
 * twenty of them do not read as a wall of rules. On hover the full mint recipe takes
 * over, so the owner's chosen treatment still lands on the link being read.
 *
 * `:not(:has(img))` matches the article-body exclusion: a caption-wrapped screenshot
 * link is a media target, not prose. The 2px bottom border is reserved as `transparent`
 * at rest for the same no-layout-jump reason.
 */
/*
 * THE SELECTOR CARRIES A SECOND CLASS ON PURPOSE — SPECIFICITY, NOT STYLE.
 *
 * `base.css` sets the site-wide floor `.pm-v2 a:not(.screen-reader-text):not(.skip-link)
 * { text-decoration: none }` and documents it as "deliberately NOT !important, so a
 * component can still opt back in on purpose". It does not actually work that way: the
 * two `:not(.class)` arguments give that floor a specificity of (0,4,1), while
 * `.pm-v2 .pm-surface__description a:not(:has(img))` is only (0,3,1). The floor therefore
 * won on specificity and silently erased this rule's `text-decoration: underline` — the
 * archive-description links rendered with NO underline at rest, which is exactly the
 * "colour-only affordance" failure the block below says must not happen. Verified by
 * measurement: the rule matched (`a.matches()` returned true) yet computed
 * `text-decoration-line: none`.
 *
 * The opt-in is therefore written with a matching number of class hooks — `.pm-v2
 * .pm-surface__description.taxonomy-description` — which is (0,4,1) and ties with the
 * floor. A tie is won by the LATER rule, and interactions.css is enqueued last, so the
 * underline lands. `.taxonomy-description` is not decoration invented for this: it is the
 * class the archive header has always printed on this exact element.
 */
.pm-v2 .pm-surface__description.taxonomy-description a:not(:has(img)) {
	color: var(--text);
	font-weight: 500;
	text-decoration: underline;
	text-decoration-color: color-mix(in srgb, var(--text) 30%, transparent);
	text-underline-offset: 3px;
	text-decoration-thickness: 1px;
	border-bottom: 2px solid transparent;
	-webkit-box-decoration-break: clone;
	box-decoration-break: clone;
	transition: color var(--pm-ease);
}

.pm-v2 .pm-surface__description.taxonomy-description a:not(:has(img)):hover,
.pm-v2 .pm-surface__description.taxonomy-description a:not(:has(img)):focus-visible {
	color: var(--primary-hover);
	text-decoration-color: transparent;
	border-bottom-color: var(--primary);
	-webkit-box-shadow: none;
	box-shadow: inset 0 -0.5em 0 0 color-mix(in srgb, var(--primary-soft) 80%, transparent);
}

/* ========================================================== card refinement == */

/*
 * The software card grid tile. The component's own `card.css` owns the border, the
 * radius and the rest/hover colour; this only COMPLETES the motion the redesign
 * asked for — a 2px lift with a soft, brand-tinted shadow instead of a flat border
 * colour swap, so a hovered tile reads as picked up rather than merely outlined.
 *
 * `transform` never affects the grid track, so a hovered tile cannot shift its
 * neighbours. The tint is `color-mix` of the brand primary at a low percentage:
 * one hue, no second accent, no gradient.
 */
.pm-v2 .pm-software-card__link {
	transition: border-color var(--pm-ease), background-color var(--pm-ease), transform var(--pm-ease), box-shadow var(--pm-ease);
}

.pm-v2 .pm-software-card__link:hover,
.pm-v2 .pm-software-card__link:focus-visible {
	transform: translateY(-2px);
	box-shadow: 0 6px 18px color-mix(in srgb, var(--primary) 14%, transparent);
}

/*
 * The related-software tile on the detail page. Same recipe as the software card so
 * the two card grids behave identically — the mapping in `.zcode/artifacts/hover-library.md`
 * already claimed they agree, and this rule is what makes that true. `detail.css` keeps
 * the tile's geometry and colour; this adds only the motion, so the two never disagree.
 */
.pm-v2 .pm-related-card__link {
	transition: border-color var(--pm-ease), background-color var(--pm-ease), transform var(--pm-ease), box-shadow var(--pm-ease);
}

.pm-v2 .pm-related-card__link:hover,
.pm-v2 .pm-related-card__link:focus-visible {
	transform: translateY(-2px);
	box-shadow: 0 6px 18px color-mix(in srgb, var(--primary) 14%, transparent);
}

/* ================================== list rows — the title underline is GONE === */

/*
 * The list row's TITLE used to grow an animated underline from the left on hover. That
 * rule is REMOVED, not corrected — see the user's report this revision answers: a rule
 * appearing under a heading is the dated affordance the request named, and a nicer
 * version of a dated thing is still a dated thing.
 *
 * WHAT CARRIES THE STATE INSTEAD, and why nothing is lost:
 *   - the row steps back onto a barely-there tint (archive.css / home.css);
 *   - the title takes the brand colour;
 *   - a small cue arrow at the end of the meta line steps forward.
 *
 * Both the tint and the arrow are non-colour cues, so WCAG 1.4.1 is satisfied with no
 * rule under the heading — which is what the owner objected to in the first place.
 */

/* ============================================== list rows: no edge anywhere ===== */

/*
 * THE HOMEPAGE ROW CARRIES NO EDGE EITHER.
 *
 * This block used to give `.pm-home__post` the same left-accent pseudo and raised plate
 * the archive row had. When the archive row's edge was removed, this one was missed —
 * and because this file loads LAST and is the declared owner of the motion, the homepage
 * kept drawing a growing left bar long after `archive.css` had stopped. Measured from the
 * rendered page after the archive fix: the homepage rows still showed one.
 *
 * The lesson is recorded because it is the failure mode this file invites: the component
 * sheets own geometry and this file owns motion, so a pattern can exist in TWO places and
 * removing it from one leaves the other live. `home.css` and this file must be checked
 * together for any change to a row's hover.
 *
 * The row keeps only its tint here; `home.css` owns the geometry, and neither file draws
 * a pseudo-element, a border-left, a shadow or a transform on the row at any state.
 */
.pm-v2 .pm-home__post {
	transition: background-color var(--pm-ease);
}

.pm-v2 .pm-home__post:hover,
.pm-v2 .pm-home__post:focus-within {
	background-color: var(--bg);
}

/*
 * The homepage row's cue arrow, matching the archive row so the two list styles describe
 * one interaction. `home.css` positions the meta line; this only moves the arrow.
 */
.pm-v2 .pm-home__post-cue {
	display: inline-block;
	margin-left: var(--sp-1);
	color: var(--muted);
	opacity: 0.55;
	transition: transform var(--pm-ease), color var(--pm-ease), opacity var(--pm-ease);
}

.pm-v2 .pm-home__post:hover .pm-home__post-cue,
.pm-v2 .pm-home__post:focus-within .pm-home__post-cue {
	transform: translateX(4px);
	color: var(--primary);
	opacity: 1;
}

/* =============================================== touch (no fine hover) ====== */

/*
 * On a device whose PRIMARY input cannot hover (`hover: none` — a phone, a tablet in
 * touch mode), the pointer never rests on a target, so a transform that only exists
 * on `:hover` is either inert or fires on the tap's synthetic hover. Drop the NEW
 * movement here for EVERY state that paints it — `:hover`, `:focus-visible` (a touched
 * link can match focus-visible) and `:active` — for every recipe class this file moved:
 * the logo, the CTA, the software card and the related card. Everything that still
 * communicates state on a tap — colour, border, background, underline — is kept.
 *
 * The menu underline is NOT turned on here: the menu link already has GP's own
 * active/current affordance, and a permanent underline on every menu item would be a
 * new resting style, not a hover one. Its transition is neutralised in the block below.
 */
@media (hover: none) {
	.pm-v2 .pm-detail__cta:is(:hover, :focus-visible, :active):not(:disabled):not([aria-disabled="true"]),
	.pm-v2 .pm-software-card__link:is(:hover, :focus-visible),
	.pm-v2 .pm-related-card__link:is(:hover, :focus-visible),
	.pm-v2 .pm-post-item:is(:hover, :focus-within)::before,
	.pm-v2 .pm-home__post:is(:hover, :focus-within)::before {
		transform: none;
	}

	/* The row plate is a paint, not travel — it stays. Only the edge's growth, which is
	   the one moving part inside the row, is neutralised above. */
	.pm-v2 .pm-post-item:is(:hover, :focus-within),
	.pm-v2 .pm-home__post:is(:hover, :focus-within) {
		box-shadow: none;
	}
}

/* ============================================== reduced motion (scoped) ===== */

/*
 * Drop THIS FILE'S new motion for a visitor who asked for less of it. The reset covers
 * every state that paints the motion — `:hover`, `:focus-visible` and `:active` — for
 * every recipe class this file moved, so a keyboard visitor who asked for reduced
 * motion gets the same stillness a pointer visitor does (the earlier version reset
 * `:hover` only and left `:focus-visible` moving).
 *
 * There is deliberately NO `transform: none` over `.pm-v2 *`: GeneratePress rotates
 * its submenu arrow with a transform, and a blanket reset would break a behaviour that
 * is not this file's to touch. Only the named recipes are reset. Under this preference
 * the underline and the colour affordances remain, so nothing becomes unreachable.
 */
@media (prefers-reduced-motion: reduce) {
	.pm-v2 .pm-software-card__link:is(:hover, :focus-visible),
	.pm-v2 .pm-related-card__link:is(:hover, :focus-visible) {
		transform: none;
	}

	.pm-v2 .pm-detail__cta:is(:hover, :focus-visible, :active):not(:disabled):not([aria-disabled="true"]) {
		transform: none;
		box-shadow: none;
	}

	.pm-v2 .pm-post-item,
	.pm-v2 .pm-post-item__link,
	.pm-v2 .pm-home__post,
	.pm-v2 .pm-home__post-link {
		transition: color var(--pm-ease);
	}

	/* The cue arrows keep their colour/opacity change (a paint) but not the travel, so a
	   reduced-motion reader still sees the state change without the row moving. */
	.pm-v2 .pm-post-item__cue,
	.pm-v2 .pm-home__post-cue {
		transition: color var(--pm-ease), opacity var(--pm-ease);
	}

	/* The article prose link's only motion is its colour swap; the mint highlight is a
	   paint and needs no motion, so nothing is lost by leaving it. */
	.pm-v2 .entry-content a:not(:has(img)):not(.psc-anlink):not(.psc-anlink__result):not(.psc-gate):not([id^="psc-an-"]):not(.wp-block-button__link):not(.wp-element-button):not(.button) {
		transition: none;
	}
}

/* ================================================================== MINT LINK == */

/*
 * THE MINT HIGHLIGHT IS FOR ARTICLE PROSE ONLY.
 *
 * HISTORY — read this before extending the recipe, it was narrowed twice on purpose.
 *
 * The mint recipe (from the author's Pen, https://codepen.io/BinLate/pen/WNWVjaE) was
 * first written for `.entry-content` alone. A later pass fanned it out to every other
 * listing link "for consistency": the category name under a list row, the widget links
 * in the sidebar and footer, the related-scope link, the detail identity link and the
 * rail's short-name link all got the same 2px mint border plus the inset highlight.
 *
 * The user rejected THAT: the effect is right for a link inside a wall of prose, and
 * wrong for a small meta link or a widget item, where a pale green slab appearing under
 * a 13px label does not read as "this is a link you are following", it just reads as a
 * bug. The request was specific — remove it from the category/tag-style CONTENT links
 * and from the widgets — so the rule is now scoped to prose only.
 *
 * WHAT STILL HAS IT: `.entry-content a` (the article body, see the block above). That is
 * the entire scope. The list-row TITLES keep their own half-line highlight further down
 * (a different, subtler treatment) and are NOT this block.
 *
 * WHAT DELIBERATELY DOES NOT: every meta/label/widget link. They keep the plain,
 * long-established affordance instead — the brand colour on hover — because a colour
 * change on a small label is legible, immediate, and does not paint a slab over the row.
 * The theme's own component sheets (archive.css, home.css, rail.css, detail.css) already
 * declare those hover colours, so nothing here has to replace them.
 *
 * `.pm-download__mirror-link` was never in scope: it is a download CONTROL, it carries
 * the sheen sweep, and a text highlight on a button would relabel it as prose. The block
 * buttons and the P0 gate controls were excluded for the same reason.
 */

/*
 * THE MINT HIGHLIGHT IS NOW *ONLY* FOR PROSE AND TAXONOMY DESCRIPTIONS.
 *
 * This block used to give every list-row TITLE, every card title and the rail's short
 * name a half-line mint highlight. The user rejected that with a screenshot of the
 * homepage, where the third card's title ("Windows 11 AIO … Office 2021 Pro Plus")
 * showed the highlight and the others did not, and set the rule out in full:
 *
 *   "chỉ dùng hiệu ứng này cho link nằm bên trong nội dung mô tả chuyên mục, mô tả tag,
 *    mô tả author, v...v... nội dung bài viết thôi, còn tất cả các nơi khác thì không"
 *
 * So the recipe is scoped to two things and nothing else:
 *
 *   1. `.entry-content a`          — the article body (declared above);
 *   2. `.pm-surface__description a` — the archive description, i.e. the category / tag /
 *      author description the same request names. That copy is real editorial prose
 *      written by the site owner, so a prose link treatment is exactly right in it.
 *
 * DELIBERATELY EXCLUDED, and every one of these was previously highlighted:
 *
 *   - list-row titles       (`.pm-post-item__link`, `.pm-home__post-link`);
 *   - card titles           (`.pm-software-card__title`, `.pm-related-card__link`);
 *   - the rail's short name (`.pm-rail__name`);
 *   - every meta/widget link (already removed in the previous pass).
 *
 * A TITLE IS NOT PROSE. It is a destination label on a scanning surface, where a slab
 * of colour behind the text competes with the row's own hover treatment instead of
 * adding to it. Those rows already say "this one" three other ways — the raised plate,
 * the growing brand edge and the colour promotion — so nothing is lost by dropping it,
 * and the homepage stops showing one highlighted title among five plain ones.
 */

/*
 * The reduced-motion note that used to live here is gone with the block: the remaining
 * mint recipe (`.entry-content a`) declares its own `transition: none` under the
 * preference, and the taxonomy-description links carry no transition from this file.
 */
/* ================================================================ polish ==== */

/*
 * This block is the second pass over the affordances the first library pass left plain.
 * Everything here is a RESTING or HOVER appearance on an element that already exists —
 * no new markup, no new colour, no new font, no JavaScript. The brand scale is the only
 * palette used, and every motion is on `var(--pm-ease)` like the rest of the file.
 */

/* ------------------------------------------------------ pagination lift ----- */

/*
 * The pagination pills already swap border/colour on hover. A small lift with the same
 * brand-tinted shadow the cards use makes a page target feel like the tile it sits next
 * to, instead of a flat box. `:active` returns it to the plane, matching the CTA. */
.pm-v2 .pm-pagination .page-numbers a {
	transition: border-color var(--pm-ease), color var(--pm-ease), background-color var(--pm-ease), transform var(--pm-ease), box-shadow var(--pm-ease);
}

.pm-v2 .pm-pagination .page-numbers a:hover,
.pm-v2 .pm-pagination .page-numbers a:focus-visible {
	transform: translateY(-2px);
	box-shadow: 0 4px 12px color-mix(in srgb, var(--primary) 14%, transparent);
}

.pm-v2 .pm-pagination .page-numbers a:active {
	transform: translateY(0);
	box-shadow: none;
}

/* --------------------------------------------------------- page headings ---- */

/*
 * The surface title (archive / search / page H1). A short brand rule under the heading
 * gives the page an opener and separates the name from the description without the
 * hairline border the header block already draws — the rule is deliberately BOUNDED
 * (a 56px bar), so it reads as an accent rather than as a second divider, and the
 * underline the reader sees is the heading's own when the heading is a link.
 */
.pm-v2 .pm-surface__title {
	position: relative;
	padding-bottom: var(--sp-3);
}

.pm-v2 .pm-surface__title::after {
	content: "";
	position: absolute;
	left: 0;
	bottom: 0;
	width: 56px;
	height: 3px;
	border-radius: 2px;
	background-color: var(--primary);
}

/*
 * TERM CHIPS. The category/tag/author archives list their terms as an inline row of
 * links (`pm-archive__terms`); as plain text links they read as a sentence, not as a
 * set of destinations. A chip — surface fill, hairline border, pill radius — makes each
 * one an obvious target and gives the row a shape. On hover/focus the border takes the
 * brand colour, the text follows, and the chip lifts 1px, which is the same vocabulary
 * the cards and pagination use at a smaller scale.
 *
 * The row's own gap comes from the template; only the chip's padding and radius are set
 * here. `:focus-visible` gets the theme ring from base.css on top of the border change.
 */
.pm-v2 .pm-archive__terms a {
	display: inline-block;
	padding: 2px var(--sp-3);
	border: 1px solid var(--border);
	border-radius: 999px;
	background-color: var(--surface);
	color: var(--text);
	text-decoration: none;
	transition: border-color var(--pm-ease), color var(--pm-ease), transform var(--pm-ease), box-shadow var(--pm-ease);
}

.pm-v2 .pm-archive__terms a:hover,
.pm-v2 .pm-archive__terms a:focus-visible {
	border-color: var(--primary);
	color: var(--primary);
	transform: translateY(-1px);
	box-shadow: 0 3px 10px color-mix(in srgb, var(--primary) 14%, transparent);
}

/* ------------------------------------------------------------ reduced motion - */

@media (prefers-reduced-motion: reduce) {
	.pm-v2 .pm-pagination .page-numbers a:is(:hover, :focus-visible, :active),
	.pm-v2 .pm-archive__terms a:is(:hover, :focus-visible) {
		transform: none;
	}
}

/* --------------------------------------------------------------- no hover ---- */

@media (hover: none) {
	.pm-v2 .pm-pagination .page-numbers a:is(:hover, :focus-visible, :active),
	.pm-v2 .pm-archive__terms a:is(:hover, :focus-visible) {
		transform: none;
	}
}
