/**
 * NF Industry - component styles.
 *
 * Colour, type scale and spacing come from theme.json as CSS custom
 * properties (--wp--preset--*), so everything here inherits whatever the
 * Site Editor is set to. Nothing below hard-codes a brand colour.
 *
 * Mobile first: base rules target small screens, media queries add up.
 */

/* -------------------------------------------------------------------------
 * 0. Design tokens
 *
 * A shared radius/shadow/motion scale so every component below reads as one
 * system instead of each one improvising its own numbers. Colour and
 * spacing already have this treatment via theme.json; these three don't
 * have a first-class equivalent in the Site Editor, so they're defined once
 * here and reused throughout the file.
 * ---------------------------------------------------------------------- */

:root {
	--nf-radius-sm: 8px;   /* inputs, small pills, table corners */
	--nf-radius-md: 12px;  /* cards, alerts, the map, images */
	--nf-radius-lg: 18px;  /* the hero and other large feature blocks */

	--nf-shadow-xs: 0 1px 2px rgba(17, 24, 39, 0.05);
	--nf-shadow-sm: 0 1px 2px rgba(17, 24, 39, 0.04), 0 4px 10px rgba(17, 24, 39, 0.05);
	--nf-shadow-md: 0 2px 6px rgba(17, 24, 39, 0.06), 0 12px 28px rgba(17, 24, 39, 0.09);
	--nf-shadow-focus: 0 0 0 4px rgba(194, 65, 12, 0.14);

	--nf-ease: cubic-bezier(0.4, 0, 0.2, 1);
	--nf-transition-fast: 160ms var(--nf-ease);
	--nf-transition: 220ms var(--nf-ease);
}

/* -------------------------------------------------------------------------
 * 1. Accessibility helpers
 * ---------------------------------------------------------------------- */

.screen-reader-text {
	border: 0;
	clip-path: inset(50%);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	white-space: nowrap;
	width: 1px;
}

.screen-reader-text:focus,
.nf-skip-link:focus {
	background: var(--wp--preset--color--base);
	clip-path: none;
	color: var(--wp--preset--color--primary-dark);
	display: block;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
	height: auto;
	left: 1rem;
	line-height: 1;
	padding: 1rem 1.25rem;
	position: fixed;
	top: 1rem;
	text-decoration: none;
	width: auto;
	z-index: 100000;
	outline: 3px solid var(--wp--preset--color--accent);
	outline-offset: 2px;
	box-shadow: var(--wp--preset--shadow--raised);
}

/* A single, consistent focus ring for every interactive element. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
	outline: 3px solid var(--wp--preset--color--accent);
	outline-offset: 2px;
	border-radius: 4px;
}

/* Respect a reduced-motion preference everywhere. */
@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}

/* Anchors land below the sticky header rather than under it. */
html {
	scroll-behavior: smooth;
	scroll-padding-top: 6rem;
}

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}
}

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

.nf-header {
	position: sticky;
	top: 0;
	z-index: 500;
	/* A soft translucent header reads more current than a flat white bar, and
	   still falls back gracefully (solid white) wherever backdrop-filter is
	   unsupported. */
	background: rgba(255, 255, 255, 0.92);
	border-bottom: 1px solid var(--wp--preset--color--border);
	box-shadow: 0 1px 0 rgba(17, 24, 39, 0.03);
}

/* Desktop only: backdrop-filter makes the header the containing block for
   position:fixed children, which would trap the mobile nav overlay (used
   below 600px) inside the header bar instead of covering the screen. */
@media (min-width: 600px) {
	@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
		.nf-header {
			backdrop-filter: saturate(180%) blur(10px);
			-webkit-backdrop-filter: saturate(180%) blur(10px);
		}
	}
}

/* While the mobile menu is open, lift the header (and its overlay) above the
   floating WhatsApp button. */
.nf-header:has(.wp-block-navigation__responsive-container.is-menu-open) {
	z-index: 1000;
}

.has-modal-open .nf-whatsapp-float {
	display: none;
}

.nf-header .wp-block-site-logo img {
	max-height: 52px;
	width: auto;
	transition: transform var(--nf-transition-fast);
}

.nf-header .wp-block-site-logo:hover img {
	transform: scale(1.04);
}

/* Branding + nav row. Given its own explicit width/centering rather than
   relying on core's alignwide/alignfull classes: those only take effect
   when their direct parent carries the "constrained" layout class, which
   the full-bleed <header> deliberately does not (the topbar and white nav
   band both need to paint edge-to-edge behind this row). */
.nf-header-row {
	box-sizing: border-box;
	margin-inline: auto;
	max-width: var(--wp--style--global--wide-size, 76rem);
	padding-inline: var(--wp--preset--spacing--30);
}

