/* KREA Swiss — Template B components not natively expressible with Kadence Blocks controls.
   Palette reference (set in Customizer > Colors & Fonts): 1 red, 2 red-deep, 3/4 ink,
   5/6 muted, 7 line, 8 cream, 9 white. */

/* The doc's own base reset (`a{color:inherit;text-decoration:none}`) was
   never ported into the theme CSS, so any link without its own more
   specific text-decoration override (e.g. `.card a`, the Knowledge/Case
   Studies hub cards' "Read →" links) fell back to the browser's default
   underline. The doc never uses an underlined link anywhere, so this is a
   straight port, not a new design decision. */
a {
	text-decoration: none;
}

/* Two-column hero rows (text column + product photo column) are built with
   the doc's `.two{align-items:start}` in mind — each column should size to
   its own content, not stretch to match its sibling. Kadence's row is CSS
   Grid, whose grid items default to align-items:stretch, so both columns
   get forced to the height of the taller one (usually the photo); the
   shorter text column then shows a slab of dead white space below its
   content instead of just ending there. Kadence already tags these rows
   "kt-row-valign-top" for top-aligned content, but that only repositions
   content inside the stretched box — it doesn't stop the stretch itself.
   Make it actually mean "don't stretch": each column keeps its own height. */
.kt-row-valign-top {
	align-items: start;
}

/* Product page hero row (foodSPRAY Pro, volumeSPRAY, chocSPRAYER,
   chocMELTER): even with the align-items:start fix above stopping the text
   column from stretching, the row's own height is still set by its tallest
   column — usually the product photo, which is proportioned taller than the
   design doc's placeholder box relative to a shortish text column. That
   height difference then stacks with Kadence's default row bottom padding
   (100px, never explicitly set), producing a gap well past what the doc's
   section rhythm calls for. Trim the row's own padding down; the leftover
   gap from the column height difference is real photo content, not a bug,
   and isn't something to fake-fix by capping the image. */
.prodhero .kt-row-column-wrap {
	padding-bottom: 40px !important;
}

/* "Why professionals move to it" benefits-list row (foodSPRAY Pro only —
   the other three product pages go straight from hero to buy-row). Same
   unfixed Kadence default row padding (100px) as everywhere else in this
   file; trimmed to match .prodhero's 40px so the gap before the buy-row box
   is the same size whether or not a page has this extra row in between. */
.prodbens .kt-row-column-wrap {
	padding-bottom: 40px !important;
}

/* Food Safety page: "What to look for when you buy" row followed directly
   by "Standards we build to" — same unfixed Kadence default row padding
   (100px top/bottom) on both, stacking to a 200px gap between them well
   past what the doc's section rhythm calls for. Trim both to the same 40px
   used everywhere else this session, so only the gap shrinks, not the
   rows' own horizontal alignment. */
.fsdetail .kt-row-column-wrap {
	padding-bottom: 40px !important;
}
.fsstandards .kt-row-column-wrap {
	padding-top: 40px !important;
}

/* Motion (build sheet section 2): "A subtle fade and rise as each section
   enters the viewport, and nothing more. Respect the reduced motion
   setting." Never implemented until now. Kept deliberately simple —
   scroll-animations.js adds .kw-animate-section (only when JS runs and
   IntersectionObserver exists, so a no-JS visitor just sees the page fully
   visible with no animation at all, never a stuck-invisible section) and
   .kw-in-view once a section scrolls into place. The prefers-reduced-motion
   check lives in the JS file itself (skips adding the classes entirely), so
   there's no motion for anyone who's asked for less. */
.kw-animate-section {
	opacity: 0;
	transform: translateY(28px);
	transition: opacity .7s ease, transform .7s ease;
}
.kw-animate-section.kw-in-view {
	opacity: 1;
	transform: translateY(0);
}

/* Buy row — ported directly from the doc's own `.buyrow`/`.btn` CSS
   (verbatim values), used via a plain flex div (see the "Buy Row" block
   pattern) instead of Kadence's row/column blocks. Kadence's row/column
   abstraction was the root cause of every buy-row bug this build hit
   (invisible grid-wrapper divs, background painted on the wrong element,
   a vertical-align default that doesn't match `align-items:center`, and a
   padding model that can't express the doc's own component padding
   without a second nested layer) — a plain div matching the doc's own
   markup renders pixel-correct by construction, no per-row overrides
   needed. Still placed inside a single-column Kadence row so it inherits
   that row's responsive 1240px/gutter container for free, matching every
   other row's content width on the page. */
