/*
Theme Name: Marin
Theme URI: https://imagewize.com/themes/marin
Author: Jasper Frumau
Author URI: https://imagewize.com
Description: Marin is a lean full-site-editing theme for WooCommerce stores. It ships a design system (theme.json), WooCommerce block templates, and style variations — no theme-level patterns. Content is composed directly from blocks. Built to speed up client e-commerce builds.
Requires at least: 6.6
Tested up to: 7.1
Requires PHP: 8.0
Version: 1.4.0
License: GNU General Public License v3 or later
License URI: https://www.gnu.org/licenses/gpl-3.0.html
Text Domain: marin
Tags: e-commerce, full-site-editing, custom-colors, custom-logo, custom-menu, editor-style, featured-images, grid-layout, template-editing, translation-ready, wide-blocks

Marin WordPress Theme, (C) 2026 Jasper Frumau
Marin is distributed under the terms of the GNU GPL v3 (or later).
*/

/*
 * The design system lives in theme.json — this file only holds what
 * theme.json cannot express: sticky positioning, pseudo-classes, media
 * queries, and overrides of core block styles that ship `!important`.
 *
 * 1. Template parts (global)
 * 2. Header
 *    2.1 Sticky masthead
 *    2.2 Scroll edge (light header)
 *    2.3 Wordmark and logo
 *    2.4 Header search
 *    2.5 Navigation underline
 *    2.6 Overlay navigation
 *    2.7 Account icon
 * 3. Footer
 * 4. Utilities
 *    4.1 Eyebrow
 * 5. Content rhythm
 * 6. Single post
 *    6.1 Post meta line
 *    6.2 Two-column article and sticky sidebar
 *    6.3 Prose
 *    6.4 Post tail and author card
 *    6.5 Sidebar widgets
 *    6.6 Related posts
 *    6.7 Comments
 *    6.8 Reading-progress bar
 * 7. Motion
 */

/* -------------------------------------------------------------------------
 * 1. Template parts (global)
 * ------------------------------------------------------------------------- */

/*
 * Core's `:where(.wp-site-blocks) > *` global style adds a 24px
 * margin-block-start to every top-level block, including the
 * wp-block-template-part wrapper WordPress injects around header/footer —
 * not to the .marin-header--dark/.foot block inside it, so setting
 * margin on those directly has no effect on the wrapper. Reset it for all
 * template parts generally (same fix as Imagewize's Elayne theme uses),
 * since no template part should carry the inter-block content gap.
 */
.wp-site-blocks > .wp-block-template-part {
	margin-block-start: 0;
}

/*
 * Pin the footer to the bottom on short pages, where it would otherwise float
 * mid-viewport with dead space beneath it.
 *
 * Safe to make `.wp-site-blocks` a flex column: its children stretch to full
 * width by default, so the constrained-layout margins that produce alignwide
 * and alignfull still resolve against the same box they did before.
 */
.wp-site-blocks {
	display: flex;
	flex-direction: column;
	min-height: 100vh;
}

/*
 * `main` takes up the slack. Its background is transparent, so on an ordinary
 * prose page the stretch is indistinguishable from the content area around it —
 * base on base, nothing to see.
 */
.wp-site-blocks > main {
	flex: 1 0 auto;
}

/*
 * The WooCommerce coming-soon template wraps its `main` in the block's own
 * `.wp-block-woocommerce-coming-soon` div, so `main` is no longer a direct child
 * of `.wp-site-blocks` and the rule above cannot reach it. The wrapper is the
 * direct child instead, and — with no background of its own — it stands in for
 * `main` here: growing it stretches base on base, invisibly, and the footer
 * still settles at the bottom on a short page.
 */
.wp-site-blocks > .wp-block-woocommerce-coming-soon {
	flex: 1 0 auto;
}

/*
 * Unless the page ends in a full-bleed section, where that same transparent
 * stretch reads as a base-coloured strip below the section's own colour. Then
 * the section itself should absorb the space instead, so its background simply
 * continues to the footer.
 *
 * Growing the footer rather than `main` was the other way to hide the strip, but
 * it is the same region either way — only the colour changes — and a viewport's
 * worth of it in the footer's tertiary reads as an enormous footer on a short
 * page (622px of it on the Sample Page). Absorbing the space is what removes it.
 *
 * Scoped with `:has()` rather than applied to every page for two reasons: `float`
 * is ignored on flex items, so an `alignleft`/`alignright` image inside
 * `entry-content` would stop wrapping its text — a real cost on prose pages, and
 * one they get nothing back for, since their filler is already invisible. Pages
 * that end in an `alignfull` section are section-built and do not float. Where
 * `:has()` is unsupported the chain simply never engages and the base-coloured
 * strip comes back, which is the unstyled behaviour anyway.
 */