/* Below 480px the logo mark, "NF Industry" text, nav toggle and the Get a
   Quote button no longer all fit on one line. The logo image's alt text
   ("NF Industry logo") already names the business, and the logo links home
   the same as the site-title does, so the text is redundant here - hiding
   it (not the image) is what buys back the room. */
@media (max-width: 480px) {
	.nf-header-row .wp-block-site-title {
		display: none;
	}
}

.nf-header-cta {
	white-space: nowrap;
}

/* Primary nav links: smooth colour transition plus a small underline that
   grows in on hover/current, rather than an instant colour swap. */
.nf-header-row .wp-block-navigation-item > a {
	position: relative;
	transition: color var(--nf-transition-fast);
}

.nf-header-row .wp-block-navigation-item > a::after {
	content: "";
	position: absolute;
	left: 0;
	right: 100%;
	bottom: -4px;
	height: 2px;
	background: var(--wp--preset--color--accent);
	border-radius: 2px;
	transition: right var(--nf-transition-fast);
}

.nf-header-row .wp-block-navigation-item > a:hover::after,
.nf-header-row .wp-block-navigation-item > a:focus-visible::after,
.nf-header-row .wp-block-navigation-item.current-menu-item > a::after {
	right: 0;
}

/* The top strip above the main nav. */
.nf-topbar {
	background: var(--wp--preset--color--primary-dark);
	color: var(--wp--preset--color--base);
	font-size: var(--wp--preset--font-size--x-small);
}

.nf-topbar a {
	color: var(--wp--preset--color--base);
	text-decoration: none;
}

.nf-topbar a:hover,
.nf-topbar a:focus {
	color: var(--wp--preset--color--base);
	text-decoration: underline;
}

.nf-topbar__inner {
	align-items: center;
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem 1.25rem;
	justify-content: center;
	padding-block: 0.5rem;
}

@media (min-width: 782px) {
	.nf-topbar__inner {
		justify-content: space-between;
	}
}

.nf-topbar__group {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem 1.25rem;
	justify-content: center;
}

/* The opening-hours line is the least useful item on a phone. */
@media (max-width: 599px) {
	.nf-topbar__item--hours {
		display: none;
	}
}

.nf-footer-links {
	list-style: none;
	margin: 0;
	padding: 0;
}

.nf-footer-links li {
	margin-bottom: 0.55rem;
}

.nf-footer-links a {
	font-size: var(--wp--preset--font-size--small);
}

/* Keep the mobile nav overlay clear of the sticky header, and give the
   stacked links room to breathe with clear tap targets. */
.wp-block-navigation__responsive-container.is-menu-open {
	box-sizing: border-box;
	height: 100dvh;
	inset: 0;
	padding: var(--wp--preset--spacing--40) var(--wp--preset--spacing--30) !important;
	position: fixed;
	width: auto;
}

.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-dialog,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container {
	box-sizing: border-box;
	margin-inline: 0 !important;
	padding-inline: 0 !important;
	width: 100%;
}

/* Full-screen mobile menu: every link stacked and visible at once, centred,
   with large tap targets and a divider between items. */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
	align-items: stretch !important;
	padding-top: 3.5rem !important;
}

.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container {
	align-items: stretch !important;
	gap: 0 !important;
	width: 100%;
}

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

.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item > a {
	display: block;
	font-family: var(--wp--preset--font-family--heading);
	font-size: 1.25rem;
	font-weight: 600;
	padding-block: 1rem !important;
	text-align: center;
	width: 100%;
}

.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item.current-menu-item > a {
	color: var(--wp--preset--color--accent);
}

.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-close {
	right: var(--wp--preset--spacing--30);
	top: var(--wp--preset--spacing--30);
}

.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-close svg {
	height: 30px;
	width: 30px;
}

/* The desktop hover underline (added above) assumes an inline link sitting
   in a horizontal row; suppress it in the stacked mobile overlay. */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item > a::after {
	content: none;
}

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

.nf-footer {
	background: var(--wp--preset--color--primary-dark);
	color: #d7e0ea;
	position: relative;
}

/* A hairline brand-to-accent gradient at the seam between the page and the
   footer - a small, restrained signature rather than a flat colour change. */
.nf-footer::before {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: 3px;
	background: linear-gradient(90deg, var(--wp--preset--color--accent) 0%, var(--wp--preset--color--primary) 55%, var(--wp--preset--color--primary-dark) 100%);
}

.nf-footer h2,
.nf-footer h3,
.nf-footer h4 {
	color: var(--wp--preset--color--base);
}

.nf-footer a {
	color: #d7e0ea;
	text-decoration: none;
	transition: color var(--nf-transition-fast);
}