.buyrow {
	background: var(--global-palette8, #faf8f5);
	border-radius: 18px;
	padding: 28px 30px;
}
/* WP core's Group block always wraps saved content in a
   .wp-block-group__inner-container div in this WP version, regardless of
   the "layout" attribute type — so .buyrow's real two children (the
   kicker+h3 group and the .g button group) end up one level deeper than
   expected. Target both levels so the flex split works either way. */
.buyrow,
.buyrow > .wp-block-group__inner-container {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 20px;
	flex-wrap: wrap;
}
/* The inner-container is a flex item of .buyrow with default flex-basis:auto,
   so it only ever sizes to fit its own content instead of stretching to fill
   .buyrow's full width — leaving .buyrow's own space-between with just one
   child to distribute (i.e. nothing to do), and the real two children
   (text/button groups) end up hugging the left edge together instead of
   spanning the box. Force it to fill so its own space-between actually
   spans the box's full inner width. */
.buyrow > .wp-block-group__inner-container {
	width: 100%;
}
.buyrow h3 {
	font-size: 22px;
	margin: 0;
}
.buyrow .kicker {
	margin-bottom: 0;
}
.buyrow .g,
.buyrow .g > .wp-block-group__inner-container {
	display: flex;
	gap: 12px;
	flex-wrap: wrap;
	align-items: center;
}
/* Same stray Kadence default 32px Group-block margin-bottom bug as
   documented elsewhere in this file (.kw-specs .kw-s, .facts .f, .card,
   etc.) — the plain wp:group wrapping .buyrow's kicker+h3 pair picks it up
   too, inflating the box height well past its intended 28px-padding fit. */
.buyrow .wp-block-group {
	margin: 0 !important;
}
/* .buyrow sits inside a single-column Kadence row purely for the responsive
   container width — but Kadence's row block defaults to 100px top/bottom
   padding when no padding attribute is set, which would add 200px of extra
   air around a box that already has its own 28px padding. Collapse the
   bottom (the .dlrow that follows sets its own top spacing already), and
   set an explicit 40px top so there's always a real, deliberate gap before
   the box — not zero, and not left to Kadence's oversized default either. */
.buyrowouter .kt-row-column-wrap {
	padding-top: 40px !important;
	padding-bottom: 0 !important;
}
/* A sitewide main#inner-wrap{padding-bottom} was tried here and reverted —
   several pages (the homepage's last section among them) intentionally end
   in a dark/coloured panel meant to flow straight into the dark footer
   with no seam, and a blanket bottom padding inserted an unwanted band of
   white between them. Spacing has to be added per white-background
   component that's actually page-final, not globally — see
   .entry-content > .buyrowouter:last-child and .dlrow below. */
.entry-content > .buyrowouter:last-child .kt-row-column-wrap {
	padding-bottom: 56px !important;
}
/* .btn also matches when "btn"/"line"/"sm" are used as a native wp:button
   block's wrapper className (WP core Button has no "link className"
   attribute, only a wrapper one) — .wp-block-button.btn > .wp-block-
   button__link picks up the exact same look so converted CTAs still get
   the real pill-button styling without duplicating these rules.
   `:not(.wp-block-button)` on the bare .btn selector is required: the
   wrapper div itself also carries the literal class "btn" (it's the only
   place a className can land on a Button block), so without this exclusion
   the bare selector ALSO matched the wrapper, double-applying padding/
   background/border-radius to both wrapper and link and rendering as a
   visibly oversized "pill inside a pill". */
.btn:not(.wp-block-button),
.wp-block-button.btn > .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	font-weight: 600;
	font-size: 15px;
	padding: 14px 24px;
	background: var(--global-palette1, #e2001a);
	color: #fff;
	border-radius: 100px;
	transition: .2s;
	text-decoration: none;
	line-height: 1.3;
}
.btn:not(.wp-block-button):hover,
.wp-block-button.btn > .wp-block-button__link:hover {
	background: #b30015;
	color: #fff;
}
.btn.line:not(.wp-block-button),
.wp-block-button.btn.line > .wp-block-button__link {
	background: transparent;
	color: var(--global-palette3, #121212);
	border: 1.5px solid var(--global-palette3, #121212);
}
.btn.line:not(.wp-block-button):hover,
.wp-block-button.btn.line > .wp-block-button__link:hover {
	background: var(--global-palette3, #121212);
	color: #fff;
}
.btn.sm:not(.wp-block-button),
.wp-block-button.btn.sm > .wp-block-button__link {
	font-size: 13px;
	padding: 10px 18px;
}

/* Facts grid, case module, readout table, prodcallout — verbatim values
   ported from the doc's own CSS. UPDATE: the wrapper-div bug below is now
   understood precisely and no longer blocks using native wp:group blocks
   for these components (needed for client editability — see the "Full
   site conversion" effort). Root cause: WP core Group block's "layout"
   attribute controls whether it adds an extra .wp-block-group__inner-
   container div around its children. layout type "constrained" (and no
   layout at all) ALWAYS adds that wrapper div, even with the type set
   explicitly — that wrapper breaks any CSS rule here that expects
   `.parent > .child` / `display:grid|flex` direct-child relationships
   (e.g. .case's 1fr/1fr grid collapsing to one column because .media/
   .body become grandchildren instead of children). layout type "flex" or
   "grid" does NOT add the wrapper — the class lands directly on the
   .wp-block-group element itself. Rule of thumb: any wp:group standing in
   for one of these structural divs (one whose CSS role depends on being a
   direct grid/flex parent or child) MUST use "layout":{"type":"flex"} (or
   "grid"), never "constrained"/omitted, regardless of whether the visual
   result is actually flex or grid — this theme's own display:grid/flex
   declaration on the class still wins the cascade and decides the real
   layout; the Gutenberg layout type here is only chosen to suppress the
   wrapper div. Groups with no grid/flex dependency on direct children
   (plain padding/text stacks) are unaffected either way. Always verify
   with `wp eval 'echo do_blocks(...)'` for stray .wp-block-group__inner-
   container divs inside a structural class before trusting a screenshot —
   the isolated pattern editor can still look plausible even when broken. */
.facts {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 1px;
	background: var(--global-palette7, #e6e3df);
	border: 1px solid var(--global-palette7, #e6e3df);
	border-radius: 14px;
	overflow: hidden;
	margin-top: 26px;
}
.facts .f {
	background: #fff;
	padding: 22px;
	/* Same stray-32px-margin-bottom issue as .kw-specs .kw-s (see that
	   comment) — the native wp:group standing in for this cell otherwise
	   shows Kadence's default Group-block spacing as a thick grey band
	   between grid rows instead of the intended 1px line. */
	margin: 0 !important;
}
.facts .f h4 {
	font-size: 12px;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--global-palette1, #e2001a);
	margin: 0 0 8px !important;
}
.facts .f p {
	font-size: 14.5px;
	color: var(--global-palette5, #6f6c68);
	margin: 0 !important;
}
@media (max-width: 860px) {
	.facts { grid-template-columns: 1fr; }
}

.case {
	display: grid;
	grid-template-columns: 1fr 1fr;
	border: 1px solid var(--global-palette3, #121212);
	border-radius: 16px;
	overflow: hidden;
	margin-top: 26px;
}
.case .media {
	background: #0d0d0d;
	display: grid;
	grid-template-rows: 1.4fr 1fr;
	min-height: 340px;
	margin: 0 !important;
}
.case .photo {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	color: #7a7a7a;
	font-size: 11px;
	letter-spacing: .12em;
	text-transform: uppercase;
	border-bottom: 1px solid #2a2a2a;
	text-align: center;
	padding: 20px;
	overflow: hidden;
}
/* Real photos fill the placeholder box edge to edge instead of sitting
   centered as a small padded caption — same object-fit:cover convention
   used for .kw-ph.img elsewhere on the site. */
.case .photo img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}
.case .vthumb {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 10px;
	position: relative;
}
/* Video-thumbnail photo as a real wp:image (not a CSS background-image) —
   Cover block was tried first since it's the obvious native fit for
   "background photo + dark scrim + text on top", but its saved HTML is too
   easy to get subtly wrong by hand (an "aspect-ratio:unset" style property
   the save() function adds that isn't obvious from the block's own JSON
   attributes) and kept reading as invalid content. A plain wp:image
   absolutely positioned to fill the box, sitting behind the existing
   ::before dark-scrim pseudo-element and the caption text, gets the same
   look with zero risk of a markup mismatch. */
.case .vthumb .kw-vthumb-photo {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	margin: 0;
	z-index: 0;
}
.case .vthumb .kw-vthumb-photo img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}
.case .vthumb.kw-vthumb--has-video::before {
	z-index: 1;
}
.case .vthumb.kw-vthumb--has-video .mini,
.case .vthumb.kw-vthumb--has-video span,
.case .vthumb.kw-vthumb--has-video p {
	z-index: 2;
}
/* A real video teaser gets its thumbnail as a background (set inline per
   instance) with a dark scrim so the play button and caption stay legible
   over any photo, matching the plain-black placeholder's contrast. */
.case .vthumb.kw-vthumb--has-video {
	background-size: cover;
	background-position: center;
}
.case .vthumb.kw-vthumb--has-video::before {
	content: "";
	position: absolute;
	inset: 0;
	background: rgba(0,0,0,.45);
}
.case .vthumb.kw-vthumb--has-video .mini,
.case .vthumb.kw-vthumb--has-video span {
	position: relative;
}
.case .vthumb .mini {
	width: 42px;
	height: 42px;
	border-radius: 50%;
	background: var(--global-palette1, #e2001a);
	display: flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
}
.case .vthumb .mini::before {
	content: "";
	border-left: 13px solid #fff;
	border-top: 8px solid transparent;
	border-bottom: 8px solid transparent;
	margin-left: 4px;
}
.case .vthumb span {
	font-size: 11px;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: #cfcdca;
}
.case .body {
	padding: 30px;
	margin: 0 !important;
}
.case .tag {
	font-size: 11px;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--global-palette1, #e2001a);
}
.case h3 {
	font-size: 24px;
	margin: 10px 0 14px !important;
}
.case .metrics {
	display: flex;
	gap: 24px;
	flex-wrap: wrap;
	margin: 16px 0;
}
.case .metrics .fig {
	font-family: var(--global-heading-font-family, 'Bricolage Grotesque');
	font-weight: 800;
	font-size: 26px;
}
.case .metrics .cap {
	font-size: 10.5px;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--global-palette5, #6f6c68);
}
.case blockquote {
	border-left: 3px solid var(--global-palette1, #e2001a);
	padding: 2px 0 2px 16px;
	font-family: var(--global-heading-font-family, 'Bricolage Grotesque');
	font-weight: 500;
	font-size: 17px;
	line-height: 1.3;
	margin: 8px 0 0;
}
.case cite {
	display: block;
	font-size: 11px;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--global-palette5, #6f6c68);
	font-style: normal;
	margin-top: 10px;
}
@media (max-width: 860px) {
	.case { grid-template-columns: 1fr; }
}

.readout {
	border: 1px solid var(--global-palette3, #121212);
	border-radius: 14px;
	overflow: hidden;
	background: #fff;
}
.readout .rt {
	display: flex;
	flex-wrap: nowrap;
	justify-content: space-between;
	padding: 14px 18px;
	margin: 0 !important;
	border-bottom: 1px solid var(--global-palette3, #121212);
	font-size: 12px;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--global-palette5, #6f6c68);
}
/* Same stray default-32px-margin-bottom bug documented throughout this file
   (.kw-specs .kw-s, .rrow, .card, etc.) — here it's on .rt's own plain,
   unclassed <p> children (the .rrow fix doesn't reach these), and since a
   flex item's margin box counts toward the line's cross-axis height,
   align-items:center was stretching the whole header to ~80px to fit one
   32px-margined paragraph instead of the ~47px the content actually needs. */
.readout .rt > * {
	margin: 0 !important;
}
/* .rrow is a wp:group block with layout:{type:"flex"} (built that way so
   the editor's flex controls could set justify-content:space-between by
   hand) — but WP core auto-generates a scoped
   .wp-container-core-group-is-layout-*{display:flex} rule for every group
   using flex layout, and that rule's specificity beats this one, silently
   turning the intended 1.4fr/1fr/1fr/.8fr grid back into flex. With no
   flex-grow set, each column then just shrinks to fit its own text (e.g.
   "Lead" renders ~33px wide instead of the spec's 142px column), losing
   the aligned-columns readout look entirely. !important forces the grid
   back on; scoped to .rrow only, no other table/group is touched. */
.rrow {
	display: grid !important;
	grid-template-columns: 1.4fr 1fr 1fr .8fr;
	gap: 8px;
	padding: 13px 18px;
	margin: 0 !important;
	border-bottom: 1px solid var(--global-palette7, #e6e3df);
	font-size: 14px;
	align-items: center;
}
.rrow:last-child {
	border-bottom: 0;
}
.rrow .s, .rrow .v, .rrow .l, .rrow .g {
	/* Same stray-32px-margin-bottom issue as .kw-specs .kw-s and .facts .f
	   — protective fix even though the fixed-height row/border-bottom
	   structure here mostly masks it visually; keeps these paragraphs from
	   silently inflating .rrow's height. */
	margin: 0 !important;
}
.rrow .s { font-weight: 600; }
.rrow .l { color: var(--global-palette5, #6f6c68); }
.rrow .g { color: #0a7d34; font-weight: 600; font-size: 12px; }
@media (max-width: 860px) {
	.rrow { grid-template-columns: 1.4fr 1fr .8fr; }
	.rrow .l { display: none; }
}

.prodcallout {
	background: var(--global-palette8, #faf8f5);
	border-radius: 14px;
	padding: 22px 24px;
	margin: 26px 0;
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 16px;
	flex-wrap: wrap;
}
.prodcallout p {
	font-size: 15px;
	margin: 0;
}

/* FAQ accordion (native WordPress Details block) — the doc has no dedicated
   mockup for this component, but it's used sitewide (FAQ page, and the FAQ
   schema script reads its Q&A pairs straight from this markup), and had
   never received any typography/spacing treatment: it was rendering as the
   browser's bare `<details>` default (no hierarchy, no rhythm between
   entries, no brand-consistent marker). Brought in line with the same ink/
   red/muted system used everywhere else. */
.wp-block-details {
	border-bottom: 1px solid var(--global-palette7, #e6e3df);
	padding: 20px 0;
}
.wp-block-details:first-of-type {
	border-top: 1px solid var(--global-palette7, #e6e3df);
}
.wp-block-details summary {
	font-family: var(--global-heading-font-family, 'Bricolage Grotesque');
	font-weight: 700;
	font-size: 17px;
	line-height: 1.3;
	color: var(--global-palette3, #121212);
	cursor: pointer;
	list-style: none;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
}
.wp-block-details summary::-webkit-details-marker {
	display: none;
}
.wp-block-details summary::after {
	content: "+";
	flex-shrink: 0;
	width: 20px;
	font-size: 20px;
	font-weight: 400;
	color: var(--global-palette1, #e2001a);
	text-align: center;
}
.wp-block-details[open] summary::after {
	content: "\2212";
}
.wp-block-details summary:hover {
	color: var(--global-palette1, #e2001a);
}
.wp-block-details summary:focus-visible {
	outline: 2px solid var(--global-palette1, #e2001a);
	outline-offset: 4px;
}
.wp-block-details p {
	margin-top: 12px !important;
	font-size: 15.5px;
	color: var(--global-palette5, #6f6c68);
	line-height: 1.6;
}

/* Base body font-size is 16px in Template B; the Customizer's base
   typography setting was left at Kadence's default 17px. */
body {
	font-size: 16px;
}

/* Case Study CPT: Kadence auto-renders its own generic entry-title header
   above the content (unstyled, huge) since the post type supports 'title'.
   The real, properly-styled H1 already lives in the block content below, so
   the auto one is a redundant duplicate — hide it. */
.case_study-title {
	display: none;
}
/* Kadence's .single-content still carries the margin-top it normally uses
   to clear that title (32px), leaving orphaned dead space now the title
   itself is hidden. Zero it so the hero row's own 100px padding is the only
   gap under the header, matching every other page's spacing. */
.single-case_study .single-content {
	margin-top: 0;
}

/* Breadcrumb trail — rendered globally by kreaswiss_auto_breadcrumb() (see
   functions.php) via Rank Math's [rank_math_breadcrumb] shortcode, printed
   once at the top of every singular page/post/CPT, sitting above the first
   Kadence row rather than inside it. In the doc, the crumb lives INSIDE the
   hero section, so the section's own top padding (~70px) is the ONE gap
   before the crumb, and the crumb's 16px margin-bottom is the ONLY gap after
   it, before the kicker. Moving the crumb outside the row broke that: the
   row's own ~70-100px top padding still pushes the kicker down, landing as a
   second huge gap AFTER the crumb instead of before it. Fix: this wrapper
   takes over the "gap before" role (matching the doc's section padding
   formula), and the first row's own top padding is zeroed below so it no
   longer double-pads on top of it. */
.kw-auto-breadcrumb-wrap {
	max-width: 1240px;
	margin-left: auto;
	margin-right: auto;
	padding-left: clamp(22px, 5vw, 72px);
	padding-right: clamp(22px, 5vw, 72px);
	padding-top: clamp(40px, 5vw, 72px);
	box-sizing: border-box;
}
/* The first row on any page with the auto-breadcrumb no longer needs its own
   top padding — the wrapper above already supplies that gap, and the row's
   own padding would otherwise stack a second, much larger gap between the
   breadcrumb and the kicker/H1 instead of before the breadcrumb. */
body:not(.home) .entry-content > .wp-block-kadence-rowlayout:first-child > .kt-row-column-wrap {
	padding-top: 0 !important;
}
/* On Knowledge articles, the doc places the breadcrumb INSIDE `.article`
   (the 720px reading column) — but this auto-breadcrumb wrapper hooks into
   `kadence_before_content`, entirely outside the post content, so it always
   rendered at the sitewide 1240px container width regardless. At narrow
   viewports the difference wasn't visible (both columns fill the same
   space), but at wide viewports the breadcrumb (1240px, centered) no
   longer lines up with the article column (720px, centered) beneath it. */
.single-post .kw-auto-breadcrumb-wrap {
	max-width: 720px;
	padding-left: 0;
	padding-right: 0;
}
/* Styled to match the original look: muted trail, current page in ink. */
.rank-math-breadcrumb p {
	font-size: 13px;
	color: var(--global-palette5, #6f6c68);
	margin-top: 0 !important;
	margin-bottom: 16px !important;
}
.rank-math-breadcrumb a {
	color: var(--global-palette5, #6f6c68);
	text-decoration: none;
}
.rank-math-breadcrumb a:hover {
	color: var(--global-palette1, #e2001a);
}
.rank-math-breadcrumb .last {
	color: var(--global-palette3, #121212);
	font-weight: 600;
}
.rank-math-breadcrumb .separator {
	margin: 0 2px;
}

/* Every Row Layout's own background can bleed full width (fullwidth/unboxed page
   layout, set per-page), but its content always centers at the site container width. */
.kt-row-column-wrap {
	max-width: 1240px;
	margin-left: auto;
	margin-right: auto;
	padding-left: clamp(22px, 5vw, 72px);
	padding-right: clamp(22px, 5vw, 72px);
	box-sizing: border-box;
}
/* Kadence's own stylesheet ships a higher-specificity rule for any row with
   a background color — `.kt-row-has-bg > .kt-row-column-wrap { padding-left:
   var(--global-content-edge-padding, 15px) }` — which silently narrows the
   side gutter on every colored panel (red/cream/black bands) to a different
   value than plain rows use, sitewide. !important restores the one gutter. */
.kt-row-has-bg > .kt-row-column-wrap {
	padding-left: clamp(22px, 5vw, 72px) !important;
	padding-right: clamp(22px, 5vw, 72px) !important;
}
/* Kadence generates a per-row rule (.kb-row-layout-idXXX > .kt-row-column-wrap)
   for every single row that hardcodes 1.5rem (24px) vertical padding — same
   specificity as a plain class selector, so it silently wins over the rule
   above. !important is the only way to guarantee the intended section rhythm
   (60-110px, per the build sheet) without hand-targeting every row ID. */
.kt-row-column-wrap {
	padding-top: clamp(40px, 7vw, 100px) !important;
	padding-bottom: clamp(40px, 7vw, 100px) !important;
}
/* Hero row is asymmetric in Template B (`.hero{padding-top:clamp(40px,6vw,80px);
   padding-bottom:clamp(20px,3vw,40px)}`), and that padding-bottom applies
   AFTER the marquee there (hero wraps the marquee). In this markup the
   marquee is a separate block after the row, so that same padding-bottom
   value is already folded into the marquee's own margin-top/redpanel gap
   math instead — applying it again here would double it. Bottom padding on
   this row itself is zeroed; only the top value (which does sit before the
   row's own content) carries over directly. */
.kb-row-layout-idhphero > .kt-row-column-wrap {
	padding-top: clamp(40px, 6vw, 80px) !important;
	padding-bottom: 0 !important;
}

/* Buttons — Kadence Blocks' "Fill"/"Outline" global-style presets don't
   reliably pick up this theme's Customizer button settings (they fall back
   to the plugin's own hardcoded 3px-radius default instead), so the exact
   values from kreaswiss-web-designer-document.html's `.btn` rule
   (padding:14px 24px) are pinned directly here. */
.kb-button.kb-btn-global-fill {
	border-radius: 100px !important;
	padding: 14px 24px !important;
	font-size: 15px !important;
	font-weight: 600 !important;
	background-color: #e2001a !important;
	color: #fff !important;
	/* Matches the outline button's actual (Kadence-controlled) 1px
	   border-width with a transparent border, so a fill/outline button pair
	   sitting side by side render at identical heights — without it, the
	   outline button's visible border made it 2px taller than the fill one. */
	border: 1px solid transparent !important;
	transition: .2s;
}
.kb-button.kb-btn-global-fill:hover {
	background-color: #b30015 !important;
}
.kb-button.kb-btn-global-outline {
	border-radius: 100px !important;
	padding: 14px 24px !important;
	font-size: 15px !important;
	font-weight: 600 !important;
	background-color: transparent !important;
	color: #121212 !important;
	border: 1.5px solid #121212 !important;
	transition: .2s;
}
.kb-button.kb-btn-global-outline:hover {
	background-color: #121212 !important;
	color: #fff !important;
}
/* Small-size preset (used for in-article CTAs) keeps the pill shape, smaller padding */
.kb-button.kt-btn-size-small {
	padding: 10px 18px !important;
	font-size: 13px !important;
}

/* Fluent Forms ships its own default blue submit button — brought in line with
   the site's red pill buttons (Contact + Food Safety document request forms). */
.ff-btn-submit,
.fluentform button[type="submit"] {
	background-color: #e2001a !important;
	border-color: #e2001a !important;
	border-radius: 100px !important;
	padding: 14px 24px !important;
	font-size: 15px !important;
	font-weight: 600 !important;
	font-family: 'Inter', sans-serif !important;
	box-shadow: none !important;
	transition: .2s;
}
.ff-btn-submit:hover,
.fluentform button[type="submit"]:hover {
	background-color: #b30015 !important;
	border-color: #b30015 !important;
}
.fluentform .ff-el-input--label label,
.fluentform label {
	font-size: 12px;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: #6f6c68;
	font-weight: 400;
}
/* Fluent Forms' own default field spacing (20px between fields) is looser
   than the doc's `.field{margin-bottom:12px}`, making the whole form read
   taller/more spread out than the reference. */
.fluentform .ff-el-group {
	margin-bottom: 12px !important;
}
.fluentform input[type="text"],
.fluentform input[type="email"] {
	height: 44px !important;
}
.fluentform textarea {
	height: 96px !important;
}
.fluentform input[type="text"],
.fluentform input[type="email"],
.fluentform textarea {
	border-radius: 10px !important;
	border-color: #e6e3df !important;
	font-family: 'Inter', sans-serif !important;
	background-color: #fafafa !important;
	font-size: 14px !important;
}
/* Food Safety's "Get the document" request form is the doc's compact
   `.buyrow .g input` pill (height:46px, radius:100px, white background) —
   a distinct component from the Contact page's plain rectangular fields,
   which otherwise share the same generic Fluent Forms styling above. */
.kb-row-layout-idfs-doc .fluentform input[type="email"] {
	height: 46px !important;
	border-radius: 100px !important;
	background-color: #fff !important;
	padding-left: 18px !important;
	padding-right: 18px !important;
}

/* Type scale (build sheet section 2): Kadence's Customizer only exposes one
   global heading size/weight, not the per-level clamp scale, so it's set here. */
/* Kadence's own content.min.css ships `.single-content h1,h2,h3{margin:1.5em 0 .5em}`
   (relative to each heading's OWN font-size, so a 96px H1 gets a 144px top
   margin) at equal selector specificity to a plain "body h1" rule, and it
   loads after this stylesheet — so !important is the only reliable way to
   zero it out and match Template B's flat reset. */
body h1 {
	font-size: clamp(42px, 7vw, 86px);
	font-weight: 700;
	line-height: 1.02;
	letter-spacing: -.02em;
	margin: 0 !important;
}
/* Only the homepage hero H1 gets the doc's tighter -.03em tracking
   (`.hphero h1{letter-spacing:-.03em}`) — every other heading uses the
   generic h1-h4 rule's -.02em. */
body.home h1 {
	letter-spacing: -.03em;
}
body h2 {
	font-size: clamp(30px, 4vw, 52px);
	font-weight: 700;
	line-height: 1.02;
	letter-spacing: -.02em;
	margin: 0 !important;
}
body h3 {
	font-size: 24px;
	font-weight: 700;
	line-height: 1.02;
	letter-spacing: -.02em;
	margin: 0 !important;
}
/* Contact page's two form-card headings ("General enquiry"/"OEM and key
   account") — the sitewide body h3 rule below silently wins on margin
   regardless of inline styles, since !important beats even inline style
   specificity — the same precedence gotcha found repeatedly elsewhere
   this build. Scoped by a class on the headings themselves rather than
   the page's post/page ID, since an ID-scoped rule silently stops
   matching anything (with no visible error) the moment a page is deleted
   and rebuilt, or its ID otherwise changes — a class survives that. */
.kw-contact-form-h3 {
	margin: 0 0 6px !important;
}
/* Food Safety's "Built to come apart..." H2, same gotcha and same
   class-not-ID reasoning as above. */
.kw-fs-detail-h2 {
	margin: 12px 0 !important;
}
/* Small uppercase red "section label" h3s (e.g. "User manuals", "Our core
   competencies", "Trusted in kitchens like") used across several pages as
   in-content sub-section dividers — same !important-precedence gotcha as
   above, but a page-ID selector isn't safe here since these pages also mix
   in plain h3s for other things (card titles, buy-row headings) that must
   keep their own margins. A shared class scoped to just these headings
   fixes the bug and gives every instance sitewide the same, consistent
   gap, rather than each page's slightly different 8-38px inline guess. */
.kw-h3-label {
	margin: 34px 0 6px !important;
}
/* Small red uppercase eyebrow-style h3 label (e.g. "Our core competencies"
   above a spec grid) — was repeated per-instance as inline style
   (font-size/letter-spacing/text-transform/color), now a class so it can be
   set via a native heading block's className instead of hand-written style. */
.kw-h3-eyebrow {
	font-size: 15px;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--global-palette1, #e2001a);
}
/* "From Krebs of Switzerland to today." on Our Story is a real visible
   sub-heading (not a small label), so it keeps its own larger margin. */
.kw-h3-subhead {
	margin: 32px 0 10px !important;
	font-size: 22px;
	font-family: var(--global-heading-font-family, 'Bricolage Grotesque');
	font-weight: 700;
}
/* Tempering article's mistake/sub-point sub-headings were originally H4
   under H2 (skipping H3 — a genuine heading-hierarchy gap, unlike the
   rest of the site's consistent H1->H3 pattern), promoted to H3 for
   correct nesting. They'd previously inherited spacing from Kadence's own
   relative h4 rule (1.5em/0.5em); body h3's !important:0 would otherwise
   flatten them, so it's restored explicitly. Class-scoped rather than
   postid-scoped — same "survives a page/post being deleted and rebuilt"
   reasoning as the two rules above (this one was in fact originally
   written as .page-id-320, which silently never matched at all since 320
   is a post, not a page — postid-320 was the fix, but a class removes
   the page-vs-post distinction as a footgun entirely). */
.kw-article-subhead {
	margin: 1.5em 0 0.5em !important;
}
/* body h1's clamp(46px,7vw,96px) is the homepage hero size only. The design
   doc's inner "pagehero" template (Technology pillar, Knowledge hub, Food
   Safety, Company, Contact, etc.) specifies a smaller .pagehero h1 scale —
   clamp(32px,5vw,60px) — but those pages don't carry a shared class in the
   live markup (each Kadence row/column gets its own per-instance ID), so
   scope by what does reliably differ: only the front page gets body.home. */
body:not(.home) h1 {
	font-size: clamp(32px, 5vw, 60px);
	margin: 14px 0 16px !important;
}
/* body h2's clamp(30px,4vw,52px) is sized for page-section headings; it also
   caught genuine in-article body subheadings on Knowledge articles, blowing
   them up to hero size. Originally scoped to .single-content alone, assuming
   that class only existed on single post/CPT views — wrong: Kadence applies
   it to the front page too, so this was silently shrinking the homepage's
   "Food safety" H2 (and any other page-level H2) down to article-body size.
   .single-post is WordPress's own body class for singular blog-post views
   specifically (the 2 Knowledge articles), so it excludes the homepage,
   every other Page, and the case-study CPT precisely. */
.single-post .single-content h2 {
	font-size: 26px;
	line-height: 1.2;
	margin: 30px 0 12px !important;
}
/* Article body copy: the doc softens long-form paragraphs to #26251f
   (not pure ink) with an explicit 18px bottom margin; per-paragraph inline
   styles on these posts only ever set font-size/line-height, so color and
   spacing were falling back to the sitewide pure-ink body color and default
   paragraph margin. */
.single-post .single-content p {
	color: #26251f;
	margin-bottom: 18px !important;
}
/* The Knowledge article template never got the doc's `.article{max-
   width:720px;margin:0 auto}` reading-column wrapper — the developer built
   the article's own content (kicker, H1, hero photo, body) as a wp:html
   block matching the doc, but that block can't retroactively wrap the
   separate heading/paragraph blocks that follow it, so the doc's central
   design decision (a comfortable ~720px reading column) never made it in;
   the article renders full theme-content-width instead. Fixed here at the
   container level rather than in each post's content.
   !important is required: Kadence's own content.min.css carries
   `.content-title-style-hide .entry-content, .content-title-style-above
   .entry-content{margin:0}`, which has the SAME specificity (two classes)
   as this rule and loads after it in the compiled <head>, so it silently
   won on source order alone and left the column flush left instead of
   centered (max-width took effect since Kadence's rule doesn't touch it;
   only the margin was clobbered). */
.single-post .single-content {
	max-width: 720px !important;
	margin-left: auto !important;
	margin-right: auto !important;
}

/* Hero photo moves above the text column on mobile/tablet (build sheet
   responsive requirement), since Kadence's grid columns don't reorder on their own. */
@media (max-width: 1024px) {
	.kadence-columnhphero-r { order: -1; }
}

/* Red brand panel headline runs larger than the generic H2 scale in Template B
   (clamp 30-60px, not 30-52px). The food-safety headline stays at the default 52px. */
/* Template B always gives the red "Swiss divider" band its own breathing
   room above whatever precedes it (`.redpanel{margin-top:clamp(50px,7vw,100px)}`) —
   matched here via Kadence's generated red-background class so it applies
   to any red-panel row sitewide, not just the homepage. */
.has-theme-palette1-background-color {
	margin-top: clamp(50px, 7vw, 100px) !important;
}
/* When a red panel directly follows the marquee, Template B's hero section
   contributes its own responsive bottom padding (clamp(20px,3vw,40px)) on
   top of the panel's own margin-top — adjacent-sibling margins would
   otherwise collapse to just the larger of the two, so this is scoped to
   that specific pairing and kept responsive to match at every width. */
.kw-marquee + .has-theme-palette1-background-color {
	margin-top: calc(clamp(50px, 7vw, 100px) + clamp(20px, 3vw, 40px) - 20px) !important;
}

.kadence-columnhpred-r p {
	margin-bottom: 0 !important;
}

/* "What we make" heading sits 14px below its kicker (build sheet homepage
   spec); every other kicker+heading pair in Template B has no extra gap. */
.kadence-columnhpmake-c h2 {
	margin-top: 14px !important;
	/* Template B wraps the kicker+heading in `.top{max-width:56ch}`, so the
	   headline breaks onto a second line even at full row width instead of
	   stretching to fill it. `ch` is relative to the element's OWN font-size;
	   template applies it in the 16px body context, not the heading's own
	   52px, so the equivalent here is the resolved pixel value (56ch @ 16px
	   = 565px), not `56ch` written directly on the (much larger) heading. */
	max-width: 565px;
}
.kadence-columnhpmake-c .kicker {
	max-width: 565px;
	display: block;
}
/* The global `body h2{margin:0}` reset (needed to kill Kadence's own huge
   em-based heading margins elsewhere) also zeroed the 46px gap Template B
   gives this heading before the card grid (`.top{margin-bottom:46px}`). */
.kadence-columnhpmake-c .cards {
	margin-top: 46px;
}
/* "What we make" row uses a slightly larger vertical rhythm than the rest of
   the page's rows (.prog{padding-block:clamp(60px,8vw,110px)} vs the site
   default clamp(40px,7vw,100px)). */
.kb-row-layout-idhpmake > .kt-row-column-wrap {
	padding-top: clamp(60px, 8vw, 110px) !important;
	padding-bottom: clamp(60px, 8vw, 110px) !important;
}

/* Kicker eyebrow label, used ahead of every H1/H2/H3. Was a plain inline
   <span> in the original design (no block-level spacing at all), now a
   native wp:paragraph after the block-conversion work — which picks up
   Kadence's default 32px Group/paragraph bottom margin since nothing here
   overrode it. .buyrow .kicker{margin-bottom:0} handles this inside actual
   .buyrow markup, but that's not !important, so it loses to this rule's
   8px wherever both apply — fine, 8px still reads as "tight" everywhere,
   and this is the only override needed for every other kicker on the site
   (heroes, section labels, etc.) that isn't inside a .buyrow. */
.kicker {
	font-size: 13px;
	font-weight: 600;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--global-palette1, #e2001a);
	display: inline-block;
	margin: 0 0 8px !important;
}

/* Product page "Downloads: ..." caption row (foodSPRAY Pro, volumeSPRAY,
   chocSPRAYER, chocMELTER). Per the design doc (TEMPLATE 02), this line sits
   as a plain caption below the cream buy-row box, on the page's own white
   background — not inside the box. Built as its own single-column Kadence
   row so it inherits the page's horizontal gutter (Kadence's row default
   left/right padding is what aligns it with the rest of the content), but
   Kadence's row block also defaults to 100px top/bottom padding when no
   padding attribute is set, which is far too much for a one-line caption.
   Keep the horizontal padding (alignment), collapse the vertical. This row
   is also the last thing on the page before the footer, so bottom gets its
   own deliberate value rather than 0 — same reasoning as .buyrowouter's
   :last-child rule above, kept per-component instead of a global
   main-wrapper rule (which broke pages whose last section is a dark panel
   meant to flow into the dark footer with no seam). */
.dlrow .kt-row-column-wrap {
	padding-top: 20px !important;
	padding-bottom: 56px !important;
}

/* Muted eyebrow caption (Application/Technique/Spraying · category) used
   above sub-page H1s — visually distinct from .kicker (grey not red,
   lighter tracking, no bold weight). Was hand-written inline style on every
   instance's wp:html div; letter-spacing and text-transform have no block
   JSON attribute equivalent (only fontSize/color/margin do), so bundling
   every property into one class avoids a part-JSON/part-inline-style split
   that would still read as invalid content for the untranslatable pieces. */
.kw-eyebrow {
	font-size: 12px;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: #6f6c68;
	margin-bottom: 12px;
}

/* Card grids (What we make / Knowledge hub / related). Every Group block in
   this file's markup declares an explicit "layout" attribute (even when it's
   just {"type":"flow"} or {"type":"flex"}) specifically so WP skips its
   legacy `.wp-block-group__inner-container` wrapper div — targeting both the
   wrapper and its inner-container at once (an earlier version of this rule)
   turns both into grid containers simultaneously, nesting a grid inside a
   grid and squeezing real content into one quarter of the row. */
.cards {
	display: grid !important;
	grid-template-columns: repeat(3, 1fr) !important;
	gap: 20px;
	margin-top: 30px;
}
/* When `.cards` wraps a Query Loop (e.g. the Case Studies hub, pulling
   dynamically from the case_study CPT) instead of hand-written card divs,
   its only direct child is the loop's own <ul class="wp-block-post-
   template">, with each card one level further in as an <li> — the same
   invisible-wrapper problem as Kadence's Group block (see the memory doc's
   Kadence gotchas #1), just from core Gutenberg instead. The grid has to
   move down to whichever element actually holds the repeated cards. */
.cards .wp-block-post-template {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 20px;
	list-style: none;
	margin: 0;
	padding: 0;
}
.cards .wp-block-post-template > li {
	list-style: none;
}
/* The Query Loop case above still leaves `.cards` itself a 3-column grid
   with exactly one grid item — the <ul> — which occupies column 1 only and
   sizes to its own min-content, while columns 2 and 3 sit empty. That's a
   second, outer grid stacked on top of the real one, and it was squeezing
   the <ul> (and every card inside it) into a fraction of the row's actual
   width instead of letting the inner 3-column grid use the full width. */
.cards:has(> .wp-block-post-template) {
	display: block !important;
}
.card {
	border: 1px solid var(--global-palette7, #e6e3df);
	border-radius: 16px;
	overflow: hidden;
	background: #fff;
	transition: .2s;
	/* Same stray-32px-margin-bottom issue as .kw-specs .kw-s / .facts .f —
	   less visible here since .cards has no background color to reveal it
	   as a grey band, but it was still inflating the gap between card rows
	   from the intended 20px to 52px. */
	margin: 0 !important;
}
/* Real featured-image photos reuse `.kw-ph`'s dark placeholder box (same
   aspect-ratio/rounded treatment) as their frame; the image itself still
   needs sizing to actually fill that box edge to edge. The base `.kw-ph`
   rule carries `padding:20px` for centering the placeholder's text label —
   real photos don't want that padding (it left a visible dark-gradient
   bezel around the image), so it's zeroed here. */
.kw-ph.img {
	padding: 0;
	/* object-fit:cover only crops the img's own raster content — it never
	   changes the img element's box, which stays a plain rectangle. Without
	   this, a real photo's square corners sit on top of and hide whatever
	   border-radius the box itself carries (16px default, or a per-instance
	   override like the testimonial avatar's 50% or Before/After's 14px).
	   Never surfaced before this class was combined with an actual <img> —
	   the text-only placeholder had nothing to clip. */
	overflow: hidden;
}
/* `.kw-ph`'s flex centering (align-items/justify-content:center) was built
   for the short placeholder text label — fine as-is for text-only slots,
   but it also treats a linked <img> as a flex item sized to its own content
   instead of stretching to fill, so a real photo shrinks to its intrinsic
   aspect ratio and floats centered in the dark gradient box. Scoped to
   `:has(img)` so it only kicks in once a real photo (or its <a> wrapper)
   is actually inside — a bare "Photo, X" text placeholder with no <img>
   keeps the base centered label instead of jumping to the top edge. */
.kw-ph.img:has(> img), .kw-ph.img:has(> a), .kw-ph.img:has(> figure) {
	align-items: stretch;
}
.kw-ph.img > a {
	display: block;
	width: 100%;
	height: 100%;
}
/* Same fix as `.kw-ph.img > a` above, for photos placed via a native
   wp:image block instead of a plain <img> or link — wp:image always wraps
   its <img> in a <figure class="wp-block-image">. That figure has no
   explicit height, and CSS percentage heights don't resolve through an
   auto-height parent, so the img's own width:100%/height:100% below
   silently no-ops and the photo falls back to its natural aspect ratio
   instead of filling the box (e.g. the homepage hero photo rendering at
   354px tall inside its 665px frame, with dark letterboxing top/bottom). */
.kw-ph.img > figure.wp-block-image {
	display: block;
	width: 100%;
	height: 100%;
	margin: 0;
}
.kw-ph.img img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
/* Product studio shots are white-background, landscape photos (roughly
   4:3) dropped into portrait/landscape frames of varying ratios — `cover`
   would crop off the nozzle or handle. `contain` shows the whole unit, and
   the white product-photo background blends into the frame's own white
   fill instead of leaving a visible letterbox. */
.kw-ph.img.kw-ph--contain {
	background: #fff;
}
.kw-ph.img.kw-ph--contain img {
	object-fit: contain;
}
.card:hover {
	transform: translateY(-3px);
	box-shadow: 0 16px 36px rgba(0,0,0,.07);
}
.card .tx { padding: 20px; margin: 0 !important; }
/* Core's <figure class="wp-block-post-featured-image"> ships its own
   margin-bottom (2em/32px) to space a featured image from following
   content — separate from and additional to this card's own
   `.tx{padding:20px}`, so it left a much taller gap under the photo than
   the doc's flat `.ph.img` + `.tx` markup ever had. */
.card .kw-ph.img { margin-bottom: 0; }
/* Scoped class instead of inline style="aspect-ratio:5/4;border-radius:0" on
   the wp:image block itself — same "invalid content" issue documented on
   .kw-beforeafter .kw-ph.img below (aspect-ratio has no block-supports JSON
   equivalent, so a hand-written style attribute always fails the editor's
   save-output diff even though it renders correctly). The doc's card photos
   are flush to the card's top corners (no radius) and a flatter 5:4 ratio
   than the default .kw-ph box. */
.card .kw-ph.img {
	aspect-ratio: 5/4;
	border-radius: 0;
}
.card h3 { font-size: 20px; margin: 8px 0 6px !important; line-height: 1.2; }
.card p { font-size: 13.5px; color: var(--global-palette5, #6f6c68); margin: 0 0 12px !important; }
.card a { color: var(--global-palette1, #e2001a); font-weight: 600; font-size: 14px; }
/* `wp:post-title{"isLink":true}` wraps the card title in its own <a>, which
   the rule above also catches — the doc only reds out the "Read →" link,
   not the title, so the title's real-DOM anchor needs its color reset. */
.card h3 a { color: inherit; }
/* Category label — same lighter-weight, tighter-tracked token as `.rel .c`
   on the article template's related-posts row (doc's `.hubcard .c`), used
   instead of the bolder/wider-tracked `.kicker` class. */
.card .c {
	font-size: 11px;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--global-palette1, #e2001a);
	margin-bottom: 6px !important;
	display: block;
}

@media (max-width: 860px) {
	.cards { grid-template-columns: 1fr !important; }
}

/* Swiss cross mark (logo + red divider band) */
.kw-mark {
	display: inline-flex;
	width: 32px;
	height: 32px;
	background: var(--global-palette1, #e2001a);
	position: relative;
	border-radius: 6px;
	flex: 0 0 auto;
}
.kw-mark::before,
.kw-mark::after {
	content: "";
	position: absolute;
	background: #fff;
}
.kw-mark::before {
	left: 50%;
	top: 7px;
	bottom: 7px;
	width: 5px;
	transform: translateX(-50%);
}
.kw-mark::after {
	top: 50%;
	left: 7px;
	right: 7px;
	height: 5px;
	transform: translateY(-50%);
}
.kw-mark.kw-mark--onred {
	background: #fff;
}
.kw-mark.kw-mark--onred::before,
.kw-mark.kw-mark--onred::after {
	background: var(--global-palette1, #e2001a);
}

/* Usage-context marquee strip — nested inside the same content container as
   the hero text/photo in Template B (not a viewport-edge full-bleed strip),
   so its border/content share the identical 1240px + 72px-gutter width. */
.kw-marquee {
	border-top: 1px solid var(--global-palette7, #e6e3df);
	border-bottom: 1px solid var(--global-palette7, #e6e3df);
	/* Template B's marquee lives inside the same padded .wrap as the hero
	   text/photo, so its border sits at that padded inner edge (1096px at
	   wide viewports), not the outer 1240px row edge. This box isn't nested
	   the same way, so the inset is reproduced by shrinking max-width by the
	   gutter on each side instead of adding it back as padding. */
	max-width: calc(1240px - 2 * clamp(22px, 5vw, 72px)) !important;
	margin-left: auto !important;
	margin-right: auto !important;
	margin-top: clamp(30px, 4vw, 50px) !important;
	padding: 20px 0;
	box-sizing: border-box;
}
.kw-marquee {
	display: flex !important;
	flex-direction: row !important;
	gap: 44px;
	flex-wrap: wrap;
	justify-content: center;
	font-family: var(--global-heading-font-family, 'Bricolage Grotesque');
	font-weight: 600;
	font-size: clamp(15px, 1.4vw, 18px);
	color: #bdbab6;
}
.kw-marquee p {
	margin: 0 !important;
}
.kw-marquee .kw-on {
	color: var(--global-palette3, #121212);
}

/* Stat row (red panel: 1946 / CH-DE / 100%) */
.kw-stats {
	display: flex !important;
	flex-direction: row !important;
	gap: 34px;
	flex-wrap: wrap;
	margin-top: 22px;
}
.kw-stats .kw-stat .kw-n {
	font-family: var(--global-heading-font-family, 'Bricolage Grotesque');
	font-weight: 800;
	font-size: 40px;
	line-height: 1;
	color: #fff;
}
.kw-stats .kw-stat .kw-n,
.kw-stats .kw-stat .kw-c {
	margin: 0 !important;
}
.kw-stats .kw-stat .kw-c {
	font-size: 12.5px;
	color: #ffd6da;
	margin-top: 5px !important;
	max-width: 16ch;
}

/* Chips (standards badges) */
.kw-chips {
	display: flex !important;
	flex-direction: row !important;
	gap: 9px;
	flex-wrap: wrap;
}
.kw-chip {
	display: inline-block;
	border: 1px solid var(--global-palette7, #e6e3df);
	color: var(--global-palette5, #6f6c68);
	font-size: 12px;
	font-weight: 500;
	padding: 8px 13px;
	border-radius: 100px;
	margin: 0 !important;
}
.kw-chip--dark {
	border-color: #333;
	color: #cbc9c5;
}

/* Benefits list (red-dot bullet, baseline two-column grid) — ported from the
   doc's `.bens`/`.bens li::before`; content previously carried only the
   per-item padding/border-bottom/font-size as inline styles with no bullet
   marker or grid layout at all. */
.kw-bens {
	list-style: none;
	padding: 0;
	margin-top: 10px;
	max-width: 760px;
}
.kw-bens li {
	display: grid;
	grid-template-columns: auto 1fr;
	gap: 12px;
	align-items: baseline;
	padding: 14px 0;
	border-bottom: 1px solid var(--global-palette7, #e6e3df);
	font-size: 15px;
}
.kw-bens li::before {
	content: "";
	width: 9px;
	height: 9px;
	border-radius: 50%;
	background: var(--global-palette1, #e2001a);
	transform: translateY(4px);
}

/* Food-safety migration readout table */
.kw-readout {
	border: 1px solid var(--global-palette3, #121212);
	border-radius: 14px;
	overflow: hidden;
	background: #fff;
}
.kw-readout .kw-readout-head {
	display: flex;
	justify-content: space-between;
	padding: 14px 18px;
	border-bottom: 1px solid var(--global-palette3, #121212);
	font-size: 12px;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--global-palette5, #6f6c68);
}
.kw-readout-row {
	display: grid !important;
	grid-template-columns: 1.4fr 1fr 1fr .8fr !important;
	gap: 8px;
	padding: 13px 18px;
	border-bottom: 1px solid var(--global-palette7, #e6e3df);
	font-size: 14px;
	align-items: center;
}
.kw-readout-row:last-child {
	border-bottom: 0;
}
.kw-readout-row .kw-s { font-weight: 600; }
.kw-readout-row .kw-l { color: var(--global-palette5, #6f6c68); }
.kw-readout-row .kw-pass { color: #0a7d34; font-weight: 600; font-size: 12px; }
.kw-readout-dark .kw-readout-row .kw-pass { color: #39d98a; }
.kw-readout-dark { background: #191919; border: 1px solid #2a2a2a; border-radius: 16px; padding: 28px; }
.kw-readout-dark .kw-readout-row { border-bottom-color: #262626; }
.kw-readout-dark .kw-s { color: #fff; }
.kw-readout-dark .kw-l { color: #8f8d8a; }
/* The homepage's dark readout only has 3 items per row (label, limit, value),
   unlike the food-safety page's 4-item rows (label, value, limit, "Pass"), so
   it can't share the 4-column grid — that left the value column stranded in
   the middle with dead space at the card's right edge. Give it its own fixed
   3-column grid so the limit-text column lines up down the table instead of
   drifting with each row's label width.
   This row is a native Gutenberg Group block ("Food Safety Readout" reusable
   block, post 93) with layout:flow, which wraps its 3 paragraph children in
   an extra .wp-block-group__inner-container div — so the grid has to target
   that wrapper (the row's actual direct child), not .kw-readout-row itself,
   or it only ever sees one grid item and the 3 paragraphs stack as plain
   block-level text instead of forming columns. The base (unscoped)
   .kw-readout-row rule below still makes the OUTER row itself a 4-column
   grid too (sized for the food-safety page's light rows) — with only one
   child now, that squeezed the inner-container into a single ~140px column
   instead of the row's full width. Collapse the outer grid to one full-width
   column so the inner grid actually gets the row's whole width to lay out
   the 3 real columns in. */
.kw-readout-dark .kw-readout-row {
	grid-template-columns: 1fr !important;
	padding: 12px 0 !important;
	margin: 0 !important;
}
.kw-readout-dark .kw-readout-row > .wp-block-group__inner-container {
	display: grid !important;
	grid-template-columns: 1.6fr 1.3fr 70px !important;
	align-items: center;
}
/* Kadence's default block spacing gives every wp:paragraph a 32px
   margin-bottom — fine for normal body copy, but these are single-line
   label/limit/value cells meant to sit flush in one row, not stacked
   paragraphs. That stray margin was inflating the grid row's height, which
   then stretched the value cell (0 margin) to match via the grid's default
   align-items:stretch, ballooning the whole card well past the doc's
   compact ~47px row height. */
.kw-readout-dark .kw-readout-row p {
	margin: 0 !important;
}
/* Doc centers this row (align-items:center) so the shorter card settles in
   the middle of the taller text column instead of being stretched to match
   its full height — Kadence's row defaults to stretch, forcing both columns
   to the same height and pinning the card's top to the kicker instead of
   letting it float centered like the reference. */
.kb-row-layout-idhpsafe > .kt-row-column-wrap {
	align-items: center !important;
}
.kw-readout-dark .kw-readout-row .kw-pass {
	text-align: right;
}

@media (max-width: 860px) {
	.kw-readout-row { grid-template-columns: 1.4fr 1fr .8fr; }
	.kw-readout-row .kw-l { display: none; }
}

/* Contact page: the hero H1 and the two enquiry forms are built as two
   separate Kadence rows, so the sitewide row-to-row rhythm padding
   (~70-100px each) stacked on both sides of that boundary, opening a ~212px
   gap where the doc has all of it in one section with just a 26px
   margin-top on the forms grid — collapsed against the H1's own 16px
   margin-bottom to a net 26px gap (adjacent-sibling margins collapse to the
   larger value, not the sum). Row boundaries don't collapse margins across
   them, so this row's padding-top has to make up the remainder itself:
   26px target minus the H1's 16px margin-bottom that still applies = 10px. */
.kb-row-layout-idcontact-hero > .kt-row-column-wrap {
	padding-bottom: 0 !important;
}
.kb-row-layout-idcontact-forms > .kt-row-column-wrap {
	padding-top: 10px !important;
}

/* Company timeline */
.kw-timeline {
	border-left: 2px solid var(--global-palette7, #e6e3df);
	margin-top: 26px;
	padding-left: 26px;
}
.kw-timeline .kw-tl {
	margin-bottom: 26px;
	position: relative;
}
.kw-timeline .kw-tl::before {
	content: "";
	position: absolute;
	left: -33px;
	top: 5px;
	width: 12px;
	height: 12px;
	border-radius: 50%;
	background: var(--global-palette1, #e2001a);
}
.kw-timeline .kw-yr {
	font-family: var(--global-heading-font-family, 'Bricolage Grotesque');
	font-weight: 800;
	font-size: 20px;
}
.kw-timeline p {
	font-size: 15px;
	color: var(--global-palette5, #6f6c68);
	margin-top: 4px;
	max-width: 60ch;
}

/* Product spec grid */
.kw-specs {
	display: grid !important;
	grid-template-columns: repeat(2, 1fr) !important;
	gap: 1px;
	background: var(--global-palette7, #e6e3df);
	border: 1px solid var(--global-palette7, #e6e3df);
	border-radius: 14px;
	overflow: hidden;
	margin-top: 22px;
}
/* The base rule's own !important beats a plain inline grid-template-columns
   override, so a page needing 3 even columns (Materials Library's 9 tiles —
   2 columns left an orphaned tile and an empty cell in the last row) needs
   its own !important modifier class instead of an inline style. */
.kw-specs.kw-specs--3col {
	grid-template-columns: repeat(3, 1fr) !important;
}
.kw-specs.kw-specs--5col {
	grid-template-columns: repeat(5, 1fr) !important;
}
@media (max-width: 860px) {
	.kw-specs.kw-specs--3col,
	.kw-specs.kw-specs--5col { grid-template-columns: 1fr !important; }
}
@media (max-width: 1080px) {
	.kw-specs.kw-specs--5col { grid-template-columns: repeat(2, 1fr) !important; }
}
/* Group block's default width on the cell wrapper stops it stretching to
   fill its grid cell (falls back to content width), leaving the parent's
   gap-line background visible as dead space — force the stretch explicitly. */
.kw-specs .kw-s {
	width: 100% !important;
	box-sizing: border-box !important;
	background: #fff;
	padding: 16px 18px;
	/* Kadence's default Group-block spacing (32px margin-bottom) was showing
	   through as a thick grey band between grid rows — the outer .kw-specs
	   background color filling the gap left by the stray margin instead of
	   the intended 1px grid line. Same recurring pattern as .kw-facts .kw-f
	   and .card below; this one was missed when the spec-grid pattern was
	   first converted to native blocks. */
	margin: 0 !important;
}
.kw-specs .kw-s .kw-k {
	font-size: 11px;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--global-palette5, #6f6c68);
	margin: 0 !important;
}
.kw-specs .kw-s .kw-v {
	font-family: var(--global-heading-font-family, 'Bricolage Grotesque');
	font-weight: 700;
	font-size: 19px;
	margin: 4px 0 0 !important;
}

/* Facts grid (case studies). Like .kw-readout-dark, .kw-facts is a native
   Gutenberg Group block (layout:flow) that wraps its 4 .kw-f children in an
   extra .wp-block-group__inner-container div — the grid has to target that
   wrapper's children, not .kw-facts itself, or it only ever sees one grid
   item (the wrapper) and the 4 boxes stack in a single column with a huge
   empty gap where the second column should be. */
.kw-facts {
	background: var(--global-palette7, #e6e3df);
	border: 1px solid var(--global-palette7, #e6e3df);
	border-radius: 14px;
	overflow: hidden;
	/* !important needed on both: margin-top was losing to the pagehero H1's
	   own 16px margin-bottom !important rule (collapsed to 16, not 26), and
	   margin-bottom was losing to Kadence's stray default Group-block 32px
	   spacing — same pattern found repeatedly elsewhere in this component. */
	margin-top: 26px !important;
	margin-bottom: 26px !important;
}
.kw-facts > .wp-block-group__inner-container {
	display: grid !important;
	grid-template-columns: repeat(2, 1fr) !important;
	gap: 1px;
}
.kw-facts .kw-f {
	width: 100% !important;
	box-sizing: border-box !important;
	background: #fff;
	padding: 22px;
	/* Kadence's default Group-block spacing (32px margin-bottom) was adding
	   ~33px between rows instead of the grid's own 1px gap, while the
	   column gap (no such margin involved) was correctly 1px. */
	margin: 0 !important;
}
.kw-facts .kw-f h4 {
	font-size: 12px;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--global-palette1, #e2001a);
	margin-bottom: 8px;
}
.kw-facts .kw-f p {
	font-size: 14.5px;
	color: var(--global-palette5, #6f6c68);
}

@media (max-width: 860px) {
	.kw-specs, .kw-facts { grid-template-columns: 1fr !important; }
}

/* Line-wrap width utilities — native heading/paragraph blocks have no JSON
   attribute for max-width, so a hand-written inline style reads as invalid
   content once the block has any style supports registered (border, color,
   spacing all count). A small set of ch-based utility classes covers every
   value actually used sitewide without repeating this per instance. */
.kw-maxch-20 {
	max-width: 20ch;
}
.kw-maxch-16 {
	max-width: 16ch;
}
.kw-maxch-14 {
	max-width: 14ch;
}
/* Aspect-ratio utility for wp:image placeholder/photo boxes — same
   inline-style-can't-round-trip reasoning as the other aspect-ratio
   comments in this file (see .kw-beforeafter). 4:3 is the most common
   ratio for card/photo slots sitewide outside the 4:5 product-photo and
   16:8/16:9 article-hero cases already covered by their own classes. */
.kw-ratio-43 {
	aspect-ratio: 4/3;
}
.kw-ratio-43-r12 {
	aspect-ratio: 4/3;
	border-radius: 12px;
}
.kw-ratio-11 {
	aspect-ratio: 1/1;
}
.kw-ratio-169-r12 {
	aspect-ratio: 16/9;
	border-radius: 12px;
}
.kw-ratio-45-r12 {
	aspect-ratio: 4/5;
	border-radius: 12px;
}
/* Our Story's paint-chapter and textile-chapter "before" photo pairs — a
   plain 2-column, 20px-gap grid, identical in both places. */
.kw-photo-pair {
	display: grid !important;
	grid-template-columns: 1fr 1fr !important;
	gap: 20px;
	margin-top: 8px;
}
/* Our Story's founder/early-years/today 3-photo row — a one-off asymmetric
   ratio (the founder portrait is narrower than the two landscape shots
   beside it), used nowhere else. !important needed on display/columns: this
   is a wp:group with layout type "flex" (chosen only to suppress the
   wrapper div — see the .kw-beforeafter/.kw-facts comments above), and
   without !important here Gutenberg's own .is-layout-flex{display:flex}
   rule wins the cascade, stacking every image full-width instead of the
   intended 3-column asymmetric row. */
.kw-story-founders {
	display: grid !important;
	grid-template-columns: 0.8fr 1.6fr 1.6fr !important;
	gap: 14px;
	align-items: start;
	margin: 16px 0 4px;
}
.kw-ratio-34-r10 {
	aspect-ratio: 3/4;
	border-radius: 10px;
}
.kw-ratio-32-r10 {
	aspect-ratio: 3/2;
	border-radius: 10px;
}
.kw-story-founders figcaption {
	font-size: 12px;
	color: var(--global-palette5, #6f6c68);
	margin-top: 6px;
}
/* Knowledge-article pull quote — was inline style on the blockquote itself;
   wp:quote has border/color style supports registered, so a hand-written
   style attribute would read as invalid content the same way it did for
   wp:image (see the .kw-beforeafter comment above for the full mechanism). */
.kw-pullquote {
	border-left: 3px solid var(--global-palette1, #e2001a);
	border-top: 0;
	border-right: 0;
	border-bottom: 0;
	padding: 6px 0 6px 20px;
	margin: 24px 0;
}
.kw-pullquote p {
	font-family: var(--global-heading-font-family, 'Bricolage Grotesque');
	font-weight: 500;
	font-size: 22px;
	line-height: 1.3;
}
/* Knowledge-article byline ("Technique · Spraying" above the H1, "Comparison
   · Spraying" above an FAQ item, etc.) — muted, distinct from the red
   .kicker eyebrow used everywhere else. Was inline style per instance. */
.kw-byline {
	font-size: 12px;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--global-palette5, #6f6c68);
	margin-bottom: 12px;
}
/* Knowledge-article hero photo — aspect-ratio again has no block-supports
   JSON equivalent (see .kw-beforeafter comment above), so it can't be
   inline style on the wp:image block. Two ratios used across the Knowledge
   section's articles. */
.kw-article-photo-168 {
	aspect-ratio: 16/8;
	border-radius: 16px;
}
.kw-article-photo-169 {
	aspect-ratio: 16/9;
	border-radius: 16px;
}
/* In-article inline photo with a caption (not a .kw-ph placeholder box —
   a real full-width illustrative photo). Border-radius as a scoped class
   rather than the wp:image block's own "style":{"border":{"radius"}} JSON
   attribute, since that combination didn't reliably round-trip through the
   editor's validator when the block also had a caption; not worth
   debugging further when the class-based approach is already proven safe
   everywhere else in this conversion. */
.kw-article-inline-photo img {
	border-radius: 12px;
}
/* OEM hub dark hero box — bg/radius/padding were inline style on a plain
   div; kicker/h1/paragraph text colors were per-instance overrides of the
   shared .kicker/heading defaults, now scoped here instead so those classes
   stay reusable unmodified elsewhere. */
/* Contact page's two form boxes — same reasoning as every other scoped
   class in this file: wp:group's border supports (width/color/radius
   together) didn't reliably round-trip through the editor's validator by
   hand, so the box chrome moves to a plain class instead of JSON style. */
.kw-contact-form-box {
	background: #fff;
	border: 1px solid var(--global-palette7, #e6e3df);
	border-radius: 16px;
	padding: 26px;
}
/* kw_oem_brand singular pages (Template 18) inherit the site's global
   Kadence "Content Style: Boxed" default — a white card with padding,
   border-radius and shadow behind the whole entry — which reads oddly here
   specifically because this template's own content starts immediately with
   a dark hero box on the page's cream background, not body copy that needs
   a paper-white reading surface. The doc's own Template 18 markup is just a
   plain section on the page background, no card. Scoped to this post type
   only via the body class Kadence already adds, so no other page's boxed
   style (which works fine elsewhere) is touched. */
body.single-kw_oem_brand {
	background: #fff;
}
body.single-kw_oem_brand .content-bg {
	background: none;
	padding: 0;
	border-radius: 0;
	box-shadow: none;
}
/* Same reasoning as .content-bg above, one layer out: Kadence's "Content
   Vertical Padding" feature (body class content-vertical-padding-show)
   stacks 80px margin-top on .content-area + 32px padding-top on
   .entry-content-wrap + 32px margin-top on .entry-content = 144px between
   the breadcrumb and this template's own hero box. That generous top
   padding exists to give a boxed white card room to breathe above the fold
   — with the card removed, it's just a big unexplained gap. Doc's own
   .crumb{margin-bottom:16px} is the only spacing wanted here. */
body.single-kw_oem_brand .content-area {
	margin-top: 0;
}
body.single-kw_oem_brand .entry-content-wrap {
	padding-top: 0;
}
body.single-kw_oem_brand .entry-content {
	margin-top: 0;
}
.kw-oem-hero {
	background: #121212;
	border-radius: 18px;
	padding: clamp(30px, 4vw, 52px);
}
.kw-oem-hero .kicker {
	color: #fff;
}
.kw-oem-hero h1 {
	font-weight: 700;
	color: #fff;
	font-size: clamp(28px, 3.6vw, 46px);
	margin: 12px 0 14px;
	max-width: 18ch;
}
.kw-oem-hero p {
	color: #b6b3af;
	max-width: 52ch;
}
/* OEM brand page's "The relationship" row (kreaswiss_render_oem_brand_content
   in functions.php) — PHP-generated with a raw inline
   display:grid;grid-template-columns:1fr 1fr style, unlike every other
   two-column layout on the site (which goes through Kadence's row/column
   blocks and gets responsive stacking for free). With no breakpoint, the
   two columns stayed forced side by side on tablet/mobile — cramped and
   wrapping badly at ~860px, and actually overflowing the viewport
   horizontally at phone widths. Moved the layout into this class (out of
   the inline style) so it can respond like every other row on the page. */
.kw-oem-relationship-grid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	/* Doc's .two uses gap:clamp(26px,4vw,54px) — resolves to 54px at desktop
	   widths, not the 24px this was originally hand-set to. */
	gap: clamp(26px, 4vw, 54px);
	/* Template 18's own markup uses the doc's base .two{align-items:center} —
	   unlike the product hero (Template 02), which explicitly overrides it to
	   "start" with an inline style. No such override here, so this row's text
	   and photo should be vertically centered against each other, not
	   top-aligned. */
	align-items: center;
}
@media (max-width: 860px) {
	.kw-oem-relationship-grid {
		grid-template-columns: 1fr;
	}
}
/* "A short timeline" label, Template 18 — same body-h3-!important-wins
   gotcha documented above (.kw-h3-label etc.): the inline
   margin:30px 0 8px this used to carry was silently zeroed out regardless,
   so the label sat flush against the timeline grid below it with no gap.
   Class-scoped override, matching the established pattern. */
.kw-oem-timeline-h3 {
	margin: 34px 0 6px !important;
}
/* Kadence's own theme CSS has `.single-content h3 + * { margin-top: 0 }`
   (kills the top margin on whatever immediately follows any heading), which
   outranks .kw-specs's own margin-top:22px on plain specificity — no
   !important on either side, this is a straight specificity fight. Two
   classes beats one class + one element, so this wins without needing
   !important at all. */
.kw-oem-timeline-h3 + .kw-specs {
	margin-top: 22px;
}
/* Shared "sub-heading right under a kicker" H2 (font-size:26px, spec margin
   10px 0) — used both in Template 18's PHP-generated "How it started..."
   heading and Template 10's (OEM hub) "Sell KREA Swiss under your own
   name." heading. Same sitewide body-h2{margin:0 !important} gotcha as the
   h3 case above: the inline/JSON margin never actually applied. */
.kw-h2-sub {
	margin: 10px 0 !important;
}
/* OEM hub's hero row — its own unfixed 100px bottom padding was invisible
   in a row-boundary-to-boundary gap check (rows always sit flush, so that
   padding is baked inside the row's own box), but very visible to an actual
   viewer: 138px of empty space between the black hero box and "Become a
   reseller" below it, on top of that section's own 34px top padding.
   Zeroed here; the reseller row's own top padding is the only spacing this
   boundary needs. */
.kb-row-layout-idoem-hero .kt-row-column-wrap {
	padding-bottom: 0 !important;
}
/* OEM hub's "Become a reseller" row (Template 10's .two, spec
   margin-top:34px) — same unfixed Kadence default row padding (100px) as
   everywhere else in this file, giving a 104px gap instead of the doc's
   34px. Trimmed to match. Bottom also needs trimming (see the whole-page
   comment below) — its unfixed 100px stacks with oem-origins' own 100px
   top padding into a 204px gap before "Origin pages, sold today under
   other brands" heading was even visible. */
.kb-row-layout-idoem-reseller .kt-row-column-wrap {
	padding-top: 34px !important;
	padding-bottom: 0 !important;
	/* This row's photo should sit centered against the text column (spec's
	   .two{align-items:center} base, no override for this instance — unlike
	   the product hero, Template 02, which explicitly overrides to "start").
	   Kadence tags the row "kt-row-valign-top", which the earlier sitewide
	   .kt-row-valign-top{align-items:start} rule (correct for Template 02)
	   also matches here — wrong context. Two classes outranks one, so this
	   wins without needing !important. */
	align-items: center;
}
/* Rest of the OEM hub page (Template 10) — oem-origins (cards), oem-marquee,
   oem-history and oem-cta all carry the same unfixed Kadence default row
   padding (100px top+bottom) documented throughout this file. Unlike the
   product-hero panels on the homepage (which read fine at 100px as
   deliberately generous full-bleed colour blocks), here the paddings stack
   at every boundary — cards-to-marquee-heading alone was 293px. Each
   boundary gets one side trimmed to 0 and the other set to a real value, so
   the gap is deliberate on one side only, not compounded from both. */
.kb-row-layout-idoem-origins .kt-row-column-wrap {
	padding-top: 56px !important;
	padding-bottom: 48px !important;
}
.kb-row-layout-idoem-marquee .kt-row-column-wrap {
	padding-top: 0 !important;
	padding-bottom: 0 !important;
}
.kb-row-layout-idoem-history .kt-row-column-wrap {
	padding-top: 48px !important;
	padding-bottom: 0 !important;
}
.kb-row-layout-idoem-cta .kt-row-column-wrap {
	padding-top: 20px !important;
	padding-bottom: 0 !important;
}
/* Chocolate and Tempering hub's "Development partner: Barry Callebaut's..."
   one-line callout — same unfixed Kadence default row padding (100px
   top+bottom) as everywhere else in this file, which for a single line of
   text produced a huge, near-empty box. Bottom trimmed to 0 since the next
   row (chocbuyrow, a .buyrowouter) already provides its own 40px top
   spacing; a value here too would just double up. */
.kb-row-layout-idchoc-partner .kt-row-column-wrap {
	padding-top: 32px !important;
	padding-bottom: 0 !important;
}
/* OEM hub's brand marquee runs full row width, unlike the homepage's inset
   version — was an inline !important style override on .kw-marquee itself;
   scoped to this row's own Kadence-generated unique-ID class instead,
   matching the .kb-row-layout-id* scoping convention already used
   elsewhere in this file (e.g. .kb-row-layout-idhpmake). */
.kb-row-layout-idoem-marquee .kw-marquee {
	max-width: none !important;
	margin-left: 0 !important;
	margin-right: 0 !important;
}
.kb-row-layout-idwhere-hero .kw-marquee {
	max-width: none !important;
	margin-left: 0 !important;
	margin-right: 0 !important;
	margin-top: 24px !important;
}
/* Where We Are Used's two lead photos (wide bakery shot + narrower tent
   shot) — a one-off asymmetric ratio, used nowhere else. */
.kw-where-photos {
	display: grid !important;
	grid-template-columns: 2fr 1fr !important;
	gap: 14px;
}

/* Aspect-ratio / margin utilities — same rationale as kw-maxch above: the
   wp:image block's border support is registered with
   __experimentalSkipSerialization, and aspect-ratio has no block-supports
   equivalent at all, so neither can be trusted to round-trip through a
   hand-written inline style without the editor flagging "invalid content".
   Used on Knowledge-article/hub photos converted from raw wp:html <img>
   markup this session, in place of the original inline aspect-ratio/margin. */
.kw-ar-16-10 {
	aspect-ratio: 16/10;
}
.kw-ar-16-9 {
	aspect-ratio: 16/9;
}
.kw-ar-16-8 {
	aspect-ratio: 16/8;
}
.kw-mt-24 {
	margin-top: 24px;
}
.kw-mb-24 {
	margin-bottom: 24px;
}
.kw-mb-30 {
	margin-bottom: 30px;
}

/* Knowledge hub card thumbnails: flush top corners (the .card wrapper
   itself carries border-radius:16px + overflow:hidden, so the image only
   needs to be square-cornered, not rounded) and a flatter 16:10 ratio
   instead of kw-ph's default centered-label min-height box. */
.cards .kw-ph.img {
	aspect-ratio: 16/10;
	border-radius: 0;
	min-height: 0;
}

/* Homepage hero photo placeholder (Template 00) */
.kw-hero-photo {
	aspect-ratio: 4/5;
	border-radius: 20px;
	position: relative;
}
.kw-hero-photo .kw-mark {
	position: absolute;
	right: 18px;
	top: 18px;
}
.kw-hero-badge {
	position: absolute;
	left: 18px;
	bottom: 18px;
	background: var(--global-palette1, #e2001a);
	color: #fff;
	font-weight: 600;
	font-size: 12.5px;
	padding: 8px 15px;
	border-radius: 100px;
	font-family: 'Inter', sans-serif;
	text-transform: none;
	letter-spacing: 0;
	margin: 0 !important;
}

/* Homepage proof section big figure (Template 00) */
.kw-proof-big {
	font-family: var(--global-heading-font-family, 'Bricolage Grotesque');
	font-weight: 800;
	font-size: clamp(54px, 9vw, 120px);
	line-height: .9;
	color: var(--global-palette1, #e2001a);
	letter-spacing: -.03em;
	margin: 0 !important;
}
.kw-proof-cap {
	font-family: 'Inter', sans-serif;
	font-weight: 500;
	font-size: 17px;
	color: var(--global-palette3, #121212);
	margin-top: 12px !important;
}

/* Placeholder photo blocks (no real photography yet) */
.kw-ph {
	background: linear-gradient(150deg, #232323, #000);
	color: #6a6a6a;
	font-size: 12px;
	letter-spacing: .12em;
	text-transform: uppercase;
	display: flex;
	align-items: center;
	justify-content: center;
	text-align: center;
	border-radius: 16px;
	min-height: 220px;
	padding: 20px;
}

/* Footer background + widget list resets (Kadence's background control + wp_kses
   strip the inline list-style/background we'd otherwise set directly). */
#colophon.site-footer {
	background: #000;
}
#colophon.site-footer .site-footer-wrap {
	padding-top: clamp(50px, 6vw, 80px) !important;
	padding-bottom: 30px !important;
}
/* Copyright row (`.fbase{border-top:1px solid #222;padding-top:22px}` in
   Template B) separates itself from the column grid above with a hairline. */
/* Column grid: Template B gives the brand column 1.5x the width of the two
   link columns (`.fgrid{grid-template-columns:1.5fr 1fr 1fr}`), not equal
   thirds, and a 34px gap rather than Kadence's default 30px. Scoped to
   tablet+ widths only — Kadence collapses this row to a single column below
   768px (.site-footer-row-mobile-column-layout-row), and an unscoped
   !important here was overriding that and forcing three cramped columns
   with clipped text on mobile instead of letting it stack. */
@media (min-width: 768px) {
.site-middle-footer-inner-wrap {
	grid-template-columns: 1.5fr 1fr 1fr !important;
	column-gap: 34px !important;
}
}
.site-middle-footer-inner-wrap {
	/* Kadence's own row template gives this a default 30px top/bottom padding
	   that Template B's .fgrid doesn't have — it only carries a margin-bottom,
	   supplied by the copyright row's own margin-top below. */
	padding-top: 0 !important;
	padding-bottom: 0 !important;
}
#colophon.site-footer .site-bottom-footer-wrap {
	margin-top: 40px;
}
/* Same Kadence default-row-padding issue as the grid above, on the nested
   wrapper that actually carries it for the bottom (copyright) row. The
   border itself belongs here, not on the full-viewport-width wrap above —
   Template B's `.fbase{border-top:1px solid #222}` only spans the same
   1100px content width as the column grid, not the full black footer band. */
.site-bottom-footer-inner-wrap {
	border-top: 1px solid #222;
	padding-top: 22px !important;
	padding-bottom: 0 !important;
}
#colophon.site-footer .footer-html {
	margin: 0 !important;
}
#colophon.site-footer ul {
	list-style: none;
}
#colophon.site-footer a:hover {
	color: #fff;
}
#colophon.site-footer h4 {
	font-family: 'Inter', sans-serif;
	font-size: 11px;
}

/* Primary nav — Kadence's own default nav link color/size/weight doesn't pick
   up the theme palette (falls back to a muted gray at 17px/400), so pin the
   exact values from kreaswiss-web-designer-document.html's shared header
   (`nav a{font-size:14px;font-weight:500}`) directly. Bumped to 15px per
   client feedback (the doc's 14px read too small in practice). */
.main-navigation ul.menu > li > a {
	color: #121212 !important;
	font-size: 15px !important;
	font-weight: 500 !important;
	transition: color .2s;
}
.main-navigation ul.menu > li > a:hover {
	color: #e2001a !important;
}
/* Current-page indicator — WordPress's nav walker already adds
   current-menu-item/current-menu-ancestor (and the current_page_* aliases)
   to the relevant <li>, but nothing here was styling them, so the active
   page never looked different from any other nav item except on hover. */
.main-navigation ul.menu > li.current-menu-item > a,
.main-navigation ul.menu > li.current-menu-ancestor > a,
.main-navigation ul.menu > li.current_page_item > a,
.main-navigation ul.menu > li.current_page_ancestor > a {
	color: #e2001a !important;
}

/* Header — sticky with a translucent blurred background and hairline border,
   70px tall (kreaswiss-web-designer-document.html's `.bar{height:70px}`);
   Kadence's header builder doesn't expose backdrop-filter or an exact height. */
.site-header {
	/* Kadence's own #masthead{position:relative} rule (header.min.css) outranks
	   a plain .site-header class selector on specificity alone. */
	position: sticky !important;
	top: 0;
	z-index: 40;
	background: rgba(255, 255, 255, .9) !important;
	backdrop-filter: blur(10px);
	-webkit-backdrop-filter: blur(10px);
	border-bottom: 1px solid #e6e3df;
}
.site-header .site-header-wrap {
	min-height: 70px !important;
}

/* Logo wordmark uses the display face at 800 weight, not the body font
   Kadence defaults new header-builder text elements to. Size matches the
   doc's `.logo b{font-size:20px}`. */
.site-header .site-title {
	font-family: 'Bricolage Grotesque', sans-serif !important;
	font-weight: 800 !important;
	font-size: 20px !important;
}
.site-header .site-header-item-logo,
.site-header .site-branding {
	gap: 12px;
}

/* Header "Shop at Kreativity.com" CTA — the doc's header markup uses the
   small button variant (`.btn.sm{font-size:13px;padding:10px 18px}`), not
   the standard pill size; Kadence's own "small" button size preset shrinks
   it much further (down to ~4px/9.5px), so pin the exact values directly. */
.site-header .header-button {
	padding: 10px 18px !important;
	font-size: 13px !important;
}

/* Kadence's own header .site-container uses a fixed 24px side padding while
   every content row uses the responsive clamp(22px,5vw,72px) gutter — at
   wide viewports that leaves the logo/nav sitting well inside where the
   hero text and every other section starts. Match them exactly. */
.site-header .site-container,
#colophon.site-footer .site-container {
	padding-left: clamp(22px, 5vw, 72px) !important;
	padding-right: clamp(22px, 5vw, 72px) !important;
}

/* Kadence Blocks' own advancedbtn stylesheet centers every button group by
   default (.kb-buttons-wrap{justify-content:center}); Template B always
   left-aligns CTA rows under left-aligned copy, sitewide. */
.kb-buttons-wrap {
	justify-content: flex-start !important;
}

/* Swiss red divider band — signature full-width section break/CTA (build sheet §3).
   Rebuilt on native blocks (Kadence Row/Column + core Group/Paragraph) so the
   message and button are directly editable; the row itself now supplies the
   red background, radius and column split (kadence/rowlayout bgColor +
   borderRadius), this file only needs the slim banner padding (the row's
   sitewide clamp(40-100px) default is far too tall for a 1-line CTA strip)
   and the message row's own flex/typography. */
.kb-row-layout-idkwdiv > .kt-row-column-wrap {
	padding-top: 22px !important;
	padding-bottom: 22px !important;
}
.kw-divider-msg {
	display: flex !important;
	flex-direction: row !important;
	align-items: center;
	gap: 16px !important;
}
.kw-divider-text {
	font-family: var(--global-heading-font-family, 'Bricolage Grotesque');
	font-weight: 700;
	font-size: clamp(17px, 2vw, 22px);
	color: #fff;
	margin: 0 !important;
}

/* Case study module — media column + content column (build sheet §5).
   .kw-case and .kw-case-media are both native Gutenberg Group blocks
   (layout:flow), which wrap their children in an extra
   .wp-block-group__inner-container div — same as .kw-facts and
   .kw-readout-dark above. Without retargeting the grid to that wrapper,
   each container only ever sees one grid item (the wrapper), so the second
   column/row collapses to empty space instead of holding real content. */
.kw-case {
	border: 1px solid var(--global-palette3, #121212);
	border-radius: 16px;
	overflow: hidden;
}
.kw-case > .wp-block-group__inner-container {
	display: grid !important;
	grid-template-columns: 1fr 1fr !important;
}
.kw-case .kw-case-media,
.kw-case .kw-case-body {
	width: 100% !important;
	box-sizing: border-box !important;
}
.kw-case .kw-case-media {
	background: #0d0d0d;
	min-height: 340px;
}
.kw-case .kw-case-media > .wp-block-group__inner-container {
	display: grid !important;
	grid-template-rows: 1.4fr 1fr !important;
	height: 100%;
}
.kw-case .kw-case-photo {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	color: #7a7a7a;
	font-size: 11px;
	letter-spacing: .12em;
	text-transform: uppercase;
	border-bottom: 1px solid #2a2a2a;
}
.kw-case .kw-case-vthumb {
	display: flex !important;
	flex-direction: row !important;
	align-items: center;
	justify-content: center;
	gap: 10px;
	color: #cfcdca;
	font-size: 11px;
	letter-spacing: .1em;
	text-transform: uppercase;
}
.kw-case .kw-case-vthumb .kw-case-play {
	width: 42px;
	height: 42px;
	border-radius: 50%;
	background: var(--global-palette1, #e2001a);
	display: flex;
	align-items: center;
	justify-content: center;
}
.kw-case .kw-case-play::before {
	content: "";
	border-left: 13px solid #fff;
	border-top: 8px solid transparent;
	border-bottom: 8px solid transparent;
	margin-left: 4px;
}
.kw-case .kw-case-body { padding: 30px; }
.kw-case .kw-case-tag {
	font-size: 11px;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--global-palette1, #e2001a);
}
/* !important needed on margin: the earlier sitewide `body h3{margin:0
   !important}` reset otherwise wins over this rule's own margin, even
   though this selector is more specific — an !important declaration always
   beats a non-!important one regardless of specificity. */
.kw-case h3.kw-case-title { font-size: 24px; margin: 10px 0 14px !important; }
/* Group block's flex layout support defaults to a column direction unless an
   explicit "orientation" is set on the block; pin it here so the block markup
   doesn't have to carry every WP-version-specific layout nuance. */
/* Grid instead of flex: each metric's wrapping Group block carries a default
   block-level width that fights flexbox's row layout (resolves as each
   item's flex-basis, forcing a stack); an auto-sized grid track isn't
   affected by a child's own width the same way, so it sits the two metrics
   side by side reliably. */
.kw-case .kw-case-metrics {
	display: grid !important;
	grid-auto-flow: column !important;
	grid-auto-columns: max-content !important;
	gap: 24px;
	/* Kadence's default Group-block spacing (32px margin-bottom) otherwise
	   wins over this margin, same !important-vs-specificity issue as the
	   title rule above. */
	margin: 16px 0 !important;
}
/* Same wp-block-group__inner-container issue as .kw-facts/.kw-case/
   .kw-case-media above, but only on SOME instances of this block — the two
   case studies were built with different Group-block layout types (flex on
   one, flow on the other), so only the "flow" one gets the extra wrapper.
   Repeating the grid rule on the wrapper (when present) covers both. */
.kw-case .kw-case-metrics > .wp-block-group__inner-container {
	display: grid !important;
	grid-auto-flow: column !important;
	grid-auto-columns: max-content !important;
	gap: 24px;
}
.kw-case .kw-case-metrics .kw-fig { font-family: var(--global-heading-font-family, 'Bricolage Grotesque'); font-weight: 800; font-size: 26px; margin: 0 !important; }
.kw-case .kw-case-metrics .kw-cap { font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--global-palette5, #6f6c68); margin: 0 !important; }
/* Each metric's own wrapping Group block also carries Kadence's default
   32px margin-bottom, inconsistently (only the first of the two actually
   showed it, likely a grid-stretch quirk) — zero it directly so both
   metrics align at the same top edge instead of one sitting 16px lower. */
.kw-case .kw-case-metrics > .wp-block-group {
	margin: 0 !important;
}
.kw-case blockquote.kw-case-quote { border-left: 3px solid var(--global-palette1, #e2001a); padding: 2px 0 2px 16px; font-family: var(--global-heading-font-family, 'Bricolage Grotesque'); font-weight: 500; font-size: 17px; line-height: 1.3; margin-top: 8px; }
.kw-case cite { display: block; font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--global-palette5, #6f6c68); font-style: normal; margin-top: 10px; }

@media (max-width: 860px) {
	.kw-case { grid-template-columns: 1fr !important; }
}

/* Engineering spec band — Part / KREA Swiss choice / paint gun contrast (build sheet §5) */
.kw-engspec { border: 1px solid var(--global-palette7, #e6e3df); border-radius: 14px; overflow: hidden; margin-top: 10px; }
.kw-engspec .kw-engspec-head,
.kw-engspec-row {
	display: grid !important;
	grid-template-columns: 1fr 1.3fr 1.3fr !important;
	gap: 1px;
	background: var(--global-palette7, #e6e3df);
}
.kw-engspec .kw-engspec-head > div,
.kw-engspec-row > div {
	width: 100% !important;
	box-sizing: border-box !important;
	background: #fff;
	padding: 14px 18px;
}
.kw-engspec .kw-engspec-head > div {
	font-size: 11px;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--global-palette5, #6f6c68);
	background: var(--global-palette8, #faf8f5);
}
.kw-engspec-row .kw-part { font-weight: 600; }
.kw-engspec-row .kw-paint { color: var(--global-palette5, #6f6c68); font-size: 14px; }
.kw-engspec-row .kw-krea { font-size: 14px; }
.kw-engspec-row .kw-krea::before { content: "✓ "; color: #0a7d34; font-weight: 700; }

@media (max-width: 860px) {
	.kw-engspec .kw-engspec-head, .kw-engspec-row { grid-template-columns: 1fr !important; }
	.kw-engspec .kw-engspec-head > div:not(:first-child) { display: none; }
}

/* Related articles teaser (Template 04, bottom of every Knowledge article) */
.related {
	display: grid !important;
	grid-template-columns: repeat(3, 1fr) !important;
	gap: 18px;
	margin-top: 14px;
	margin-bottom: 60px;
}
/* The "Related" label above is a plain .kicker paragraph, but Kadence's own
   `.single-post .single-content p{color:...}` rule (2 classes + 1 element)
   outranks the base `.kicker{color:red}` (1 class) on pure specificity —
   no !important on either side, so this needed a selector with more classes
   to win outright rather than fighting it with !important. Scoped via
   :has() to the specific group wrapping this one kicker (the one
   immediately before a .related block), so no other kicker sitewide is
   touched. */
.wp-block-group:has(+ .wp-block-query.related) .kicker {
	color: var(--global-palette1, #e2001a);
	/* Same specificity fight as color above, but this time against another
	   !important rule (Kadence's `.single-post .single-content p{margin-
	   bottom:18px !important}`) — needs both enough specificity AND
	   !important to win, not just one or the other. */
	margin-bottom: 8px !important;
}
/* Same wrapping group also carries the stray default 32px margin-bottom
   documented throughout this file — .related's own margin-top:14px should
   be the only spacing between "Related" and the cards below, but this
   group's 32px was adding well beyond that. margin-bottom only — the
   group's own inline margin-top:20px (matching the doc's spec) needs to
   stay untouched. */
.wp-block-group:has(+ .wp-block-query.related) {
	margin-bottom: 0 !important;
}
/* When `.related` wraps a Query Loop instead of hand-written `.rel` divs,
   the grid has to move down to the loop's own <ul class="wp-block-post-
   template"> — same invisible-wrapper issue as the Case Studies hub (see
   the `.cards .wp-block-post-template` rule and the memory doc's Kadence
   gotchas #1/#6). The comment above described this, but the outer
   .related{display:grid;grid-template-columns:repeat(3,1fr)} rule was never
   actually turned off for this case — with the query loop's <ul> as
   .related's ONLY child, that single grid item only ever occupies the
   first of .related's own 3 column tracks (~1/3 the real width), so
   width:100% below just resolves against that already-too-narrow track.
   Cancel the outer grid whenever a query loop is present; the inner rule
   below is the one actually doing the layout work in that case. */
.related:has(.wp-block-post-template) {
	display: block !important;
}
.related .wp-block-post-template {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	width: 100%;
	gap: 18px;
	list-style: none;
	margin: 0;
	padding: 0;
}
.related .wp-block-post-template > li {
	list-style: none;
}
.rel .wp-block-post-terms {
	font-size: 11px;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--global-palette1, #e2001a);
}
.rel .wp-block-post-terms a { color: inherit; }
.rel {
	border-top: 2px solid var(--global-palette3, #121212);
	padding-top: 12px;
}
.rel .c {
	font-size: 11px;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--global-palette1, #e2001a);
}
.rel h3 {
	font-size: 16px;
	font-weight: 700;
	margin: 8px 0 0 !important;
	line-height: 1.2;
}
.rel a { color: inherit; }
@media (max-width: 860px) {
	.related { grid-template-columns: 1fr !important; }
	.related .wp-block-post-template { grid-template-columns: 1fr; }
}

/* Pills (knowledge hub filters) */
.kw-pills { display: flex; gap: 10px; flex-wrap: wrap; }
.kw-pill {
	border: 1px solid var(--global-palette7, #e6e3df);
	border-radius: 100px;
	padding: 9px 16px;
	font-size: 13px;
	font-weight: 500;
	display: inline-block;
	background: transparent;
	color: inherit;
	font-family: inherit;
	cursor: pointer;
	transition: .15s;
}
/* Hover matches the Secondary/outline button's own hover treatment
   (background fills to ink, text turns white) instead of just darkening
   the border, so every outline-style control inverts the same way. */
.kw-pill:hover {
	background: var(--global-palette3, #121212);
	color: #fff;
	border-color: var(--global-palette3, #121212);
}
.kw-pill.kw-pill--on {
	background: var(--global-palette3, #121212);
	color: #fff;
	border-color: var(--global-palette3, #121212);
}
.kw-empty {
	margin-top: 30px;
	color: var(--global-palette5, #6f6c68);
	font-size: 14px;
}

/* Comparison table (brush vs aerosol vs sprayer, and future comparisons).
   Ported from the expansion doc's `.cmp`, kw-prefixed per this file's own
   convention for new multi-item/grid components. */
.kw-cmp {
	width: 100%;
	border-collapse: collapse;
	margin: 22px 0;
	border: 1px solid var(--global-palette7, #e6e3df);
	border-radius: 14px;
	overflow: hidden;
}
.kw-cmp th, .kw-cmp td {
	padding: 14px 16px;
	text-align: left;
	font-size: 15px;
	border-bottom: 1px solid var(--global-palette7, #e6e3df);
	vertical-align: top;
}
.kw-cmp thead th {
	font-family: 'Bricolage Grotesque', sans-serif;
	font-weight: 700;
	font-size: 14px;
	background: var(--global-palette8, #faf8f5);
}
.kw-cmp thead th:last-child {
	background: var(--global-palette1, #e2001a);
	color: #fff;
}
.kw-cmp td:first-child {
	font-weight: 600;
	width: 26%;
}
.kw-cmp tr:last-child td {
	border-bottom: 0;
}
/* Was .kw-cmp .win, a class on individual <td> cells — core Table block's
   cell schema only recognizes align/colspan/rowspan/scope/tag per cell, no
   generic className, so a hand-written class="win" isn't reconstructed by
   the block's save() and reads as invalid content. The highlighted cell is
   always the last (KREA Swiss) column, so a structural :last-child selector
   gets the identical result with no unsupported attribute needed. */
.kw-cmp td:last-child {
	color: #0a7d34;
	font-weight: 600;
}
@media (max-width: 860px) {
	.kw-cmp thead { display: none; }
	.kw-cmp td { display: block; border: 0; padding: 6px 16px; }
	.kw-cmp tr { display: block; border-bottom: 1px solid var(--global-palette7, #e6e3df); padding: 8px 0; }
	.kw-cmp td:first-child { width: auto; color: var(--global-palette1, #e2001a); text-transform: uppercase; font-size: 11px; letter-spacing: .08em; }
}

/* Gallery masonry grid (Template 14). Filter pills reuse the existing
   .kw-pills/.kw-pill component and its filtering script, same pattern as
   the Knowledge hub. */
.kw-gal {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 12px;
	margin-top: 26px;
}
.kw-gal .kw-g {
	aspect-ratio: 1/1;
	border-radius: 12px;
	background-size: cover;
	background-position: center;
	display: block;
}
/* The class selector above beats the UA stylesheet's `[hidden]{display:none}`
   on specificity, so the filter script's `.hidden = true` silently stopped
   hiding anything — every tile stayed visually in the grid regardless of
   which pill was active. Needs its own explicit override to win back. */
.kw-gal .kw-g[hidden] {
	display: none;
}
.kw-gal .kw-g.kw-g--tall {
	grid-row: span 2;
	aspect-ratio: 1/2;
}
.kw-gal .kw-g.kw-g--wide {
	grid-column: span 2;
	aspect-ratio: 2/1;
}
@media (max-width: 860px) {
	.kw-gal { grid-template-columns: repeat(2, 1fr); }
}

/* Proof components (Template 20) — reusable testimonial (face + quote) and
   before/after image pair, dropped into product, application and
   case-study pages in place of a bare "quote goes here" blockquote. */
.kw-testimonial {
	display: flex;
	align-items: center;
	gap: 20px;
	margin-top: 8px;
}
.kw-testimonial .kw-ph {
	width: 120px;
	height: 120px;
	min-height: 0;
	border-radius: 50%;
	flex: none;
	font-size: 10px;
}
.kw-testimonial blockquote {
	margin: 0 !important;
	flex: 1;
}
@media (max-width: 640px) {
	.kw-testimonial { flex-direction: column; align-items: flex-start; }
	.kw-testimonial .kw-ph { width: 72px; height: 72px; }
}
.kw-beforeafter {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 24px;
	margin-top: 20px;
}
/* Scoped class instead of inline style="aspect-ratio:...;border-radius:..."
   on the wp:image block itself — a native block with style "supports"
   (border, in this case) validates its saved HTML by recomputing the
   expected markup purely from its JSON attributes; a hand-written style
   attribute the parser can't attribute back to a known JSON key (aspect-
   ratio has no block-supports equivalent) always reads as "invalid
   content" in the editor, even with zero mismatched properties visually. */
.kw-beforeafter .kw-ph.img {
	aspect-ratio: 4/3;
	border-radius: 14px;
	min-height: 0;
}
@media (max-width: 640px) {
	.kw-beforeafter { grid-template-columns: 1fr; }
}
/* Product page hero photo (foodSPRAY Pro, volumeSPRAY, chocSPRAYER,
   chocMELTER) — same reasoning as .kw-beforeafter above: aspect-ratio has no
   block-supports JSON equivalent, so it can't be a hand-written inline style
   on the wp:image block without triggering "invalid content" in the editor.
   The design doc's own placeholder box used 4/5 (a tall portrait box, sized
   for a text caption, not a real photo). The actual product photos are all
   natural 1024x1024 squares, so 4/5 forced them into object-fit:contain
   letterboxing (~66px empty space above and below the photo inside its own
   frame) on top of stretching the hero row taller than the text column next
   to it. 1/1 matches the real photography with no letterboxing. */
.kw-product-photo.kw-ph.img {
	aspect-ratio: 1/1;
	border-radius: 16px;
	min-height: 0;
}

/* Primary nav dropdowns/flyouts — Kadence's own customizer output sets the
   sub-menu panel to a dark ink background with cream text (globals
   palette3/palette8/palette9/palette4), which doesn't match the approved
   header design (white panel, red top border, dark text, cream+red hover).
   Overriding the exact selectors the customizer itself generates so this
   wins on specificity without touching the customizer setting directly. */
.header-navigation .header-menu-container ul ul.sub-menu,
.header-navigation .header-menu-container ul ul.submenu {
	background: var(--global-palette9, #fff) !important;
	border-top: 2px solid var(--global-palette1, #e2001a);
	border-radius: 0 0 12px 12px;
	/* Without this, the last item's hover/current-page background is a
	   plain square-cornered rectangle that pokes out past the panel's own
	   rounded bottom corners — clip everything to the panel's shape so
	   hover states round off cleanly instead of overhanging the edge. */
	overflow: hidden;
}
.header-navigation .header-menu-container ul ul li.menu-item > a {
	color: var(--global-palette3, #121212) !important;
	border-bottom: 1px solid var(--global-palette7, #e6e3df) !important;
	/* Was inheriting Kadence's own default (12px) with nothing here pinning
	   it — bumped to 14px per client feedback, same reasoning as the 15px
	   top-level nav size above. */
	font-size: 14px !important;
}
.header-navigation .header-menu-container ul ul li.menu-item:last-child > a {
	border-bottom: 0 !important;
}
.header-navigation .header-menu-container ul ul li.menu-item > a:hover {
	color: var(--global-palette1, #e2001a) !important;
	background: var(--global-palette8, #faf8f5) !important;
}
/* Third-level flyout (Technologies' own children, inside the Knowledge
   dropdown) inherits the same overrides via the shared "ul ul" selector
   above, so Food Spraying/Chocolate/Other Technologies get the same
   white-panel treatment automatically — no separate rule needed. */

/* Parent-item dropdown indicator — Kadence renders this as a bold outlined
   SVG chevron (24x24 viewBox, quite heavy next to 14px nav text). The
   approved header design uses a small, light triangle instead, so the SVG
   is hidden and a text-character caret put in its place. Kadence still
   handles the box itself (.dropdown-nav-toggle is already absolutely
   positioned + sized by the theme); only its contents change. */
.header-navigation .dropdown-nav-toggle .kadence-svg-iconset {
	display: none;
}
.header-navigation .dropdown-nav-toggle {
	align-items: center;
	justify-content: center;
}
.header-navigation .dropdown-nav-toggle::after {
	content: "\25BE";
	display: inline-block;
	font-size: 11px;
	line-height: 1;
	color: var(--global-palette5, #6f6c68);
}
/* Nested flyout triggers (a parent item one level inside an already-open
   dropdown, e.g. Technologies inside Knowledge) point sideways instead of
   down — Kadence rotated its own SVG the same way via this exact selector,
   so the replacement caret picks up the same rule. */
.header-navigation .header-menu-container ul ul .dropdown-nav-toggle::after {
	display: inline-block;
	transform: rotate(-90deg);
}
.header-navigation li.menu-item > a:hover .dropdown-nav-toggle::after {
	color: var(--global-palette1, #e2001a);
}
/* "You are here" state inside a dropdown/flyout — Kadence's own rule sets
   white text (palette9) on a dark chip (palette4), built for the old dark
   dropdown. The link-color override above forces dark ink text regardless,
   so on an unpatched dark-on-dark chip that text became invisible — a
   solid black box where "Food Spraying" should read. Reuses the same
   cream+red hover treatment so the current item still reads as distinct,
   just no longer illegible. */
.header-navigation .header-menu-container ul ul li.menu-item.current-menu-item > a {
	background: var(--global-palette8, #faf8f5) !important;
	color: var(--global-palette1, #e2001a) !important;
}