.wp-site-blocks > main:has(> .entry-content > :last-child.alignfull),
.wp-site-blocks > main:has(> .entry-content > :last-child.alignfull) > .entry-content {
	display: flex;
	flex-direction: column;
}

.wp-site-blocks > main:has(> .entry-content > :last-child.alignfull) > .entry-content,
.wp-site-blocks > main:has(> .entry-content > :last-child.alignfull) > .entry-content > :last-child {
	flex: 1 0 auto;
}

/* -------------------------------------------------------------------------
 * 2. Header
 * ------------------------------------------------------------------------- */

/* 2.1 Sticky masthead
 * ------------------------------------------------------------------------- */

/*
 * Both variants stick. The rules below are scoped to `.marin-header` rather
 * than `.marin-header--dark` wherever they are tonal-neutral, so the light
 * header is a colour alternative rather than a header with features missing.
 */
.marin-header {
	position: sticky;
	top: 0;
	z-index: 50;
}

/*
 * When the header part renders inside a wrapper element (template-part
 * `tagName`, or the block editor's part boundary), the wrapper is only as
 * tall as the header itself, so a sticky child has no scroll range to move
 * within and never sticks. Make the wrapper the sticky element in that case.
 */
.wp-block-template-part:has(> .marin-header) {
	position: sticky;
	top: 0;
	z-index: 50;
}

/* 2.2 Scroll edge (light header)
 * ------------------------------------------------------------------------- */

/*
 * The light header sits on `base` and so does the page under it, so a resting
 * border has no tonal change to describe — it reads as a scratch rather than a
 * boundary. Instead the edge appears only once the page has moved, when the
 * sticky masthead genuinely is above something.
 *
 * Done with a scroll-driven animation rather than a scroll listener because the
 * theme ships no JavaScript. Where `scroll()` is unsupported the header simply
 * stays flush, which is the rest state we are choosing anyway — so no fallback
 * is needed. The dark header is excluded: it carries its own light hairline in
 * the block markup, and a `border-light` shadow under it would read as a seam.
 *
 * The colours are literal because a keyframe needs the transparent stop to be
 * the same colour at zero alpha: `#e5ded2` is `border-light`, `#211c1a` is
 * `contrast`. Same hex-with-alpha idiom the dark header's border uses.
 */
@supports (animation-timeline: scroll()) {
	.marin-header:not(.marin-header--dark) {
		animation: marin-header-edge linear both;
		animation-range: 0 8px;
		animation-timeline: scroll(root block);
	}
}

@keyframes marin-header-edge {
	from {
		box-shadow:
			0 1px 0 0 #e5ded200,
			0 8px 24px -18px #211c1a00;
	}

	to {
		box-shadow:
			0 1px 0 0 #e5ded2,
			0 8px 24px -18px #211c1a80;
	}
}

/* 2.3 Wordmark and logo
 * ------------------------------------------------------------------------- */

.marin-header .wp-block-site-title a {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 800;
	font-size: 1.15rem;
	letter-spacing: -0.03em;
	text-decoration: none;
}

.marin-header .wp-block-site-title a:hover {
	text-decoration: none;
}

/* For the Marin marketing site: hide logo when using text wordmark */
body .marin-header--dark .wp-block-site-logo {
	display: none;
}

/* 2.4 Header search
 * ------------------------------------------------------------------------- */

/*
 * Icon-only product search (core/search, `post_type=product`). It opens inline
 * when focused, so the resting header stays as tidy as the account and cart
 * icons next to it. Colour follows the header's text colour in both variants.
 */
.marin-header .wp-block-search .wp-block-search__button.wp-element-button {
	background: transparent;
	border: 0;
	border-radius: 0;
	box-shadow: none;
	color: inherit;
	padding: 0.25rem;
}

.marin-header .wp-block-search .wp-block-search__button.wp-element-button:hover {
	background: transparent;
	color: inherit;
	opacity: 0.7;
}

.marin-header .wp-block-search {
	margin: 0;
}

.marin-header .wp-block-search__inside-wrapper {
	align-items: center;
}

.marin-header .wp-block-search__button svg {
	fill: currentColor;
}