.nf-footer a:hover,
.nf-footer a:focus {
	color: var(--wp--preset--color--base);
	text-decoration: underline;
	text-underline-offset: 3px;
}

.nf-footer .nf-contact-list__label,
.nf-footer .nf-hours__day {
	color: #9fb3c8;
}

.nf-footer-bottom {
	border-top: 1px solid rgba(255, 255, 255, 0.12);
	color: #a9bcd0;
	font-size: var(--wp--preset--font-size--x-small);
}

/* -------------------------------------------------------------------------
 * 4. Block style variations
 * ---------------------------------------------------------------------- */

.wp-block-group.is-style-nf-card {
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--nf-radius-md);
	box-shadow: var(--nf-shadow-sm);
	height: 100%;
	padding: var(--wp--preset--spacing--40);
	transition: box-shadow var(--nf-transition), transform var(--nf-transition), border-color var(--nf-transition);
}

.wp-block-group.is-style-nf-card:hover {
	border-color: #e8c4ae;
	box-shadow: var(--nf-shadow-md);
	transform: translateY(-3px);
}

.wp-block-group.is-style-nf-bordered {
	border-left: 3px solid var(--wp--preset--color--accent);
	border-radius: 0 var(--nf-radius-sm) var(--nf-radius-sm) 0;
	padding: var(--wp--preset--spacing--20) var(--wp--preset--spacing--30);
	background: var(--wp--preset--color--surface);
}

/* Statistics row. */
.wp-block-columns.is-style-nf-stat-row {
	gap: var(--wp--preset--spacing--40);
	text-align: center;
}

.wp-block-columns.is-style-nf-stat-row .wp-block-column {
	border-bottom: 2px solid var(--wp--preset--color--accent);
	padding-bottom: var(--wp--preset--spacing--30);
}

@media (min-width: 782px) {
	.wp-block-columns.is-style-nf-stat-row .wp-block-column {
		border-bottom: 0;
		border-right: 1px solid var(--wp--preset--color--border);
		padding-bottom: 0;
	}

	.wp-block-columns.is-style-nf-stat-row .wp-block-column:last-child {
		border-right: 0;
	}
}

/* Checkmark list. */
.wp-block-list.is-style-nf-check-list {
	list-style: none;
	padding-left: 0;
}

.wp-block-list.is-style-nf-check-list li {
	padding-left: 1.9rem;
	position: relative;
	margin-bottom: 0.6rem;
}

.wp-block-list.is-style-nf-check-list li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.42em;
	width: 0.72rem;
	height: 0.38rem;
	border-left: 2.5px solid var(--wp--preset--color--accent);
	border-bottom: 2.5px solid var(--wp--preset--color--accent);
	transform: rotate(-45deg);
}

/* Framed image. */
.wp-block-image.is-style-nf-frame img {
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--nf-radius-md);
	box-shadow: var(--nf-shadow-sm);
}

/* Ghost button. */
.wp-block-button.is-style-nf-ghost .wp-block-button__link,
a.wp-element-button.is-style-nf-ghost {
	background: transparent;
	border: 2px solid currentColor;
	color: var(--wp--preset--color--primary-dark);
	transition: background-color var(--nf-transition), color var(--nf-transition), border-color var(--nf-transition);
}

.wp-block-button.is-style-nf-ghost .wp-block-button__link:hover,
.wp-block-button.is-style-nf-ghost .wp-block-button__link:focus,
a.wp-element-button.is-style-nf-ghost:hover,
a.wp-element-button.is-style-nf-ghost:focus {
	background: var(--wp--preset--color--primary-dark);
	border-color: var(--wp--preset--color--primary-dark);
	color: var(--wp--preset--color--base);
}

/* On a dark section the ghost button needs to read as light. The hero is a
   cover block with a gradient, so it carries no has-*-background-color class
   and must be listed explicitly - without it the button is dark-on-dark and
   effectively invisible. */
.nf-hero .wp-block-button.is-style-nf-ghost .wp-block-button__link,
.has-primary-dark-background-color .wp-block-button.is-style-nf-ghost .wp-block-button__link,
.has-primary-background-color .wp-block-button.is-style-nf-ghost .wp-block-button__link {
	border-color: var(--wp--preset--color--base);
	color: var(--wp--preset--color--base);
}

.nf-hero .wp-block-button.is-style-nf-ghost .wp-block-button__link:hover,
.nf-hero .wp-block-button.is-style-nf-ghost .wp-block-button__link:focus,
.has-primary-dark-background-color .wp-block-button.is-style-nf-ghost .wp-block-button__link:hover,
.has-primary-dark-background-color .wp-block-button.is-style-nf-ghost .wp-block-button__link:focus,
.has-primary-background-color .wp-block-button.is-style-nf-ghost .wp-block-button__link:hover,
.has-primary-background-color .wp-block-button.is-style-nf-ghost .wp-block-button__link:focus {
	background: var(--wp--preset--color--base);
	border-color: var(--wp--preset--color--base);
	color: var(--wp--preset--color--primary-dark);
}

