/*
Theme Name: Value Cremations
Theme URI: https://weave.co.nz
Author: Weave Digital Studio
Author URI: https://weave.co.nz
Description: Value Cremations block theme. Presentation only, site behaviour lives in the weave-site-functions plugin.
Requires at least: 7.0
Tested up to: 7.1
Requires PHP: 8.1
Version: 0.9.38
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: value-cremations
Tags: block-patterns, full-site-editing, one-column, custom-colors, custom-logo, editor-style, wide-blocks
*/

/*
 * Custom CSS policy (CLAUDE.md hard rule 5): everything that can be a token or a block support lives in theme.json.
 * Each rule below names the block limitation it works around so it can be counted as FSE friction. Rule codes
 * (H1, Q1, CS3 and so on) match the weave-blocks reference theme, where each was measured and logged.
 */

/* ------------------------------------------------------------------
 * Header. Each rule names the core limitation it works around.
 * The part carries two rows, the desktop bar and the mobile pill, because core has no
 * per-breakpoint visibility and the two layouts share nothing but the menu (one
 * wp_navigation post, referenced by both). Live switches at 1400px (measured 9 Sep 2026).
 * ------------------------------------------------------------------ */

/* H4. Bar above 1400px, pill at 1400px and below. Core has no per-breakpoint visibility. */
@media (max-width: 1400px) {
	.weave-header .weave-header__bar { display: none; }
}
@media (min-width: 1401px) {
	.weave-header .weave-header__pill { display: none; }
}

/* H1. Core Navigation exposes no design controls for the dropdown panel (only the nav's own
 *     colours, inherited). Reference (live): white panel, 5px radius, soft shadow, 18px 600
 *     links padded 10px 20px. Selector carries .wp-block-navigation twice because core's
 *     ".wp-block-navigation:not(.has-background) .wp-block-navigation__submenu-container"
 *     sets white/bordered at (0,3,0). */
.weave-header .weave-header__nav.wp-block-navigation .wp-block-navigation__submenu-container {
	background-color: var(--wp--preset--color--surface);
	border: 0;
	border-radius: var(--wp--preset--border-radius--small);
	box-shadow: var(--wp--preset--shadow--dropdown);
	padding: var(--wp--preset--spacing--10) 0;
	margin-top: var(--wp--preset--spacing--10);
}
/* H1c. The 10px gap above the panel is dead space for the pointer, so the menu closes while
 *      the mouse crosses it. Bridge the gap with an invisible pseudo-element that is part of
 *      the panel (hover stays on the item). */
.weave-header .weave-header__nav.wp-block-navigation .wp-block-navigation__submenu-container::before {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 100%;
	height: var(--wp--preset--spacing--10);
}
.weave-header .weave-header__nav.wp-block-navigation .wp-block-navigation__submenu-container > .wp-block-navigation-item > .wp-block-navigation-item__content {
	padding: var(--wp--preset--spacing--10) var(--wp--preset--spacing--20);
	white-space: nowrap;
}
/* H1d. The Locations list has 17 entries, too tall for one column (the Figma mobile menu shows it
 *      in two). Core's open-state rule sets display:flex at (0,5,0), so the grid is set on the same
 *      states. Assumption: the live desktop dropdown could not be opened under Playwright. */
.weave-header .weave-header__nav.wp-block-navigation .has-child:hover > .wp-block-navigation__submenu-container:has(> :nth-child(9)),
.weave-header .weave-header__nav.wp-block-navigation .has-child:focus-within > .wp-block-navigation__submenu-container:has(> :nth-child(9)),
.weave-header .weave-header__nav.wp-block-navigation .has-child .wp-block-navigation-submenu__toggle[aria-expanded="true"] ~ .wp-block-navigation__submenu-container:has(> :nth-child(9)) {
	display: grid;
	grid-template-columns: 1fr 1fr;
}

/* H7. Navigation link hover colour. Core sets
 *     ".wp-block-navigation .wp-block-navigation-item__content.wp-block-navigation-item__content { color: inherit }"
 *     at (0,3,0), so neither theme.json (styles.blocks.core/navigation.elements.link:hover) nor a
 *     block-level link colour can change a nav link's colour on hover. Header, overlay and footer
 *     hover to the link hover colour, as every other link on the site does. */
.weave-header .wp-block-navigation .wp-block-navigation-item__content.wp-block-navigation-item__content:hover,
.weave-header .wp-block-navigation .wp-block-navigation-item__content.wp-block-navigation-item__content:focus-visible,
.weave-overlay .wp-block-navigation .wp-block-navigation-item__content.wp-block-navigation-item__content:hover,
.weave-overlay .wp-block-navigation .wp-block-navigation-item__content.wp-block-navigation-item__content:focus-visible,
.weave-footer .wp-block-navigation .wp-block-navigation-item__content.wp-block-navigation-item__content:hover,
.weave-footer .wp-block-navigation .wp-block-navigation-item__content.wp-block-navigation-item__content:focus-visible {
	color: var(--wp--preset--color--primary-strong);
}