/* 2.5 Navigation underline
 * ------------------------------------------------------------------------- */

/*
 * Wipe-in underline on hover, held open for the current page. `currentColor`
 * rather than `primary` so the same rule serves both headers — primary against
 * the dark header's `main` background is too low-contrast to read as a marker.
 *
 * Hooked on `[aria-current="page"]`, which core puts on the link itself, rather
 * than the `.current-menu-item` class it puts on the `li`. Scoped to the
 * top-level container so submenu items do not pick it up.
 */
.marin-header .wp-block-navigation__container > .wp-block-navigation-item > .wp-block-navigation-item__content {
	position: relative;
	text-decoration: none;
}

.marin-header .wp-block-navigation__container > .wp-block-navigation-item > .wp-block-navigation-item__content::after {
	background: currentColor;
	bottom: -0.25em;
	content: "";
	height: 2px;
	left: 0;
	position: absolute;
	right: 0;
	transform: scaleX(0);
	transform-origin: left;
	transition: transform 0.16s ease;
}

.marin-header .wp-block-navigation__container > .wp-block-navigation-item > .wp-block-navigation-item__content:hover::after,
.marin-header .wp-block-navigation__container > .wp-block-navigation-item > .wp-block-navigation-item__content[aria-current="page"]::after {
	transform: scaleX(1);
}

/*
 * The mobile overlay stacks the same links full-width, where an underline
 * spanning the whole row reads as a divider rather than a marker.
 */
.marin-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content::after {
	content: none;
}

/* 2.6 Actions cluster order
 * ------------------------------------------------------------------------- */

/*
 * `.marin-header__actions` (parts/header.html, parts/header-dark.html)
 * holds the icon group (search, account, cart) and the navigation block in that
 * source order, so the hamburger renders last — rightmost, with the icons
 * immediately before it — which is what a collapsed header (below 1024px, see
 * §2.7) wants.
 *
 * Once the navigation goes inline at 1024px+, that same order would put the
 * link row after the icons, which reads backwards for a desktop
 * masthead — so only there, pull it back in front with `order`.
 */
@media (min-width: 1024px) {
	.marin-header__actions .wp-block-navigation {
		order: -1;
	}
}

/* 2.7 Overlay navigation
 * ------------------------------------------------------------------------- */

/*
 * Raise the overlay breakpoint from core's 600px to 1024px.
 *
 * `overlayMenu: "mobile"` only takes the three keywords, so the width at which
 * the navigation collapses is not configurable — core hardcodes it in two rules
 * inside `@media (min-width: 600px)`: one flips `.wp-block-navigation__responsive-container`
 * from the hidden fixed-position overlay to an inline block, the other hides the
 * hamburger. Between 600px and 1024px that left the inline menu competing with
 * the wordmark and the search, cart and account icons, and the row wrapped — a
 * 105px-tall masthead on a tablet.
 *
 * Restoring those two declarations to their base values across the band is the
 * whole fix: everything else about the overlay, including the fixed positioning
 * it needs when open, already lives outside the media query.
 *
 * 1024px rather than a rounder 960px because the masthead's own contents decide
 * it: this menu's six items plus the wordmark and icons measured 973px, so
 * at 960px the row still wrapped. A longer menu would want this raised again.
 */
@media (min-width: 600px) and (max-width: 1023px) {
	.marin-header .wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) {
		display: none;
	}

	.marin-header .wp-block-navigation__responsive-container-open:not(.always-shown) {
		display: flex;
	}
}

/*
 * The open overlay is a full-screen menu, so it is laid out as one: a
 * left-aligned, full-width list of large display-face links separated by
 * hairlines, rather than core's shrink-wrapped, right-anchored list of
 * body-size links on a white screen.
 *
 * Core's `align-items: flex-end` on the container-content shrink-wraps the list
 * and pins it to the right edge, which also made it fragile — a longer label
 * or a larger text-size setting pushed the list past the padded edge and the
 * link read as clipped. Stretching the list to the full padded width removes
 * that: it can never be wider than the box it is aligned in.
 */
.marin-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
	align-items: stretch;
	padding-top: 2.5rem;
}

.marin-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container {
	align-items: stretch;
	gap: 0;
	text-align: left;
	width: 100%;
}

.marin-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item {
	align-items: stretch;
	border-bottom: 1px solid var(--wp--preset--color--border-light);
	width: 100%;
}

.marin-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content {
	display: block;
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--large);
	padding: 0.9rem 0;
}