/* Plus Jakarta Sans sets a fairly narrow word space, and tight heading
   tracking narrows it further, so words crowd each other in large headings,
   buttons and the nav. A little explicit word spacing restores the rhythm. */
h1, h2, h3, h4, h5, h6,
.wp-element-button,
.wp-block-button__link,
.wp-block-navigation,
.wp-block-site-title {
	word-spacing: 0.08em;
}

/* Every button on the site - the accent CTA, ghost buttons, form submit
   buttons - shares one restrained hover/active treatment: a small lift with
   a soft shadow, settling back down on click. Layered on top of each
   variant's own colour rules above rather than replacing them. */
.wp-element-button,
.wp-block-button__link {
	transition: background-color var(--nf-transition), color var(--nf-transition), border-color var(--nf-transition), box-shadow var(--nf-transition), transform var(--nf-transition-fast);
}

.wp-element-button:hover,
.wp-block-button__link:hover {
	box-shadow: var(--nf-shadow-sm);
	transform: translateY(-1px);
}

.wp-element-button:active,
.wp-block-button__link:active {
	box-shadow: none;
	transform: translateY(0);
}

/* -------------------------------------------------------------------------
 * 5. Eyebrow / section heading helper
 * ---------------------------------------------------------------------- */

.nf-eyebrow {
	align-items: center;
	color: var(--wp--preset--color--accent);
	display: inline-flex;
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 700;
	gap: 0.55rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	margin-bottom: 0.5rem;
}

/* A short marker rule in front of the eyebrow label - a small, quiet cue
   that this line introduces a section, used throughout marketing sections. */
.nf-eyebrow::before {
	content: "";
	display: inline-block;
	width: 1.25rem;
	height: 2px;
	background: currentColor;
	border-radius: 2px;
	flex: 0 0 auto;
}


.has-primary-dark-background-color .nf-eyebrow,
.has-primary-background-color .nf-eyebrow,
.nf-hero .nf-eyebrow {
	color: #ffb27d;
}

/* -------------------------------------------------------------------------
 * 6. Hero
 * ---------------------------------------------------------------------- */

.nf-hero {
	position: relative;
}

/* A quiet radial highlight behind the copy for depth, layered above the
   existing gradient background and below the content. Purely decorative. */
.nf-hero::before {
	content: "";
	position: absolute;
	inset: 0;
	background: radial-gradient(60% 90% at 15% 15%, rgba(255, 255, 255, 0.07), transparent 60%);
	pointer-events: none;
}

.nf-hero .wp-block-cover__inner-container {
	max-width: 46rem;
	position: relative;
}

/* -------------------------------------------------------------------------
 * 7. Product cards & archive
 * ---------------------------------------------------------------------- */

.nf-product-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--wp--preset--spacing--40);
}

@media (min-width: 600px) {
	.nf-product-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 900px) {
	.nf-product-grid {
		grid-template-columns: repeat(3, 1fr);
	}
}

/* The post-template block renders its own grid; this styles each card. */
.nf-product-card {
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--nf-radius-md);
	display: flex;
	flex-direction: column;
	height: 100%;
	overflow: hidden;
	transition: box-shadow var(--nf-transition), border-color var(--nf-transition), transform var(--nf-transition);
}

.nf-product-card:hover,
.nf-product-card:focus-within {
	border-color: #e8c4ae;
	box-shadow: var(--nf-shadow-md);
	transform: translateY(-3px);
}

.nf-product-card .wp-block-post-featured-image {
	margin: 0;
	overflow: hidden;
}

.nf-product-card .wp-block-post-featured-image img {
	aspect-ratio: 4 / 3;
	display: block;
	object-fit: cover;
	width: 100%;
	transition: transform var(--nf-transition);
}

/* A gentle zoom on the photo is a common, tasteful way to signal a card is
   interactive without moving or shadowing the image itself. */
.nf-product-card:hover .wp-block-post-featured-image img,
.nf-product-card:focus-within .wp-block-post-featured-image img {
	transform: scale(1.05);
}

.nf-product-card .wp-block-post-title {
	margin: 0;
}

.nf-product-card .wp-block-post-title a {
	text-decoration: none;
}

/* Makes the whole card clickable without nesting interactive elements. */
.nf-product-card .wp-block-post-title a::after {
	content: "";
	position: absolute;
	inset: 0;
}