/* H3. Current page highlight. theme.json cannot target .current-menu-item. */
.weave-header .wp-block-navigation .current-menu-item > .wp-block-navigation-item__content.wp-block-navigation-item__content {
	color: var(--wp--preset--color--primary-strong);
}

/* H6. Sticky header. Core's sticky position only works on a Group at the root of the
 *     template, but a header part renders inside a <header class="wp-block-template-part">
 *     wrapper the height of the header, so the Group can never stick. Sticky goes on the
 *     wrapper instead. */
header.wp-block-template-part:has(> .weave-header) {
	position: sticky;
	top: 0;
	z-index: 20;
}

/* H5. Once scrolled the header gains a full-width shadow and the bar shrinks (live: Themer sticky
 *     plus shrink, 109px to 98px, the white band edge to edge). Core sticky position has no
 *     scroll-state styling, so this is a CSS scroll-driven animation; browsers without
 *     animation-timeline keep the full-height bar and no shadow. */
@supports (animation-timeline: scroll()) {
	.weave-header {
		animation: weave-header-shadow linear both;
		animation-timeline: scroll();
		animation-range: 0 160px;
	}
	.weave-header__bar {
		animation: weave-header-shrink linear both;
		animation-timeline: scroll();
		animation-range: 0 160px;
	}
	@keyframes weave-header-shadow {
		to { box-shadow: var(--wp--preset--shadow--header); }
	}
	@keyframes weave-header-shrink {
		to {
			padding-top: var(--wp--preset--spacing--20);
			padding-bottom: var(--wp--preset--spacing--20);
		}
	}
}
/* H5b. On mobile the pill floats over the page (live: no band behind it), so the header's
 *      background and the scroll shadow go at the pill breakpoint. Background colour is a block
 *      support but has no per-breakpoint form. */
@media (max-width: 1400px) {
	.weave-header { background-color: transparent !important; animation: none; } /* !important: core's .has-surface-background-color preset rule is !important too */
}

/* H12. Icon-only phone link in the pill and the overlay top row. Core Button carries text only
 *      and the Icon block cannot be a link, so the button keeps its accessible text, collapsed
 *      to zero size, and the icon mask (functions.php, icon block styles) does the drawing. */
.weave-header__pill-phone .wp-block-button.is-style-text .wp-block-button__link,
.weave-overlay__phone .wp-block-button.is-style-text .wp-block-button__link {
	font-size: 0;
	line-height: 0;
	padding: var(--wp--preset--spacing--10); /* (0,4,0) to beat the theme.json variation's padding */
}
.weave-header__pill-phone .wp-block-button.is-style-icon-phone .wp-block-button__link::before,
.weave-overlay__phone .wp-block-button.is-style-icon-phone .wp-block-button__link::before {
	width: var(--wp--preset--font-size--large-body);
	height: var(--wp--preset--font-size--large-body);
}

/* ------------------------------------------------------------------
 * Mobile overlay (the navigation-overlay part). Each rule names the limitation.
 * ------------------------------------------------------------------ */

/* O1. Submenus inline and expanded. Inside core's open overlay every nested submenu is held open
 *     by the Interactivity state (aria-expanded stays true and the toggle does nothing), which is
 *     core's own overlay behaviour, so the overlay nav shows plain links with their children listed
 *     beneath. Core still positions the panel as an absolute dropdown (the parent li.has-child is a
 *     flex row), hence the static grid here. Long lists flow in two columns as in the Figma menu. */
.weave-overlay .weave-overlay__nav .has-child {
	flex-wrap: wrap;
}
.weave-overlay .weave-overlay__nav.wp-block-navigation .has-child.wp-block-navigation-item > .wp-block-navigation__submenu-container {
	position: static;
	flex: 0 0 100%; /* always its own row under the link; core's focus-within rule sets width:auto at (0,6,0), so this selector is (0,7,0) and the wrap is forced through flex-basis too */
	display: grid;
	grid-template-columns: minmax(0, 1fr); /* minmax(0, ...) so long labels wrap instead of widening the card */
	gap: 0 var(--wp--preset--spacing--20);
	width: 100%;
	min-width: 0;
	margin-top: var(--wp--preset--spacing--10);
	padding: 0;
	background: transparent;
	box-shadow: none;
	height: auto;
	overflow: visible;
	opacity: 1;
	visibility: visible;
}
.weave-overlay .weave-overlay__nav.wp-block-navigation .has-child.wp-block-navigation-item > .wp-block-navigation__submenu-container:has(> :nth-child(9)) {
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); /* the 17 locations in two columns */
}
.weave-overlay .weave-overlay__nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	font-size: var(--wp--preset--font-size--small);
	font-weight: 400;
	padding: var(--wp--preset--spacing--10) 0;
}

/* O3. The accordion (assets/js/overlay-menu.js). The script adds a toggle button after each parent
 *     link; the children are hidden until the button is pressed (state: the panel's hidden attribute). The chevron
 *     is the theme's dropdown icon as a mask so it takes the current colour and turns when open.
 *     Without the script nothing here applies and the lists stay expanded. */