/*
 * Core paints the overlay white (`#fff`) whenever the navigation block has no
 * background of its own, which leaves it a stark sheet next to the cream page
 * and the header it slides out of. Use the theme's own `base`.
 *
 * One class more than core's `.wp-block-navigation:not(.has-background)
 * .wp-block-navigation__responsive-container.is-menu-open`, so no !important.
 * Scoped to `.is-menu-open` for the same reason as the dark-header rule below:
 * above the breakpoint the same element renders the inline desktop menu.
 */
.marin-header .wp-block-navigation:not(.has-background) .wp-block-navigation__responsive-container.is-menu-open {
	background-color: var(--wp--preset--color--base);
}

/*
 * Core insets the overlay (and, with it, the close button pinned to its
 * top-right corner) from the screen edge via the `--wp--style--root--padding-*`
 * custom properties that `settings.useRootPaddingAwareAlignments` is meant to
 * supply. Here they resolve to nothing usable, so the overlay's own padding
 * collapses to 0 and the close button lands flush against the literal
 * top-right corner of the screen — well above and outside of where the
 * hamburger it replaces actually sits.
 *
 * Give the overlay the header's own padding directly instead of relying on
 * that chain, so the close button opens right where the hamburger was. The
 * left and bottom insets match, so the link list sits inside the same margins.
 */
.marin-header .wp-block-navigation__responsive-container.is-menu-open {
	padding: var(--wp--preset--spacing--small);
}

/*
 * The dark header's navigation has no background of its own, so core's
 * `.wp-block-navigation:not(.has-background) …is-menu-open` rule paints the
 * mobile overlay white — while the block's `textColor: "base"` keeps the
 * links and close button white too, leaving the open menu unreadable.
 *
 * Scoped to `.is-menu-open`: with `overlayMenu: "mobile"` the container
 * carries no `hidden-by-default` class, so above 600px core reuses that same
 * element to render the inline desktop nav. An unscoped rule here would
 * darken those desktop links against the dark masthead.
 *
 * !important needed: the navigation markup carries has-base-color, and core
 * emits `.has-base-color { color: ... !important }`.
 */
.marin-header--dark .wp-block-navigation__responsive-container.is-menu-open,
.marin-header--dark .wp-block-navigation__responsive-container.is-menu-open * {
	color: var(--wp--preset--color--main) !important;
}

/* 2.8 Account icon
 * ------------------------------------------------------------------------- */

/*
 * The customer-account block renders as a link, so it picks up the global
 * `primary` link colour — rose, which is too low-contrast on the dark header's
 * `main` background and reads as a different element from the mini cart beside
 * it. Inherit the surrounding header text colour instead, so the account icon
 * follows the cart in both headers: `base` on the dark header, `contrast` on
 * the light one. The icon's SVG paints in `currentColor`, so it comes along.
 */
.marin-header .wp-block-woocommerce-customer-account a {
	color: inherit;
}

/*
 * Size the account icon. WooCommerce ships its sizing rule against
 * `.wc-block-customer-account__account-icon`, but the block actually renders
 * the SVG with `class="icon"` (its `iconClass` default) — the two never match,
 * so the icon collapses to zero and is invisible in every display mode. Give
 * it an explicit size here; the `:not()` leaves the dropdown caret, which
 * carries its own dimensions, alone. `em` so it tracks the header font size,
 * matching WooCommerce's intended 1.5em.
 */
.marin-header .wp-block-woocommerce-customer-account svg:not(.wc-block-customer-account__caret) {
	height: 1.5em;
	width: 1.5em;
}

/* -------------------------------------------------------------------------
 * 3. Footer
 * ------------------------------------------------------------------------- */

/* Match redesign mockup */
.foot {
	background-color: var(--wp--preset--color--tertiary);
}

.foot .shell {
	display: flex;
	flex-wrap: wrap;
	gap: 1.5rem;
	justify-content: space-between;
	align-items: center;
	font-size: 0.85rem;
	color: var(--wp--preset--color--secondary);
}

.foot .wp-block-navigation {
	margin: 0;
	padding: 0;
}

.foot .wp-block-navigation__container {
	margin: 0;
	padding: 0;
	list-style: none;
}

.foot .wp-block-navigation-item {
	margin: 0;
	padding: 0;
}

.foot a {
	text-decoration: none;
}

.foot a:hover {
	color: var(--wp--preset--color--primary);
}

/* 3.1 Mobile footer layout
 * ------------------------------------------------------------------------- */