.nf-product-card {
	position: relative;
}

.nf-product-card .wp-block-post-excerpt__excerpt {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--small);
}

/* Category filter. */
.nf-filter__list {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.nf-filter__link {
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 999px;
	color: var(--wp--preset--color--primary-dark);
	display: inline-block;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	padding: 0.5rem 1.15rem;
	text-decoration: none;
	transition: background var(--nf-transition-fast), border-color var(--nf-transition-fast), color var(--nf-transition-fast), box-shadow var(--nf-transition-fast);
}

.nf-filter__link:hover,
.nf-filter__link:focus {
	background: var(--wp--preset--color--primary-soft);
	border-color: var(--wp--preset--color--primary);
	color: var(--wp--preset--color--primary-dark);
}

.nf-filter__link.is-current {
	background: var(--wp--preset--color--primary-dark);
	border-color: var(--wp--preset--color--primary-dark);
	box-shadow: var(--nf-shadow-xs);
	color: var(--wp--preset--color--base);
}

/* Extra product photos, shown under the specifications table. */
.nf-product-gallery {
	display: grid;
	gap: 0.6rem;
	grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
	list-style: none;
	margin: var(--wp--preset--spacing--30) 0 0;
	padding: 0;
}

.nf-product-gallery__item a {
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--nf-radius-sm);
	display: block;
	overflow: hidden;
	transition: border-color var(--nf-transition-fast), box-shadow var(--nf-transition-fast);
}

.nf-product-gallery__item a:hover,
.nf-product-gallery__item a:focus-visible {
	border-color: var(--wp--preset--color--accent);
	box-shadow: var(--nf-shadow-xs);
}

.nf-product-gallery__item img {
	aspect-ratio: 1 / 1;
	display: block;
	object-fit: cover;
	width: 100%;
}

/*
 * Photos added to a product's editor content: centred, three to a row,
 * uniform size (the leftover row is centred too). Text keeps full width.
 */
.single-nf_product .wp-block-post-content {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--30);
	justify-content: center;
}

.single-nf_product .wp-block-post-content > * {
	flex: 0 0 100%;
	margin-block: 0;
}

.single-nf_product .wp-block-post-content > .wp-block-image {
	flex: 0 1 calc((100% - 2 * var(--wp--preset--spacing--30)) / 3);
	max-width: none;
	text-align: center;
}

.single-nf_product .wp-block-post-content > .wp-block-image img {
	aspect-ratio: 3 / 4;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--nf-radius-md);
	box-shadow: var(--nf-shadow-xs);
	height: auto !important;
	margin-inline: auto;
	object-fit: cover;
	width: 100% !important;
}

@media (max-width: 600px) {
	.single-nf_product .wp-block-post-content > .wp-block-image {
		flex-basis: calc((100% - var(--wp--preset--spacing--30)) / 2);
	}
}

/* -------------------------------------------------------------------------
 * 8. Specifications table
 * ---------------------------------------------------------------------- */

.nf-specs {
	margin-block: var(--wp--preset--spacing--40);
}

.nf-specs__title {
	font-size: var(--wp--preset--font-size--x-large);
	margin-bottom: var(--wp--preset--spacing--20);
}

/* Narrow screens scroll the table rather than squashing it. Rounded corners
   need border-collapse:separate (collapsed borders ignore border-radius),
   with overflow:hidden on the table itself clipping the row backgrounds to
   match - no extra wrapper markup required. */
.nf-specs__table {
	border: 1px solid var(--wp--preset--color--border);
	border-collapse: separate;
	border-radius: var(--nf-radius-md);
	border-spacing: 0;
	overflow: hidden;
	width: 100%;
	font-size: var(--wp--preset--font-size--small);
}

.nf-specs__table th,
.nf-specs__table td {
	border-bottom: 1px solid var(--wp--preset--color--border);
	padding: 0.8rem 0.9rem;
	text-align: left;
	vertical-align: top;
}

.nf-specs__table th {
	background: var(--wp--preset--color--surface);
	color: var(--wp--preset--color--primary-dark);
	font-weight: 700;
	width: 45%;
}

.nf-specs__table td {
	font-family: var(--wp--preset--font-family--mono);
}

.nf-specs__table tr:last-child th,
.nf-specs__table tr:last-child td {
	border-bottom: 0;
}

/* The featured-image block renders nothing at all when a product has no
   image, which would otherwise leave half the product header blank. Collapse
   the empty column and let the details take the full width. Scoped to this
   one layout so no other columns block is affected. */
.nf-product-header > .wp-block-column:not(:has(*)) {
	display: none;
}