.weave-overlay .weave-overlay__nav.wp-block-navigation .has-child.wp-block-navigation-item > .wp-block-navigation__submenu-container[hidden] {
	display: none; /* (0,7,0): above core's hover / focus-within open rule for a parent item, which fires while the toggle has focus; the hidden attribute is state the runtime never touches */
}
.weave-overlay .weave-overlay__nav .has-child > .wp-block-navigation-item__content { order: 0; }
.weave-overlay .weave-overlay__nav .has-child > .weave-overlay__toggle { order: 1; }
.weave-overlay .weave-overlay__nav .has-child > .wp-block-navigation__submenu-container { order: 2; } /* the runtime may reorder the children; the row reads link, chevron, list regardless */
.weave-overlay__toggle {
	appearance: none;
	background: transparent;
	border: 0;
	padding: 0;
	margin-left: var(--wp--preset--spacing--10);
	width: 1.25em;
	height: 1.25em;
	color: inherit;
	cursor: pointer;
}
.weave-overlay__toggle::before {
	content: "";
	display: block;
	width: 100%;
	height: 100%;
	background-color: currentColor;
	-webkit-mask: url("assets/icons/dropdown.svg") center / contain no-repeat;
	mask: url("assets/icons/dropdown.svg") center / contain no-repeat;
	transition: var(--wp--custom--motion--fast);
}
.weave-overlay__toggle[aria-expanded="true"]::before {
	transform: rotate(180deg);
}
@media (prefers-reduced-motion: reduce) {
	.weave-overlay__toggle::before { transition: none; }
}

/* O2. Menu rows: vertical padding and a 1px accent divider per item (live: 15px and #51C05C).
 *     Navigation items carry no spacing or border controls. */
.weave-overlay .weave-overlay__nav > .wp-block-navigation__container > .wp-block-navigation-item {
	width: 100%;
	padding: var(--wp--preset--spacing--20) 0;
	border-bottom: 1px solid var(--wp--preset--color--accent);
}
.weave-overlay .weave-overlay__nav > .wp-block-navigation__container > .wp-block-navigation-item:last-child {
	border-bottom: 0;
}

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

/* F1. Legal links are separated by a pipe (live and Figma). Navigation has no separator control. */
.weave-footer__legal .wp-block-navigation-item + .wp-block-navigation-item::before {
	content: "|";
	margin-right: var(--wp--preset--spacing--10);
}

/* T2. Live balances heading line breaks (text-wrap: balance on the H1, so "Transforming" sits
 *     alone on line one). theme.json has no text-wrap property. */
h1, h2, h3 { text-wrap: balance; }

/* T3. Live sets text-wrap: pretty on paragraphs (fewer orphans, slightly different line breaks in
 *     the quotes and the CTA prompt). theme.json has no text-wrap property. */
p { text-wrap: pretty; }

/* T1. Live headings use line-height 1.25 at 768px and below (1.1 above). theme.json line-height
 *     is a single value with no fluid form, so this is one media rule for all headings. */
@media (max-width: 768px) {
	h1, h2, h3, h4 { line-height: var(--wp--custom--line-height--heading-mobile); }
}

/* ------------------------------------------------------------------
 * Our work 
 * ------------------------------------------------------------------ */

/* W1. Bento spans. Post Template's grid layout is uniform and Query Loop has no per-item span, so
 *     live's 660 / 310 / 310 then 485-image / 660 arrangement is three nth-child rules on the
 *     four-column template. Below 768 the template is one column and these do nothing. */
@media (min-width: 769px) {
	.weave-work__grid .wp-block-post-template > li:nth-child(1),
	.weave-work__grid .wp-block-post-template > li:nth-child(4),
	.weave-work__grid .wp-block-post-template > li:nth-child(5) { grid-column: span 2; }
	.weave-work__grid .wp-block-post-template > li:nth-child(4) .wp-block-post-featured-image { max-width: 485px; }
}

/* W2. Card hover: title to the accent colour and a soft dark gradient over the image, as on live. Post Title
 *     and Featured Image have no hover states of their own, and the "card" is a Post Template
 *     item, so this is one hover rule pair. Featured Image's overlay support is static, not hover. */
.weave-work__grid .wp-block-post-template > li .wp-block-post-title a { transition: color .15s ease-out; }
.weave-work__grid .wp-block-post-template > li:hover .wp-block-post-title a,
.weave-work__grid .wp-block-post-template > li:focus-within .wp-block-post-title a { color: var(--wp--preset--color--accent); }
.weave-work__grid .wp-block-post-featured-image { position: relative; overflow: hidden; border-radius: var(--wp--preset--border-radius--card); }
.weave-work__grid .wp-block-post-featured-image::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
	background: linear-gradient(180deg, rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0.35) 100%);
	opacity: 0;
	transition: opacity .3s ease-out;
	pointer-events: none;
}
.weave-work__grid .wp-block-post-template > li:hover .wp-block-post-featured-image::after,
.weave-work__grid .wp-block-post-template > li:focus-within .wp-block-post-featured-image::after { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .weave-work__grid .wp-block-post-featured-image::after, .weave-work__grid .wp-block-post-title a { transition: none; } }