/*
 * The footer navigation never collapses into a hamburger — the block itself
 * sets `overlayMenu: "never"` (see parts/footer.html), so core renders a plain
 * list at every width and emits no overlay markup. All that's left to do here
 * is stack the footer on narrow screens.
 */
@media (max-width: 600px) {
	.foot .shell {
		flex-direction: column;
		align-items: flex-start;
		gap: 1rem;
	}

	/*
	 * With no assigned menu the nav falls back to a page list, which core nests
	 * as `__container > .wp-block-page-list > li` — so both levels need to
	 * stack, not just the outer container.
	 *
	 * align-items is required too: core defaults `--navigation-layout-align` to
	 * `center` for a row, and once the direction flips to column that variable
	 * governs the horizontal axis, centering each link inside the nav's
	 * shrink-to-fit width instead of aligning them left.
	 */
	.foot .wp-block-navigation__container,
	.foot .wp-block-navigation .wp-block-page-list {
		align-items: flex-start;
		flex-direction: column;
		gap: 0.5rem;
		width: 100%;
	}
}

/* -------------------------------------------------------------------------
 * 4. Utilities
 * ------------------------------------------------------------------------- */

/* 4.1 Eyebrow
 * ------------------------------------------------------------------------- */

/*
 * The theme's one repeated structural device: a mono, letter-spaced label
 * introduced by a short rule. Add it as a class on any block that carries a
 * short piece of text — a paragraph, a post-terms block — to mark a section
 * without spending a heading on it.
 *
 * theme.json can't express it: the leading rule is a pseudo-element, and the
 * class has to be available to arbitrary blocks rather than to one block type.
 */
.marin-eyebrow {
	align-items: baseline;
	color: var(--wp--preset--color--main-accent);
	display: flex;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--xx-small);
	font-weight: 600;
	gap: 0.6rem;
	letter-spacing: 0.14em;
	line-height: 1.4;
	text-transform: uppercase;
}

.marin-eyebrow::before {
	background: currentColor;
	content: "";
	flex: none;
	height: 1px;
	translate: 0 -0.28em;
	width: 1.5rem;
}

.marin-eyebrow a {
	color: inherit;
	text-decoration: none;
}

.marin-eyebrow a:hover {
	color: var(--wp--preset--color--primary);
}

/* -------------------------------------------------------------------------
 * 5. Content rhythm
 * ------------------------------------------------------------------------- */

/*
 * theme.json sets the global `blockGap` that separates blocks, and an `h2` top
 * margin that opens a section up. What it cannot express is the other half of
 * the pairing — a heading should sit *close* to the block it introduces, which
 * needs a sibling selector.
 *
 * Without this the full block gap lands between a heading and its own first
 * paragraph, and the heading reads as belonging to the text above it.
 */
.entry-content :is(h2, h3, h4, h5, h6) + * {
	margin-block-start: var(--wp--preset--spacing--small);
}

/* -------------------------------------------------------------------------
 * 6. Single post
 *
 * All scoped to the `.single` body class core adds on single posts, so none
 * of it leaks onto pages or archives. Layout primitives (the sticky sidebar,
 * the two-column collapse) and pseudo-elements live here because theme.json
 * cannot express them; colours and type reference the presets as everywhere
 * else.
 * ------------------------------------------------------------------------- */

/* 6.1 Post meta line
 * ------------------------------------------------------------------------- */

/*
 * A mono, letter-spaced byline under the title: avatar, author, date. Built
 * from core blocks (avatar / post-author-name / post-date) rather than one
 * block, so each piece can be styled and a reading-time block can slot in
 * later without disturbing the rest.
 */