/* Let the surviving column take the freed space. !important is needed because
   core ships `.wp-block-columns .wp-block-column[style*=flex-basis]{flex-grow:0}`,
   which is more specific than any plain class selector here. When both columns
   are visible their bases already total 100%, so there is no free space and
   this changes nothing - it only matters once the empty one is hidden. */
.nf-product-header > .wp-block-column {
	flex-grow: 1 !important;
}

/* -------------------------------------------------------------------------
 * 9. Product enquiry CTA
 * ---------------------------------------------------------------------- */

.nf-enquiry-cta {
	background: var(--wp--preset--color--primary-soft);
	border-radius: var(--nf-radius-md);
	border-left: 4px solid var(--wp--preset--color--accent);
	margin-block: var(--wp--preset--spacing--50);
	padding: var(--wp--preset--spacing--40);
}

.nf-enquiry-cta__title {
	font-size: var(--wp--preset--font-size--large);
	margin-top: 0;
}

.nf-enquiry-cta__text {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--small);
}

.nf-enquiry-cta__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	margin-top: var(--wp--preset--spacing--30);
}

/* -------------------------------------------------------------------------
 * 10. Contact details, hours, social
 * ---------------------------------------------------------------------- */

.nf-contact-list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.nf-contact-list__item {
	margin-bottom: var(--wp--preset--spacing--30);
}

.nf-contact-list__label {
	color: var(--wp--preset--color--muted);
	display: block;
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 700;
	letter-spacing: 0.1em;
	margin-bottom: 0.25rem;
	text-transform: uppercase;
}

.nf-contact-list__value,
.nf-contact-list address {
	display: block;
	font-size: var(--wp--preset--font-size--medium);
	font-style: normal;
	line-height: 1.5;
}

/* Second phone number sits on its own line via block display instead of a
   <br> between them (see nf_contact_details_shortcode()). */
.nf-contact-list__value--stacked span {
	display: block;
}

.nf-contact-list__extra {
	display: inline-block;
	font-size: var(--wp--preset--font-size--small);
	margin-top: 0.3rem;
}

.nf-contact-details--compact .nf-contact-list__item {
	margin-bottom: var(--wp--preset--spacing--20);
}

.nf-hours {
	list-style: none;
	margin: 0;
	padding: 0;
}

.nf-hours__row {
	border-bottom: 1px solid var(--wp--preset--color--border);
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	justify-content: space-between;
	padding: 0.6rem 0;
}

.nf-hours__row:last-child {
	border-bottom: 0;
}

.nf-hours__day {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--small);
}

.nf-hours__time {
	font-weight: 600;
}

.nf-social {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.nf-social__link {
	border: 1px solid currentColor;
	border-radius: var(--nf-radius-sm);
	display: inline-block;
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 600;
	padding: 0.45rem 0.95rem;
	text-decoration: none;
	transition: background-color var(--nf-transition-fast), color var(--nf-transition-fast);
}

/* currentColor drives the border, and on hover the fill too - so the label
   needs an explicit colour once the background takes over, or the text
   would vanish into it. What that colour should be depends on how light or
   dark currentColor resolves to in context (light on the dark footer, dark
   in the white contact-page card), so the footer gets its own override. */
.nf-social__link:hover,
.nf-social__link:focus-visible {
	background: currentColor;
	color: var(--wp--preset--color--base);
}

.nf-footer .nf-social__link:hover,
.nf-footer .nf-social__link:focus-visible {
	color: var(--wp--preset--color--primary-dark);
}

/* -------------------------------------------------------------------------
 * 11. Map
 * ---------------------------------------------------------------------- */

.nf-map {
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--nf-radius-md);
	line-height: 0;
	overflow: hidden;
}

.nf-map iframe {
	display: block;
	width: 100%;
	height: 340px;
}

@media (min-width: 782px) {
	.nf-map iframe {
		height: 440px;
	}
}

/* -------------------------------------------------------------------------
 * 12. Forms
 * ---------------------------------------------------------------------- */

.nf-form-wrap {
	scroll-margin-top: 6rem;
}

.nf-form__grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--wp--preset--spacing--30);
}

@media (min-width: 600px) {
	.nf-form__grid {
		grid-template-columns: repeat(2, 1fr);
	}

	.nf-field--wide {
		grid-column: 1 / -1;
	}
}

.nf-field__label {
	display: block;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	margin-bottom: 0.35rem;
}

.nf-req {
	color: var(--wp--preset--color--accent);
	margin-left: 0.15rem;
}