/* ------------------------------------------------------------------
 * Testimonials .
 * ------------------------------------------------------------------ */

/* Q1. Scroller. Core has no carousel block, so the track is a nowrap flex Group of 100%-wide
 *     slide Groups (child sizing from block attributes) that scrolls horizontally with scroll
 *     snap; Group has no overflow or scroll-snap controls. Works with no script (swipe, trackpad,
 *     keyboard scroll); the buttons and counter are wired by assets/js/testimonials.js, and the
 *     nav stays hidden until that script marks the section ready so a no-JS page shows no dead
 *     buttons. Live hides the scrollbar too. Slides carry selfStretch "fixed" / flexSize 100%
 *     from the block, but core's fixed child sizing sets flex-basis without flex-shrink: 0, so
 *     three slides still squeezed into one row; the flex shorthand here makes fixed mean fixed. */
.weave-testimonials__track {
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	overscroll-behavior-x: contain;
	scrollbar-width: none;
}
.weave-testimonials__track::-webkit-scrollbar { display: none; }
.weave-testimonials__track > * { flex: 0 0 100%; scroll-snap-align: start; }
.weave-testimonials:not(.is-ready) .weave-testimonials__nav { visibility: hidden; }

/* Q2. Icon-only prev / next. Core Button carries text only and the Icon block cannot be a
 *     button, so each control is a Button block (tagName button, outline style) whose visible
 *     label is pushed out of a 38px round box (text stays in the accessibility tree) and whose
 *     arrow is the icon set glyph as a currentColor mask, so the outline style's hover and
 *     focus (navy fill, white text) invert the arrow too. Reference: 38px glyph, 28px at 768 and below. */
.weave-testimonials__nav .wp-block-button__link {
	position: relative;
	width: 2.375rem;
	height: 2.375rem;
	padding: 0;
	overflow: hidden;
	white-space: nowrap;
	text-indent: 100%;
	border-radius: 50%;
}
.weave-testimonials__nav .wp-block-button__link::before {
	content: "";
	position: absolute;
	inset: 25%;
	background-color: currentColor;
	-webkit-mask: url("assets/images/icons/arrow-left.svg") center / contain no-repeat;
	mask: url("assets/images/icons/arrow-left.svg") center / contain no-repeat;
}
.weave-testimonials__next .wp-block-button__link::before {
	-webkit-mask-image: url("assets/images/icons/arrow-right.svg");
	mask-image: url("assets/images/icons/arrow-right.svg");
}
@media (max-width: 768px) {
	.weave-testimonials__nav .wp-block-button__link { width: 1.75rem; height: 1.75rem; }
}

/* ------------------------------------------------------------------
 * CTA .
 * ------------------------------------------------------------------ */

/* C1. Button arrow. Core Button carries text only (no icon slot; the Icon block cannot sit inside
 *     a button), so the "White with arrow" style draws the icon set arrow-up-right after the
 *     label as a currentColor mask; it inverts with the style's hover / focus from theme.json.
 *     Reference: 22px glyph 8px after a 20px label, label never wraps. */
.is-style-white-arrow .wp-block-button__link { white-space: nowrap; }
.is-style-white-arrow .wp-block-button__link::after {
	content: "";
	display: inline-block;
	width: 0.85em;
	height: 1.1em;
	margin-left: 0.4em;
	vertical-align: -0.2em;
	background-color: currentColor;
	-webkit-mask: url("assets/images/icons/arrow-up-right.svg") center / contain no-repeat;
	mask: url("assets/images/icons/arrow-up-right.svg") center / contain no-repeat;
}

/* ------------------------------------------------------------------
 * Service pages .
 * ------------------------------------------------------------------ */

/* C2. CTA text column. The column must shrink beside the button at desktop (so a long display line
 *     wraps to two lines rather than pushing the button under it) and drop below the button on
 *     mobile. Core's "fill" child sizing is flex: 1 1 auto, whose auto basis makes a wrapping row
 *     wrap first and shrink never; basis 0 plus a 600px floor (the prompt's width) does both. */
.weave-cta__panel > .wp-block-group:first-child { flex: 1 1 0; min-width: min(100%, 600px); }

/* SV1. FAQ accordion icon. Core renders the "+" at the heading's size and colour (32px Parchment);
 *      the reference shows a 20px white glyph. Two declarations; the glyph itself is core's. */
.weave-service__faq-list .wp-block-accordion-heading__toggle-icon { font-size: var(--wp--preset--font-size--body); color: var(--wp--preset--color--text-inverse); }

/* A1. Focus ring. Browsers' default focus-visible ring (blue, 1px) is 2.9:1 on the navy bands,
 *     under WCAG 1.4.11. theme.json has no focus-visible outline, so: a 2px ring in the text
 *     colour of the page, swapped to white inside any navy band. */