.marin-post-meta {
	color: var(--wp--preset--color--main-accent);
	font-family: var(--wp--preset--font-family--mono);
	gap: 0.55rem;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.marin-post-meta .wp-block-avatar {
	line-height: 0;
}

.marin-post-meta .wp-block-avatar img {
	border-radius: 999px;
}

/* "By" reads muted (inherits the block colour); the name link takes contrast. */
.marin-post-meta .wp-block-post-author-name::before {
	content: "By ";
}

.marin-post-meta .wp-block-post-author-name a {
	color: var(--wp--preset--color--contrast);
	font-weight: 600;
	text-decoration: none;
}

/* A hairline dot separates the date from the author; the flex gap does the spacing. */
.marin-post-meta .wp-block-post-date::before {
	color: var(--wp--preset--color--sand-deep);
	content: "·";
	padding-right: 0.55rem;
}

.marin-post-meta .wp-block-post-date a,
.marin-post-meta .wp-block-post-date time {
	color: inherit;
	text-decoration: none;
}

/* The lede under the title: colour and size come from the block; cap the measure. */
.marin-post-lede {
	max-width: 56ch;
}

/* 6.2 Two-column article and sticky sidebar
 * ------------------------------------------------------------------------- */

/*
 * The content column has no width (it grows); the sidebar column is a fixed
 * 300px. Two columns that both carry a percentage summing to 100% wrap onto
 * two rows once the column gap is added, so the grow-plus-fixed pairing is
 * what keeps them on one row.
 *
 * Sticky is not a core group support, so the inner sidebar group carries a
 * class and the positioning lives here. The offset clears the sticky masthead
 * (~66px) plus a little breathing room.
 */
.single .marin-sidebar__sticky {
	position: sticky;
	top: 5.5rem;
}

/*
 * Collapse to one column below 980px — earlier than core's own 782px column
 * stacking, because the 300px sidebar beside a shrinking content column gets
 * cramped before then. Once stacked, the sidebar drops its sticky behaviour
 * (nothing to stick against in a single column) and sits below the article.
 */
@media (max-width: 980px) {
	.single .marin-article > .wp-block-column {
		flex-basis: 100%;
	}

	.single .marin-sidebar__sticky {
		position: static;
	}
}

/* 6.3 Prose
 * ------------------------------------------------------------------------- */

/*
 * theme.json and §5 handle block rhythm; these are the post-body flourishes
 * that need element or pseudo selectors: a display-face pull quote, primary
 * list markers, and a drop cap on a post that opens with a paragraph.
 */
.single .entry-content blockquote {
	border-left: 3px solid var(--wp--preset--color--primary);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--large);
	font-weight: 500;
	letter-spacing: -0.02em;
	line-height: 1.3;
	margin-inline: 0;
	padding: var(--wp--preset--spacing--small) 0 var(--wp--preset--spacing--small) var(--wp--preset--spacing--medium);
}

.single .entry-content li::marker {
	color: var(--wp--preset--color--primary);
}

/*
 * Drop cap only when the very first child is a paragraph — `:first-child`
 * rather than `:first-of-type`, so a post opening with a heading, list or
 * image is left alone rather than having a paragraph further down capitalised.
 */
.single .entry-content > p:first-child::first-letter {
	color: var(--wp--preset--color--primary);
	float: left;
	font-family: var(--wp--preset--font-family--display);
	font-size: 3.1em;
	font-weight: 700;
	line-height: 0.78;
	padding: 0.06em 0.12em 0 0;
}

/* 6.4 Post tail and author card
 * ------------------------------------------------------------------------- */

/* Tags render as mono outline pills (post-terms with an empty separator). */
.single .marin-tags {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
}

.single .marin-tags a {
	border: 1px solid var(--wp--preset--color--border-light);
	border-radius: 999px;
	color: var(--wp--preset--color--secondary);
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--xx-small);
	letter-spacing: 0.06em;
	padding: 0.35em 0.7em;
	text-decoration: none;
	transition: border-color 0.14s, color 0.14s;
}

.single .marin-tags a:hover {
	border-color: var(--wp--preset--color--primary);
	color: var(--wp--preset--color--primary);
}

/* The author card is core/post-author; background/padding/radius are block attrs. */
.single .marin-author-card {
	align-items: flex-start;
	display: flex;
	gap: var(--wp--preset--spacing--small);
}

.single .marin-author-card .wp-block-post-author__avatar img {
	border-radius: 999px;
}

.single .marin-author-card .wp-block-post-author__byline {
	color: var(--wp--preset--color--main-accent);
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--xx-small);
	letter-spacing: 0.1em;
	margin: 0;
	text-transform: uppercase;
}

.single .marin-author-card .wp-block-post-author__name {
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--medium);
	font-weight: 600;
	margin: 0.15em 0 0.3em;
}

.single .marin-author-card .wp-block-post-author__bio {
	color: var(--wp--preset--color--secondary);
	font-size: var(--wp--preset--font-size--small);
	margin: 0;
}

/* 6.5 Sidebar widgets
 * ------------------------------------------------------------------------- */

/* A mono label with a hairline under it, distinct from the display headings. */
.single .marin-widget-title {
	border-bottom: 1px solid var(--wp--preset--color--border-light);
	color: var(--wp--preset--color--main-accent);
	font-family: var(--wp--preset--font-family--mono);
	font-weight: 600;
	letter-spacing: 0.14em;
	margin-bottom: var(--wp--preset--spacing--small);
	padding-bottom: var(--wp--preset--spacing--2-x-small);
	text-transform: uppercase;
}