.nf-form input[type="text"],
.nf-form input[type="email"],
.nf-form input[type="tel"],
.nf-form input[type="url"],
.nf-form select,
.nf-form textarea {
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--nf-radius-sm);
	/* Without this, width:100% plus padding and border makes every field
	   ~28px wider than its column and the whole page scrolls sideways on a
	   phone. Browsers do not inherit box-sizing into form controls. */
	box-sizing: border-box;
	color: var(--wp--preset--color--contrast);
	/* 16px minimum stops iOS Safari zooming the page on focus. */
	font-family: inherit;
	font-size: 1rem;
	padding: 0.8rem 1rem;
	transition: border-color var(--nf-transition-fast), box-shadow var(--nf-transition-fast);
	width: 100%;
	max-width: 100%;
}

.nf-form textarea {
	min-height: 9rem;
	resize: vertical;
}

.nf-form input:hover,
.nf-form select:hover,
.nf-form textarea:hover {
	border-color: #c7ced8;
}

.nf-form input:focus,
.nf-form select:focus,
.nf-form textarea:focus {
	border-color: var(--wp--preset--color--primary);
	box-shadow: 0 0 0 4px var(--wp--preset--color--primary-soft);
	outline: none;
}

.nf-field--error input,
.nf-field--error select,
.nf-field--error textarea {
	border-color: #b32d2e;
	border-width: 2px;
}

.nf-field--error input:focus,
.nf-field--error select:focus,
.nf-field--error textarea:focus {
	box-shadow: 0 0 0 4px rgba(179, 45, 46, 0.12);
}

.nf-field__help {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--x-small);
	margin: 0.35rem 0 0;
}

.nf-field__error {
	color: #b32d2e;
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 600;
	margin: 0.35rem 0 0;
}

.nf-field--consent {
	margin-top: var(--wp--preset--spacing--30);
}

.nf-field--consent label {
	align-items: flex-start;
	display: flex;
	font-size: var(--wp--preset--font-size--small);
	gap: 0.6rem;
	line-height: 1.5;
}

.nf-field--consent input[type="checkbox"] {
	/* Tints the native checkbox itself, so ticking it doesn't jar against an
	   otherwise on-brand form - supported in every current browser, and a
	   plain unstyled checkbox everywhere it isn't. */
	accent-color: var(--wp--preset--color--accent);
	flex: 0 0 auto;
	margin-top: 0.25rem;
	width: 1.1rem;
	height: 1.1rem;
}

/* Keeps the consent sentence as one flex item so the privacy-policy link
   flows inline with the text instead of being pushed into its own column. */
.nf-consent-text {
	flex: 1 1 auto;
	min-width: 0;
}

.nf-form input[type="file"] {
	background: var(--wp--preset--color--surface);
	border: 1px dashed #b7c0cb;
	border-radius: var(--nf-radius-sm);
	box-sizing: border-box;
	font-size: var(--wp--preset--font-size--small);
	max-width: 100%;
	padding: 0.7rem 0.85rem;
	transition: border-color var(--nf-transition-fast), background-color var(--nf-transition-fast);
	width: 100%;
}

.nf-form input[type="file"]:hover {
	background: var(--wp--preset--color--primary-soft);
	border-color: var(--wp--preset--color--primary);
}

.nf-form input[type="file"]::file-selector-button {
	background: var(--wp--preset--color--primary-dark);
	border: 0;
	border-radius: var(--nf-radius-sm);
	color: var(--wp--preset--color--base);
	cursor: pointer;
	font-family: inherit;
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 600;
	margin-right: 0.75rem;
	padding: 0.55rem 0.95rem;
	transition: background-color var(--nf-transition-fast);
}

.nf-form input[type="file"]:hover::file-selector-button {
	background: var(--wp--preset--color--primary);
}

.nf-form__actions {
	margin-top: var(--wp--preset--spacing--30);
}

.nf-form__actions,
.nf-submit {
	/* Defensive: on at least one page in testing this button intermittently
	   stretched to several hundred pixels tall with no CSS rule found to
	   account for it (not reproducible via any selector search, and not
	   caused by the map iframe elsewhere on the same page). Pinning height
	   explicitly is cheap insurance against whatever the source turns out
	   to be. */
	height: auto !important;
	max-height: none;
}

.nf-submit {
	border: 0;
	cursor: pointer;
	font-family: inherit;
	width: 100%;
}

@media (min-width: 600px) {
	.nf-submit {
		width: auto;
	}
}

.nf-form__note {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--x-small);
	margin-top: var(--wp--preset--spacing--20);
}

/* Honeypot: off-screen, not display:none, so bots that skip hidden fields
   still fill it in. aria-hidden keeps it away from screen readers. */
