/*
Theme Name: Weave Blocks Starter (Change to Client)
Theme URI: https://weave.co.nz
Author: Weave Digital Studio
Author URI: https://weave.co.nz
Description: Weave Digital Studio starter block theme. Design tokens live in theme.json; this stylesheet holds only the small, commented set of rules that block supports cannot express yet.
Requires at least: 7.0
Tested up to: 7.1
Requires PHP: 8.1
Version: 0.3
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: weave-blocks
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.
 * ------------------------------------------------------------------ */

/* H1. Core Navigation exposes no design controls for the dropdown panel
 *     (only the nav's own colours, inherited). Reference: a light panel, 8px radius,
 *     soft shadow, 340px wide, 16px links. 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--panel);
	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). Same problem the mega-menu probe hit (P4). */
.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 {
	font-size: 1rem;
	padding: var(--wp--preset--spacing--10) var(--wp--preset--spacing--20) var(--wp--preset--spacing--10) 3.25rem;
}

/* H1b. Core's open-state rule sets width:auto and min-width:200px on :hover / :focus-within /
 *      aria-expanded, so the 340px live width has to be set on the same states. */
.weave-header .weave-header__nav.wp-block-navigation .has-child:hover > .wp-block-navigation__submenu-container,
.weave-header .weave-header__nav.wp-block-navigation .has-child:focus-within > .wp-block-navigation__submenu-container,
.weave-header .weave-header__nav.wp-block-navigation .has-child .wp-block-navigation-submenu__toggle[aria-expanded="true"] ~ .wp-block-navigation__submenu-container {
	width: 340px;
	min-width: 340px;
}


/* 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 and overlay hover to
 *     the accent colour, footer hovers to the inverse text colour. */
.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 {
	color: var(--wp--preset--color--accent-strong);
}
.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--text-inverse);
}

/* 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--accent-strong);
}

/* H4. Two menus (left | logo | right) so the logo can sit centred with one source per
 *     link. On mobile the right nav owns the hamburger and the overlay part shows both
 *     menus, so the left nav must hide. Core has no per-breakpoint visibility. Logo 80px
 *     on mobile: Site Logo width is a single value. */
@media (max-width: 768px) {
	/* 3-column grid so the logo centres like live; left nav removed, logo and right nav pinned to columns 2 and 3 */
	.weave-header > .wp-block-group { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); }
	.weave-header .weave-header__nav--left { display: none; }
	.weave-header .weave-header__logo { grid-column: 2; }
	.weave-header .weave-header__nav--right { grid-column: 3; justify-self: end; }
	.weave-header__logo img { width: 80px; }
}

/* 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;
}

/* H8. Core's Navigation "mobile" overlay breakpoint is hard-coded at 600px and not
 *     configurable. Live switches at 768px (six items plus a centred logo do not fit
 *     between 600 and 768). Re-state core's two switching rules for that band. */
@media (min-width: 600px) and (max-width: 768px) {
	.weave-header .wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) { display: none; }
	.weave-header .wp-block-navigation__responsive-container-open:not(.always-shown) { display: flex; }
}

/* H5. Header is transparent over the hero at the top of the page and turns solid with a
 *     shadow and shrinks once scrolled (live: absolute, then fixed). Core sticky position
 *     has no scroll-state styling, so this is a CSS scroll-driven animation. Browsers
 *     without animation-timeline get an always-solid sticky header. */
.weave-header { background-color: var(--wp--preset--color--surface); }
@supports (animation-timeline: scroll()) {
	.weave-header {
		background-color: transparent;
		animation: weave-header-stick linear both;
		animation-timeline: scroll();
		animation-range: 0 160px;
	}
	.weave-header__logo img {
		animation: weave-header-logo linear both;
		animation-timeline: scroll();
		animation-range: 0 160px;
	}
	@keyframes weave-header-stick {
		to {
			background-color: var(--wp--preset--color--surface);
			box-shadow: var(--wp--preset--shadow--header);
			padding-top: var(--wp--preset--spacing--10);
			padding-bottom: var(--wp--preset--spacing--10);
		}
	}
	@keyframes weave-header-logo {
		to { width: var(--wp--custom--header--logo-width-shrunk); }
	}
}

/* H10. Scroll cue is hidden at 768 and below on live. Core has no per-breakpoint visibility. */
@media (max-width: 768px) {
	.weave-hero .weave-hero__scroll-cue.wp-block-image { display: none; } /* (0,3,0) to beat core .wp-block-image.aligncenter { display: table } */
}

/* 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, color-mix(in srgb, var(--wp--preset--color--black) 0%, transparent) 40%, color-mix(in srgb, var(--wp--preset--color--black) 35%, transparent) 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;
}

/* ------------------------------------------------------------------
 * Dark-page header . Service and other navy pages use the header-dark part
 * (white text, white logo image instead of the Site Logo block, which has one image).
 * ------------------------------------------------------------------ */

/* H11. Same scroll behaviour as H5 but the scrolled bar turns navy, not cream, because the
 *      page behind it is navy; text stays white throughout (live: header-dark-bg Themer layout). */
.weave-header--dark { background-color: var(--wp--preset--color--surface-inverse); }
@supports (animation-timeline: scroll()) {
	.weave-header--dark { background-color: transparent; animation-name: weave-header-stick-dark; }
	@keyframes weave-header-stick-dark {
		to {
			background-color: var(--wp--preset--color--surface-inverse);
			box-shadow: var(--wp--preset--shadow--header);
			padding-top: var(--wp--preset--spacing--10);
			padding-bottom: var(--wp--preset--spacing--10);
		}
	}
}

/* ------------------------------------------------------------------
 * 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--primary-strong); }
.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--grid-row); }
.weave-page .entry-content > h3.wp-block-heading { margin-block-start: var(--wp--preset--spacing--card-row); }

/* 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); }