/* Recent (core/latest-posts) — title over a mono date, hairline between items. */
.single .marin-mini-posts {
	list-style: none;
	margin: 0;
	padding-left: 0;
}

.single .marin-mini-posts li {
	border-bottom: 1px solid var(--wp--preset--color--border-light);
	padding-block: var(--wp--preset--spacing--x-small);
}

.single .marin-mini-posts li:last-child {
	border-bottom: 0;
}

.single .marin-mini-posts a {
	color: var(--wp--preset--color--contrast);
	display: block;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	line-height: 1.3;
	text-decoration: none;
}

.single .marin-mini-posts a:hover {
	color: var(--wp--preset--color--primary);
}

.single .marin-mini-posts .wp-block-latest-posts__post-date {
	color: var(--wp--preset--color--main-accent);
	display: block;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--xx-small);
	letter-spacing: 0.06em;
	margin-top: 0.15em;
}

/* Topics (core/categories) — a plain hairline-separated list. */
.single .marin-topics {
	list-style: none;
	margin: 0;
	padding-left: 0;
}

.single .marin-topics li {
	border-bottom: 1px solid var(--wp--preset--color--border-light);
	padding-block: 0.3rem;
}

.single .marin-topics li:last-child {
	border-bottom: 0;
}

.single .marin-topics a {
	color: var(--wp--preset--color--secondary);
	font-size: var(--wp--preset--font-size--small);
	text-decoration: none;
}

.single .marin-topics a:hover {
	color: var(--wp--preset--color--primary);
}

/*
 * Sidebar CTA button: base on main, inverting the theme.json primary button.
 * The named-colour classes core emits carry `!important`, so the hover has to
 * as well to win — same idiom core's colour utility classes need.
 */
.single .marin-aside-cta .wp-block-button__link:hover {
	background-color: var(--wp--preset--color--white) !important;
	color: var(--wp--preset--color--main) !important;
}

/* 6.6 Related posts
 * ------------------------------------------------------------------------- */

/*
 * The query loop renders a grid of <li> cards. The featured image sits flush
 * to the card's top edge (card `overflow: hidden` clips it to the radius); the
 * text blocks carry their own inline padding. A card without a featured image
 * keeps its top spacing from the eyebrow's own top margin, so both cases read.
 */
.single .marin-related__grid .wp-block-post-template > li {
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--border-light);
	border-radius: var(--wp--preset--border-radius--lg);
	overflow: hidden;
	padding-bottom: var(--wp--preset--spacing--medium);
	transition: transform 0.16s, box-shadow 0.16s, border-color 0.16s;
}

.single .marin-related__grid .wp-block-post-template > li:hover {
	border-color: var(--wp--preset--color--sand-deep);
	box-shadow: 0 16px 32px -22px rgb(33 28 26 / 0.55);
	transform: translateY(-3px);
}

.single .marin-related__grid .wp-block-post-featured-image {
	margin: 0;
}

.single .marin-related__grid .wp-block-post-featured-image img {
	aspect-ratio: 16 / 10;
	border-radius: 0;
	object-fit: cover;
	width: 100%;
}

.single .marin-related__grid :is(.wp-block-post-terms, .wp-block-post-title, .wp-block-post-excerpt) {
	padding-inline: var(--wp--preset--spacing--medium);
}

/* 6.7 Comments
 * ------------------------------------------------------------------------- */

.single .marin-comments .wp-block-comment-template {
	list-style: none;
	margin-top: var(--wp--preset--spacing--large);
	padding-left: 0;
}

.single .marin-comments .wp-block-comment-template > li {
	border-bottom: 1px solid var(--wp--preset--color--border-light);
	padding-block: var(--wp--preset--spacing--medium);
}

.single .marin-comments .wp-block-avatar img {
	border-radius: 999px;
}

.single .marin-comment__meta {
	gap: 0.6rem;
}

.single .marin-comment__meta .wp-block-comment-author-name {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 600;
}

.single .marin-comment__meta .wp-block-comment-author-name a {
	text-decoration: none;
}

.single .marin-comment__meta .wp-block-comment-date,
.single .marin-comment__meta .wp-block-comment-date a {
	color: var(--wp--preset--color--main-accent);
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--xx-small);
	letter-spacing: 0.06em;
	text-decoration: none;
}