:focus-visible { outline: 2px solid var(--wp--preset--color--primary); outline-offset: 3px; }
.has-surface-inverse-background-color :focus-visible { outline-color: var(--wp--preset--color--text-inverse); } /* descendants only: the ring sits on the surface behind the element, so a navy button on a light band keeps the navy ring */
.has-surface-inverse-background-color .has-white-background-color :focus-visible,
.has-surface-inverse-background-color .has-surface-background-color :focus-visible,
.has-surface-inverse-background-color .has-accent-background-color :focus-visible { outline-color: var(--wp--preset--color--primary); } /* a light panel inside a navy band */

/* ------------------------------------------------------------------
 * Case studies : archive, taxonomy archives, single project.
 * ------------------------------------------------------------------ */

/* CS1. Term filter lists. The Terms List (Categories) block renders a bulleted <ul>; the reference shows a
 *      plain stack of term links beside the label. Block supports offer no list-style control. */
.weave-term-list { padding: 0; margin: 0; list-style: none; }
.weave-term-list li { margin: 0 0 var(--wp--preset--spacing--10); }
.weave-term-list a { color: inherit; text-decoration: none; }
.weave-term-list a:hover, .weave-term-list a:focus-visible { text-decoration: underline; }

/* CS2. Bento spans on the archive grid: the first card spans 4 of 8 columns and the rest span 2
 *      (same Post Template limitation as W1 on the homepage). One column below 768. */
@media (min-width: 769px) {
	.weave-project-grid--bento .wp-block-post-template > li { grid-column: span 2; }
	.weave-project-grid--bento .wp-block-post-template > li:first-child { grid-column: span 4; }
}

/* CS3. Card hover for every project grid (the homepage W2 rule covered only .weave-work__grid):
 *      image dims to 90% and the title turns the accent colour, as the reference. Featured Image and Post Title have
 *      no hover supports. */
.weave-project-grid .wp-block-post-title a { transition: color .15s ease-out; }
.weave-project-grid .wp-block-post-template > li:hover .wp-block-post-title a,
.weave-project-grid .wp-block-post-template > li:focus-within .wp-block-post-title a { color: var(--wp--preset--color--accent); }
.weave-project-grid .wp-block-post-featured-image img { transition: filter .15s ease-out; }
.weave-project-grid .wp-block-post-template > li:hover .wp-block-post-featured-image img,
.weave-project-grid .wp-block-post-template > li:focus-within .wp-block-post-featured-image img { filter: brightness(0.9); }
@media (prefers-reduced-motion: reduce) { .weave-project-grid .wp-block-post-title a, .weave-project-grid .wp-block-post-featured-image img { transition: none; } }

/* CS4. Single project summary: the service terms read as a bullet list (Post Terms renders inline
 *      links with separators), and on narrow screens the title column comes before the label
 *      column as the reference (core Columns stack in source order only; wrap-reverse flips the rows). */
.weave-project-summary__services a { color: inherit; display: list-item; list-style: disc inside; margin: 0 0 0.5rem; text-decoration: none; }
.weave-project-summary__services a:hover, .weave-project-summary__services a:focus-visible { text-decoration: underline; }
@media (max-width: 781px) { .wp-block-columns.weave-project-summary { flex-wrap: wrap-reverse !important; } } /* core's .wp-block-columns sets flex-wrap: wrap !important */

/* CS5. Industry term pills inside project bodies: Post Terms renders plain links; the reference shows
 *      accent pills (radius 50, 0.4em / 1em). The block exposes no per-link styling. Text is
 *      muted; check AA against the accent once the palette is real. */
.weave-term-pills { display: flex; flex-wrap: wrap; gap: var(--wp--preset--spacing--10); }
.weave-term-pills a { display: inline-block; background: var(--wp--preset--color--accent); color: var(--wp--preset--color--text-muted); border-radius: var(--wp--preset--border-radius--pill); padding: 0.4em 1em; text-decoration: none; font-weight: 400; }
.weave-term-pills a:hover, .weave-term-pills a:focus-visible { color: var(--wp--preset--color--primary); }

/* CS6. Project body bands: the label column keeps its 30% width but the stacked mobile order
 *      follows source (label first), as the reference. Quote bands use the theme quote styles. */
.weave-project-band .wp-block-quote { margin: 0; }
.weave-project-quote p { font-weight: 400; }
.weave-project-band h2 { font-weight: 300; }

/* ------------------------------------------------------------------
 * Insights : posts index, archives, single post.
 * ------------------------------------------------------------------ */

/* I1. The first card spans two of the three grid columns (live's featured treatment is
 *     positional). Post Template's grid is uniform, as on the homepage (W1). */
@media (min-width: 769px) { .weave-insights-grid .wp-block-post-template > li:first-child { grid-column: span 2; } }

/* I2. Category row. The Categories block renders a bulleted <ul>; the reference shows a centred wrapping
 *     row of links with no markers. No layout controls on the block. */
.weave-term-row { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--wp--preset--spacing--10) var(--wp--preset--spacing--40); padding: 0; margin: 0; list-style: none; }
.weave-term-row li { margin: 0; }
.weave-term-row a { color: inherit; text-decoration: none; }
.weave-term-row a:hover, .weave-term-row a:focus-visible, .weave-term-row .current-cat > a { text-decoration: underline; }