.nf-hp {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

/* Alerts. */
.nf-alert {
	border-radius: var(--nf-radius-md);
	box-shadow: var(--nf-shadow-xs);
	margin-bottom: var(--wp--preset--spacing--40);
	padding: var(--wp--preset--spacing--30);
	scroll-margin-top: 6rem;
}

.nf-alert__title {
	font-size: var(--wp--preset--font-size--large);
	margin: 0 0 0.5rem;
}

.nf-alert p:last-child,
.nf-alert ul:last-child {
	margin-bottom: 0;
}

.nf-alert--success {
	background: #e8f5ec;
	border-left: 4px solid #1a7f37;
	color: #14532d;
}

.nf-alert--success .nf-alert__title {
	color: #14532d;
}

.nf-alert--error {
	background: #fdeaea;
	border-left: 4px solid #b32d2e;
	color: #7a1f20;
}

.nf-alert--error .nf-alert__title {
	color: #7a1f20;
}

.nf-alert--error ul {
	margin: 0;
	padding-left: 1.2rem;
}

.nf-alert--error a {
	color: #7a1f20;
}

/* Admin-only hints. */
.nf-notice--admin {
	background: #fff8e5;
	border: 1px dashed #b8860b;
	border-radius: var(--nf-radius-sm);
	color: #6b5200;
	font-size: var(--wp--preset--font-size--small);
	padding: 0.9rem 1.1rem;
}

.nf-notice--admin a {
	color: #6b5200;
}

/* -------------------------------------------------------------------------
 * 13. Floating WhatsApp button
 * ---------------------------------------------------------------------- */

.nf-whatsapp-float {
	align-items: center;
	background: #25d366;
	border-radius: 999px;
	bottom: 1rem;
	box-shadow: 0 4px 14px rgba(17, 24, 39, 0.28);
	/* #0b3d20 on #25d366 is ~7.3:1 - the white-on-green pairing used by most
	   WhatsApp widgets is only 2.1:1 and fails WCAG AA. */
	color: #0b3d20;
	display: inline-flex;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
	gap: 0.5rem;
	padding: 0.85rem 1.15rem;
	position: fixed;
	right: 1rem;
	text-decoration: none;
	transition: transform var(--nf-transition), box-shadow var(--nf-transition);
	z-index: 900;
}

.nf-whatsapp-float:hover,
.nf-whatsapp-float:focus {
	box-shadow: 0 8px 24px rgba(17, 24, 39, 0.32);
	color: #0b3d20;
	transform: translateY(-3px);
}

.nf-whatsapp-float__icon {
	flex: 0 0 auto;
}

/* On phones the label is dropped so the button never covers page content. */
.nf-whatsapp-float__label {
	display: none;
}

@media (min-width: 600px) {
	.nf-whatsapp-float {
		bottom: 1.5rem;
		right: 1.5rem;
	}

	.nf-whatsapp-float__label {
		display: inline;
	}
}

/* -------------------------------------------------------------------------
 * 14. Misc
 * ---------------------------------------------------------------------- */

/* Anything a template marks as the main landmark target. */
#nf-content {
	scroll-margin-top: 0;
}

/* Pagination. */
.wp-block-query-pagination {
	margin-top: var(--wp--preset--spacing--50);
}

.wp-block-query-pagination .page-numbers {
	border: 1px solid var(--wp--preset--color--border);
	border-radius: var(--nf-radius-sm);
	padding: 0.45rem 0.85rem;
	text-decoration: none;
	transition: background-color var(--nf-transition-fast), border-color var(--nf-transition-fast), color var(--nf-transition-fast);
}

.wp-block-query-pagination .page-numbers:hover,
.wp-block-query-pagination .page-numbers:focus-visible {
	background: var(--wp--preset--color--primary-soft);
	border-color: var(--wp--preset--color--primary);
}

.wp-block-query-pagination .page-numbers.current {
	background: var(--wp--preset--color--primary-dark);
	border-color: var(--wp--preset--color--primary-dark);
	color: var(--wp--preset--color--base);
}

/* Tables inside post content scroll instead of overflowing. */
.wp-block-table {
	overflow-x: auto;
}

/* Never let an image push the layout wider than the screen. */
img {
	max-width: 100%;
	height: auto;
}

/* Gallery images get a consistent crop, radius and a quiet hover lift so the
   grid matches the rest of the site's card language. */
.wp-block-gallery.nf-gallery img {
	aspect-ratio: 1 / 1;
	border-radius: var(--nf-radius-sm);
	object-fit: cover;
	transition: transform var(--nf-transition), box-shadow var(--nf-transition);
}

.wp-block-gallery.nf-gallery .wp-block-image:hover img {
	box-shadow: var(--nf-shadow-sm);
	transform: translateY(-2px);
}

/* 404 page. */
.nf-404__code {
	color: var(--wp--preset--color--border);
	font-size: clamp(5rem, 18vw, 10rem);
	font-weight: 800;
	line-height: 1;
	margin: 0;
}