/*
 * Comment form. Core renders the browser-default field: a white box with a
 * sharp grey border, which reads as a foreign element on the cream page. Put
 * the fields on `base` with a hairline border and the theme radius, and give
 * their labels the same mono treatment the sidebar widgets and meta line use,
 * so the form belongs to the design rather than the browser.
 */
.single .marin-comments .comment-form label {
	color: var(--wp--preset--color--main-accent);
	display: block;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--xx-small);
	letter-spacing: 0.1em;
	margin-bottom: var(--wp--preset--spacing--2-x-small);
	text-transform: uppercase;
}

.single .marin-comments .comment-form :is(textarea, input[type="text"], input[type="email"], input[type="url"]) {
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--custom--color--control-border);
	border-radius: var(--wp--preset--border-radius--md);
	/* Keep padding and border inside the 100% width. Core's comments-form
	   block styles already set this, but without it the fields would overflow
	   the column on phones, as the product review form's did. */
	box-sizing: border-box;
	color: var(--wp--preset--color--contrast);
	font-family: var(--wp--preset--font-family--primary);
	font-size: var(--wp--preset--font-size--base);
	padding: 0.75em 0.9em;
	width: 100%;
}

.single .marin-comments .comment-form textarea {
	min-height: 130px;
	resize: vertical;
}

/*
 * `:focus-visible` rather than `:focus` so a pointer click doesn't ring the
 * field, and a real outline rather than the border swap this used to do — see
 * the matching note on the catalog sorting select in `woocommerce.css`.
 */
.single .marin-comments .comment-form :is(textarea, input[type="text"], input[type="email"], input[type="url"]):focus-visible {
	border-color: var(--wp--preset--color--primary);
	outline: 2px solid var(--wp--preset--color--primary);
	outline-offset: 2px;
}

.single .marin-comments .comment-form ::placeholder {
	color: var(--wp--preset--color--main-accent);
	opacity: 1;
}

/* 6.8 Reading-progress bar
 * ------------------------------------------------------------------------- */

/*
 * A hairline under the masthead that fills as the page scrolls. Driven by a
 * scroll timeline rather than a scroll listener, for the same reason §2.2's
 * header edge is: the theme ships no JavaScript, and where `scroll()` is
 * unsupported the bar simply never appears — the rest state we would choose
 * anyway. Scoped to `.single` so it is a reading affordance for posts only.
 *
 * Anchored to `.marin-header`, which §2.1 already makes sticky (hence
 * positioned), so the absolute bar sits on its bottom edge.
 */
@supports (animation-timeline: scroll()) {
	.single .marin-header::after {
		animation: marin-read-progress linear both;
		animation-timeline: scroll(root block);
		background: var(--wp--preset--color--primary);
		bottom: 0;
		content: "";
		height: 2px;
		left: 0;
		position: absolute;
		transform: scaleX(0);
		transform-origin: left;
		width: 100%;
	}
}

@keyframes marin-read-progress {
	to {
		transform: scaleX(1);
	}
}

/* -------------------------------------------------------------------------
 * 7. Motion
 * ------------------------------------------------------------------------- */

/*
 * Store home: the illustration in a category tile lifts when the tile is
 * hovered or focused, and a product card photo eases in. Buttons in the page
 * content darken slightly on hover. All of it is switched off for visitors
 * who ask for reduced motion.
 */
.marin-art {
	transition: transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1);
}

.marin-tile:hover .marin-art,
.marin-tile:focus-within .marin-art {
	transform: translateY(-8px);
}

.wp-block-woocommerce-product-template .wc-block-components-product-image {
	overflow: hidden;
}

.wp-block-woocommerce-product-template .wc-block-components-product-image img {
	transition: transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1);
}

.wp-block-woocommerce-product-template .wc-block-product:hover .wc-block-components-product-image img {
	transform: scale(1.04);
}

main .wp-block-button__link {
	transition: filter 0.2s;
}

main .wp-block-button__link:hover {
	filter: brightness(0.92);
}

@media (prefers-reduced-motion: reduce) {
	.marin-art,
	.wp-block-woocommerce-product-template .wc-block-components-product-image img,
	main .wp-block-button__link {
		transition: none;
	}

	.marin-tile:hover .marin-art,
	.marin-tile:focus-within .marin-art,
	.wp-block-woocommerce-product-template .wc-block-product:hover .wc-block-components-product-image img {
		transform: none;
	}
}