/* I3. Article body headings. Post Content on a post uses live's article scale (h2 at the subheading size, h3 at the small-heading size) while the global h2 / h3 are the homepage display sizes.
 *     theme.json's post-content element styles would also resize the homepage headings, so the
 *     override is scoped to the single post template. */
.weave-single-post .wp-block-post-content h2 { font-size: var(--wp--preset--font-size--subheading); color: var(--wp--preset--color--text); }
.weave-single-post .wp-block-post-content h3 { font-size: var(--wp--preset--font-size--small-heading); font-weight: 300; color: var(--wp--preset--color--primary); }
.weave-single-post .wp-block-post-content ul, .weave-single-post .wp-block-post-content ol { padding-left: var(--wp--preset--spacing--50); }
.weave-single-post .wp-block-post-content .wp-block-quote { font-size: var(--wp--preset--font-size--headline); font-weight: 500; color: var(--wp--preset--color--text-muted); line-height: 1.4; }

/* I4. Single header categories: Post Terms centres through textAlign but the separator is a space;
 *     give the links live's 40px visual gap. */
.weave-post-categories a { margin: 0 var(--wp--preset--spacing--20); }

/* S1: Sector feature list. Core List cannot hold a heading and a paragraph per item and has no icon
   marker control, so the ticked info list is a Group of "Feature" Groups (h3 + p) and the tick is a
   masked SVG pseudo-element in a 22px column, 22px from the text (live: icon set glyph, 22 x 22). */
.weave-tick-list__item {
	display: grid;
	grid-template-columns: 22px 1fr;
	column-gap: 22px;
}
.weave-tick-list__item > * { grid-column: 2; }
.weave-tick-list__item::before {
	content: "";
	grid-column: 1;
	grid-row: 1;
	width: 22px;
	height: 22px;
	margin-top: 0.25em;
	background-color: currentColor;
	-webkit-mask: url("assets/images/icons/check.svg") no-repeat center / contain;
	mask: url("assets/images/icons/check.svg") no-repeat center / contain;
}

/* L1. Prose pages (legal): space above headings. Core's flow layout sets every child's margin to the
 *     block gap (20 here), so headings sit flush on the paragraph before them; the reference has 136 / 108
 *     above H2 / H3 at 1440 and 51 / 40 at 390. theme.json heading margins lose to that layout rule. */
.weave-page .entry-content > h2.wp-block-heading { margin-block-start: var(--wp--preset--spacing--40); }
.weave-page .entry-content > h3.wp-block-heading { margin-block-start: var(--wp--preset--spacing--30); }

/* S2. Sector showcase panel: the one band that stops widening. Live caps it at 1400 and centres it at
 *     2000 while every other band follows the gutter; a Group has no max-width control of its own. */
.weave-sector-showcase.alignwide { max-width: min(100%, 1400px); margin-inline: auto; }

/* S3. Sector work cards: equal-height cards with the "View project" link on a common baseline (live's
 *     ragged bottoms were flagged not-to-reproduce). Post Template grid items stretch, the inner
 *     Groups do not. */
.weave-sector-work__grid .wp-block-post > .wp-block-group { height: 100%; display: flex; flex-direction: column; }
.weave-sector-work__grid .wp-block-post > .wp-block-group > .wp-block-group { flex: 1 1 auto; display: flex; flex-direction: column; }
.weave-sector-work__grid .wp-block-read-more { margin-block-start: auto; padding-block-start: var(--wp--preset--spacing--20); }

/* ------------------------------------------------------------------
 * Homepage sections (stage 5). Each rule names the block limitation it works around.
 * ------------------------------------------------------------------ */

/* HM1. Hero illustration on phones: live and Figma crop the wide doodle image to a square (390 x 390 on
 *      live, cover). The Image block's aspect ratio and scale are one value for every viewport, so the
 *      crop is CSS. The full bleed itself is core's: the illustration group is alignfull inside the
 *      constrained section, with its inner content size holding the image to the narrow width on desktop. */
@media (max-width: 768px) {
	.value-hero__image img { aspect-ratio: 1; object-fit: cover; width: 100%; }
}

/* HM2. Features on tablets and phones: live and Figma show the four cards two across at 768 and 390. The
 *      Grid block's column count is one number for every viewport (auto mode would drop to one column at
 *      390), so the phone track count is CSS; the doodle shrinks from 150 to 80 as on live (max-width, so
 *      the block's own inline width stays the desktop truth). */
@media (max-width: 768px) {
	.value-grid--four.is-layout-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } /* features and benefits */
	.value-features__doodle img { max-width: 80px; }
	.value-cards__doodle img, .value-cards-center__doodle img { max-width: 90px; } /* process cards and the location's package cards: live 90 at 390 */
}

/* HM3. Standard band with the image on the left: the copy column comes first in the markup so phones read
 *      and show the text before the panel (live and Figma), and the Columns block stacks in markup order.
 *      Above core's 781px stacking point the panel moves left with order; the mirrored band needs nothing. */
@media (min-width: 782px) {
	.value-standard--image-left > .wp-block-columns > .wp-block-column:first-child { order: 2; }
}

/* HM4. Icon-only arrow link on an item row (locations). Core Button carries text only and the Icon block
 *      cannot be a link, so the button keeps its accessible text (the location name) collapsed to zero
 *      size and the icon style draws the glyph inside a fixed square, as Figma's Item Row (the arrow
 *      on a location or FAQ row, the external-link mark on the Cost page's funeral-grant links).
 *      (0,4,1) on the icon rule to beat the generated icon style's em sizing. */
.value-item-row__arrow.wp-block-button .wp-block-button__link { font-size: 0; line-height: 0; gap: 0; padding: calc(var(--wp--preset--spacing--30) / 2); }
.value-item-row__arrow.wp-block-button[class*="is-style-icon-"] .wp-block-button__link::after { width: var(--wp--preset--font-size--large-body); height: var(--wp--preset--font-size--large-body); }

/* HM5. FAQ plus box. Core's accordion heading renders its toggle icon as a "+" character at the heading's
 *      size with no box; Figma and live show it inside an off-white 50px square on the right. */
.value-faq__list .wp-block-accordion-heading__toggle-icon {
	display: flex; align-items: center; justify-content: center; flex: none;
	width: calc(var(--wp--preset--spacing--30) + var(--wp--preset--font-size--large-body));
	height: calc(var(--wp--preset--spacing--30) + var(--wp--preset--font-size--large-body));
	background: var(--wp--preset--color--surface-subtle);
	border-radius: var(--wp--preset--border-radius--small);
	font-size: var(--wp--preset--font-size--large-lead);
	font-weight: 300;
}

/* ------------------------------------------------------------------
 * Inner pages (stage 6). Each rule names the block limitation it works around.
 * ------------------------------------------------------------------ */

/* HM6. Standard band on tablets and phones: a Columns column has one width for every viewport, so
 *      once the band stacks (core's 781px point) the image panel would run the full content width.
 *      Live holds it to a 380px square, centred, at every width below the stack. */
@media (max-width: 781px) {
	.value-standard__panel { max-width: 380px; margin-inline: auto; }
}

/* HM7. CTA card buttons on tablets and phones: the arrange and call buttons sit at the card's two
 *      edges on desktop (Figma "CTA Long", live) and centred as a pair once the card is narrow. A
 *      flex layout's justification is one value for every viewport, so the narrow case is CSS. */
@media (max-width: 781px) {
	.value-cta-long .wp-block-buttons.alignwide { justify-content: center; }
}

/* HM8. Button pairs on phones: blockGap is one value for every viewport, so the hero's 40px desktop
 *      gap (live's too) pushes the arrange-and-call pair onto two lines under about 420px. Live keeps
 *      them on one line by dropping the gap, which is what this does. */
@media (max-width: 420px) {
	.value-hero .wp-block-buttons { gap: var(--wp--preset--spacing--20); }
}

/* HM9. Comparison tables. Core's Table block carries colour, border and typography on the table
 *      element only: there is no block support that reaches a th or a td, so the cell rhythm,
 *      the row dividers and the header weight are CSS. Values are live's at 1440 (UI Kit
 *      "Table Cell"): header 20px/600 with 18px padding, cells 18px with 12px/14px, a 1px
 *      divider under every row. The cells always contrast with the band they sit on, so the
 *      colour pair flips with the --cells- modifier rather than being fixed. */
.value-comparison__table table { border-collapse: collapse; width: 100%; }
.value-comparison__table th,
.value-comparison__table td {
	padding: 0.875rem;
	border: 0;
	border-bottom: 1px solid var(--wp--preset--color--surface-subtle);
	background: var(--wp--preset--color--surface);
	vertical-align: top;
}
.value-comparison__table th {
	padding: 1.125rem;
	font-size: var(--wp--preset--font-size--large-body);
	font-weight: 600;
	text-align: left;
}
.value-comparison__table th.has-text-align-center { text-align: center; }
.value-comparison__table th.has-text-align-right { text-align: right; }
/* A comparison sets the two columns against each other: the second is the other side of the
 * argument and lives on the tinted ground, with the dividers inverted (live, UI Kit "Comparison"). */
.value-comparison__table--sides th:nth-child(2),
.value-comparison__table--sides td:nth-child(2) {
	background: var(--wp--preset--color--surface-subtle);
	border-bottom-color: var(--wp--preset--color--surface);
}

/* The first column reads as the row's label on a two-column table, as live has it. */
.value-comparison__table--bold-first td:first-child { font-weight: 600; }
/* The cost-by-location rows are shorter, and their height comes from the link rather than the
 * text, so the vertical padding follows the viewport the way live's does. */
.value-comparison__table--padding-small td { padding: clamp(0.5rem, 0.83vw, 0.75rem) 0.875rem; }

/* The single-column band is a core List, not a one-column table (a table with no header row is a
 * layout table, hard rule 7). List items take the same rhythm as cells: block supports reach the
 * list, not its items. */
.value-comparison__list { padding-left: 0; }
.value-comparison__list > li {
	padding: 0.875rem 0.875rem 0.875rem 3.125rem;
	border-bottom: 1px solid var(--wp--preset--color--surface-subtle);
}
.value-comparison__list.is-style-icon-close > li::before { left: 0.875rem; top: 0.875rem; }

/* HM10. Icons inside table cells. A cell's content is RichText, so no block (and no inline SVG)
 *       can sit inside one: the icon is a masked pseudo-element on the cell, one modifier per
 *       column, drawn from the same assets/icons files as the Icon block styles. functions.php
 *       prints the matching --weave-icon-<slug> data URI when such a table renders. */
.value-comparison__table--icon-check-col-1 td:nth-child(1),
.value-comparison__table--icon-right-arrow-col-1 td:nth-child(1),
.value-comparison__table--icon-check-col-2 td:nth-child(2),
.value-comparison__table--icon-right-arrow-col-2 td:nth-child(2) {
	position: relative;
	padding-left: 3.125rem;
}
.value-comparison__table--icon-check-col-1 td:nth-child(1)::before,
.value-comparison__table--icon-right-arrow-col-1 td:nth-child(1)::before,
.value-comparison__table--icon-check-col-2 td:nth-child(2)::before,
.value-comparison__table--icon-right-arrow-col-2 td:nth-child(2)::before {
	content: "";
	position: absolute;
	left: 0.875rem;
	top: 0.875rem;
	width: 1.2em;
	height: 1.2em;
	background-color: currentColor;
	-webkit-mask: var(--value-table-icon) center/contain no-repeat;
	mask: var(--value-table-icon) center/contain no-repeat;
}
.value-comparison__table--icon-check-col-1 td:nth-child(1)::before,
.value-comparison__table--icon-check-col-2 td:nth-child(2)::before {
	--value-table-icon: var(--weave-icon-check);
	color: var(--wp--preset--color--accent);
}
.value-comparison__table--icon-right-arrow-col-1 td:nth-child(1)::before,
.value-comparison__table--icon-right-arrow-col-2 td:nth-child(2)::before {
	--value-table-icon: var(--weave-icon-right-arrow);
	color: var(--wp--preset--color--text);
}

/* HM11. A 35/65 split. Core's fixed table layout divides the width equally and offers no
 *       per-column width control, so the one table that is not equal-column says so in a class. */
.value-comparison__table--35-65 th:first-child,
.value-comparison__table--35-65 td:first-child { width: 35%; }

/* HM12. Cell rhythm on phones. The padding above is live's desktop value; live scales it fluidly
 *       and this build's tokens are fixed (stage 7), so the icon gutter alone would leave a
 *       two-column cell about 110px of text at 390. One step down, as live lands at that width. */
@media (max-width: 600px) {
	.value-comparison__table th,
	.value-comparison__table td { padding: 0.625rem; }
	.value-comparison__list > li { padding: 0.625rem 0.625rem 0.625rem 2.625rem; }
	.value-comparison__list.is-style-icon-close > li::before { left: 0.625rem; top: 0.625rem; }
	.value-comparison__table--padding-small td { padding-inline: 0.625rem; }
	.value-comparison__table--icon-check-col-1 td:nth-child(1),
	.value-comparison__table--icon-right-arrow-col-1 td:nth-child(1),
	.value-comparison__table--icon-check-col-2 td:nth-child(2),
	.value-comparison__table--icon-right-arrow-col-2 td:nth-child(2) { padding-left: 2.625rem; }
}

/* HM13. The link inside a Comparison cell. A table cell's content is RichText, so a Button block
 *       cannot sit in one (HM10): the cost-by-location table writes a plain anchor and this gives
 *       it the small off-white pill live uses. Tokens only, same values as the Button block's. */
.value-comparison__cell-link {
	display: inline-flex;
	align-items: center;
	gap: 0.5em;
	padding: var(--wp--preset--spacing--10) 0.9375rem;
	border-radius: var(--wp--preset--border-radius--panel);
	background: var(--wp--preset--color--surface-subtle);
	color: var(--wp--preset--color--text);
	font-size: var(--wp--preset--font-size--medium);
	font-weight: 600;
	text-decoration: none;
}
.value-comparison__cell-link:hover,
.value-comparison__cell-link:focus-visible { background: var(--wp--preset--color--primary); }
.value-comparison__cell-link::after {
	content: "";
	flex: none;
	width: 1.1em;
	height: 1.1em;
	background-color: currentColor;
	-webkit-mask: var(--weave-icon-thin-right-arrow) center/contain no-repeat;
	mask: var(--weave-icon-thin-right-arrow) center/contain no-repeat;
}

/* HM14. The cost-by-location link on a phone. Three columns and a full pill do not fit at 390, so
 *       the label collapses to its arrow and stays in the accessibility tree, as live does. */
@media (max-width: 600px) {
	.value-comparison__cell-link { padding: 0.375rem 0.625rem; gap: 0; }
	.value-comparison__cell-link-label {
		position: absolute;
		width: 1px;
		height: 1px;
		overflow: hidden;
		clip-path: inset(50%);
		white-space: nowrap;
	}
}
