/* ==========================================================================
   Create Home Envy — redesign foundation
   Loaded after style.css. See PROJECT_SPECIFIC_ELEMENTOR_BUILD_NOTES.md.

   TWO SCOPES, BOTH NOW UNCONDITIONAL:

   .he-site      Design tokens — the custom properties everything below reads.
   .he-redesign  The resets (container default padding, radius, line-height)
                 and every component rule.

   Both are emitted on every request by che_body_class() in
   includes/redesign.php. The prefixes are kept as written rather than stripped
   out because they are a working opt-out: filtering `che_is_redesign_page` to
   false drops the resets for a request that needs Elementor's stock defaults
   back. Re-scoping ~1800 lines of selectors to achieve the identical computed
   result would only be a chance to change specificity by accident.

   HISTORY, so nobody "restores" the old gate: in the previous child theme
   .he-redesign was opt-in per post id, because 76% of the OLD site's Elementor
   containers rendered off the stock 10px default container padding and the
   reset would have stripped it from all of them at once. That theme is gone.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design tokens (build plan §A.2). Inert until consumed.
   -------------------------------------------------------------------------- */
.he-site {
	/* Surfaces */
	--he-sand:            #efe7da; /* default page background */
	--he-offwhite:        #fdfbf7; /* alternating band; header bar at .92 alpha */
	--he-white:           #ffffff;
	--he-ink:             #241f1c; /* dark bands, eyebrow chips, hero overlay */
	--he-footer:          #181513; /* footer only */

	/* Brand green */
	--he-green:           #76bb00; /* primary CTA, step numbers, active ring */
	--he-green-hover:     #88d000;
	--he-green-bright:    #96d42b; /* labels on dark bands, footer headings */
	--he-link:            #3f6300; /* body links, "Read more" */
	--he-green-tint:      #eff8e0; /* icon-chip backgrounds on light */
	--he-image-well:      #f2ece2; /* the product card's image well (:835) */

	/* Canada red */
	--he-red:             #c8102e; /* Made-in-Canada band, Promotions theme */
	--he-red-hover:       #a50d25;
	--he-red-light:       #e2314b;

	/* Text */
	--he-text-strong:     #17181a; /* headings */
	--he-text-body:       #3f3a35; /* body copy */
	--he-text-muted:      #5b544b; /* section paragraphs */
	--he-text-soft:       #6b6357;
	--he-text-softer:     #857c70;
	--he-text-softest:    #7d7466;

	/* Borders — light */
	--he-border:          #ece3d6; /* cards */
	--he-border-header:   #e6ddce;
	--he-border-input:    #e0d7c7;
	--he-border-outline:  #cdbfa8; /* outline buttons */

	/* Borders — dark */
	--he-border-on-ink:   #3d352e;
	--he-border-footer:   #2a2521;
	--he-border-social:   #342e28;

	/* Layout — the design has three container widths, not one */
	--he-container:       1200px;
	--he-container-faq:   900px;
}

/* --------------------------------------------------------------------------
   2. Resets — redesign templates ONLY.
   -------------------------------------------------------------------------- */

/*
 * MOVED TO THE KIT (wp-content/che-build/build-kit.php):
 *
 *   container default padding 0   -> kit `container_padding`
 *   body line-height `normal`     -> kit `body_typography_line_height` (custom)
 *   button + img radius 0         -> kit `button_border_radius` / `image_border_radius`
 *
 * They used to live here as CSS workarounds because the OLD kit was shared with
 * the live site and could not be touched. This theme ships with its own kit, so
 * the values belong in the kit — one source of truth, and the one the client can
 * actually edit. Do not re-add them here: a CSS copy silently wins over the kit
 * and the panel then lies about what the site does.
 *
 * What stays below is only what the kit has no control for.
 */

/*
 * CASCADE REPAIR for kit-bound heading colours (Step 3).
 *
 * A heading widget's Text Color control writes
 *   .elementor-element-<id> .elementor-heading-title { color: X }
 * but most headings in this build's chrome carry a `link`, so the visible text
 * is an <a> INSIDE that element — and the kit's own Theme Style writes
 * `.elementor-kit-27618 a { color: #3f6300 }`, which targets the anchor
 * directly and therefore beats inheritance. Without this one rule, binding
 * `title_color` on a linked heading looks correct in the panel, emits correct
 * CSS, and changes nothing on screen.
 *
 * This is a structural repair, not a design value: it carries no colour of its
 * own, it just lets the widget's own binding through. Hover is unaffected —
 * `title_hover_color` writes an `a:hover` rule, which outranks this one.
 */
.he-redesign .elementor-widget-heading .elementor-heading-title a {
	color: inherit;
}

/*
 * MOBILE FLEX-WRAP DEFAULT — the mechanism behind the "widget collapses to
 * near-zero height on a phone" class (rooms grid, every page-embedded Loop
 * Grid, the split-band photographs).
 *
 * Elementor ships this, in custom-frontend CSS:
 *
 *   .e-con-inner            { height: 100%; }
 *   @media (max-width:767px){ .e-con.e-flex { --flex-wrap: var(--flex-wrap-mobile); } }
 *
 * and it emits `--flex-wrap-mobile: wrap` into EVERY container's default block.
 * The two together are the defect. `height: 100%` gives a flex container a
 * DEFINITE main size; a `flex-direction: column` container with a definite
 * height and `flex-wrap: wrap` breaks its children into flex LINES that run
 * sideways — so a 2240px grid inside a 331px band is not clipped, it is moved
 * to a second column off to the right, and the widget reports the height of the
 * first line only (80px, or 0px for an image). Measured on the live DOM:
 * `flex-wrap: nowrap` on the parent restored every collapsed widget exactly.
 *
 * The intent of Elementor's rule is that ROW containers stack on a phone, and
 * that is worth keeping. So this does not set `flex-wrap` — it sets the
 * VARIABLE, at the same (0,2,0) specificity as Elementor's own mobile rule, in
 * a stylesheet that loads later (see note 52). It therefore beats the stock
 * default and LOSES to any container that authored a wrap of its own, because
 * Elementor writes those per element at (0,3,0)
 * (`.elementor-<post> .elementor-element.elementor-element-<id>`).
 *
 * `:where()` is load-bearing: it keeps the `.he-redesign` opt-out scope while
 * contributing ZERO specificity. Written as `.he-redesign .e-con.e-flex` the
 * rule would be (0,3,0), tie with every authored value, win on load order, and
 * silently flatten the hero CTA stack, the stats row and the footer legal row.
 */
@media (max-width: 767px) {
	:where(.he-redesign) .e-con.e-flex {
		--flex-wrap: nowrap;
	}
}

/*
 * WIDGET BOTTOM MARGIN — why a `.he-*` rule that says `margin-bottom` is dead.
 *
 * Elementor ships `.e-con .elementor-widget.elementor-widget{margin-block-end:0}`
 * to zero the stock widget spacing inside containers, because containers space
 * their children with `gap`. That rule is (0,3,0) AND it uses the LOGICAL
 * property, so a component rule written as `.he-redesign .he-x{margin-bottom:16}`
 * — (0,2,0), physical — loses twice over. It emits, it reads back correctly in
 * the stylesheet, and it computes to 0px. Seven rules in this file were dead
 * that way: three footer heads, four footer/mega/hub/capture gaps. Measured
 * gap head->links in the footer was 0px against the design's 16 (:1817).
 *
 * The two ways to write an under-widget gap that actually lands:
 *
 *   1. NATIVE `_margin` on the widget (che_eyebrow does this). Elementor emits
 *      it on `> .elementor-widget-container`, a DIFFERENT element, so the
 *      zeroing rule never touches it. This is the client-editable path and the
 *      right one for a value the design varies per instance.
 *   2. From this stylesheet, as `margin-block-end` on a selector that carries
 *      the `.elementor-widget` class as well — `.he-redesign .e-con
 *      .elementor-widget.he-x`, (0,4,0). Used below for the fixed values that
 *      belong to a component rather than to an instance.
 *
 * Never `margin-bottom` on a bare `.he-*` widget class. It is silently 0.
 */

/*
 * Radius on the elements the kit's Images/Buttons theme style does not reach:
 * text inputs, selects, textareas, containers and the design's card component.
 * (The kit covers `button`, `input[type=button|submit]`, `.elementor-button`
 * and `img`.) The design writes `border-radius: 0` on essentially every
 * element; the only rounded things are a 999px pill tag and the canvas chrome,
 * which is not part of the site.
 */
.he-redesign input,
.he-redesign select,
.he-redesign textarea,
.he-redesign .e-con,
.he-redesign .che-card {
	border-radius: 0;
}

/* ==========================================================================
   3. SECTION GRAMMAR  (build plan §A.3, design :846-872)

   Everything below is scoped under .he-redesign, so it reaches the redesign
   preview page and nothing else. The live pages are untouched by design, not
   by luck.

   NATIVE-vs-CSS, decided once per pattern (skill rule 6):
   band backgrounds are native container settings (a per-instance choice the
   client should make in the panel); section padding is CSS, because the
   design's single repeated rhythm — clamp(64px,8vw,120px) clamp(20px,5vw,48px)
   — cannot be expressed in Elementor's native dimensions control at all.
   ========================================================================== */

/* --- The band ----------------------------------------------------------- */

/*
 * The signature hairline. The design writes this <div> literally ~40 times;
 * here it is one ::before, so there is no extra element for an editor to
 * delete and no chance of forty copies drifting apart.
 */
.he-redesign .he-band {
	position: relative;
}

/*
 * ::after, NOT ::before — and this is load-bearing, not a style choice.
 *
 * `::before` on a container belongs to ELEMENTOR: it is the element that paints
 * the background overlay (`frontend.min.css`, `.e-con:before{content:var(--background-overlay);
 * position:absolute;top:…;left:…;height:max(100% + …);opacity:var(--overlay-opacity)}`).
 * The hairline used to be written on that same pseudo-element at 0,2,1, which
 * beat Elementor's 0,1,1 base rule and replaced the overlay's `height` and
 * `inset` with `height:1px; top/left/right:0`. Any band that set a background
 * overlay therefore got a 1px hairline instead of a scrim — and
 * `.he-mediahero::before{display:none}`, written to hide the hairline on a
 * photographic band, was switching OFF the hero's entire scrim.
 *
 * That is why the home and About heroes rendered white type on an unmasked
 * photograph, and it is why raising `background_overlay_opacity` to 1 changed
 * nothing: the element it applied to was `display: none`.
 *
 * RULE: never write `::before` on a `.e-con`. It is not ours.
 */
.he-redesign .he-band::after {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: 1px;
	background: linear-gradient(90deg, transparent, #76bb00, #96d42b, #76bb00, transparent);
	pointer-events: none;
	z-index: 2;
}

/* Promotions colourway (design :1338). */
.he-redesign .he-band--red::after {
	background: linear-gradient(90deg, transparent, #c8102e, #e2314b, #c8102e, transparent);
}

/*
 * THE 1140px TRAP — now fixed in the kit, not here.
 *
 * A boxed container does not cap its own width; Elementor caps the INNER box:
 *   .e-con > .e-con-inner { max-width: var(--content-width) }
 *   --content-width: min(100%, var(--container-max-width, 1140px))
 * so a kit that never sets container_width leaves every band 60px narrower than
 * the design, invisibly. This file used to force `--content-width: 100%` here to
 * escape it.
 *
 * The kit now sets container_width to 1104px — the design's real content box
 * (1200px band minus 2 x 48px of side padding, design :51 occurrences of
 * `margin:0 auto;padding:clamp(64px,8vw,120px) clamp(20px,5vw,48px)`). Inside a
 * band that equals the 100% the inner already had, so the rendering is
 * unchanged; outside one, a plain boxed container now gets the design's measure
 * instead of 1140px. The outer element below still owns the max-width and the
 * section padding.
 */
.he-redesign .he-band__inner:not(.he-native) {
	max-width: var(--he-container);
	margin-inline: auto;
	padding: clamp(64px, 8vw, 120px) clamp(20px, 5vw, 48px);
	width: 100%;
}

/* ≤760px: 64-120px bands are far too tall on a phone (design :91-96). */
@media (max-width: 760px) {
	.he-redesign .he-band__inner:not(.he-native) {
		padding-top: clamp(48px, 10vw, 64px);
		padding-bottom: clamp(48px, 10vw, 64px);
	}
}

/*
 * The band's own inherited colour, for anything not otherwise coloured.
 *
 * The `.he-band--dark .elementor-heading-title` half of this rule was REMOVED
 * in Step 3 and its removal is load-bearing: at specificity 0,3,0 it outranked
 * every widget's own `title_color` binding (0,2,0), so it would have painted
 * the on-dark eyebrow chip white-on-white the moment che_eyebrow() started
 * binding che_ink for that colourway. Heading colour on dark bands is now the
 * widget's, which is the whole point of Step 3.
 */
.he-redesign .he-band--dark {
	color: #ffffff;
}

/* --- Eyebrow chip (design :850) ----------------------------------------- */

/*
 * _css_classes lands on the widget WRAPPER, not the inner element (skill rule
 * 3), so the chip's box is drawn on the .elementor-heading-title descendant
 * while the wrapper stays a plain block. Painting the wrapper instead would
 * stretch the chip to the full column width.
 */
/*
 * Type and text colour are BOUND to the kit (`che_eyebrow`, and che_white /
 * che_ink per colourway) in che_eyebrow(). What is left here is the chip BOX,
 * which no widget control can reach: a heading widget's background control
 * paints the full-width wrapper, and the chip has to be inline-flex on the
 * title element itself or it stretches across the column.
 */
.he-redesign .he-eyebrow .elementor-heading-title {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	padding: 7px 13px;
	background: var(--he-ink);
	line-height: 1.2;
}

/* Chip -> heading gap. NATIVE on rebuilt pages (the design varies it 12-24px
   per section); this is the pre-native fallback. */
.he-redesign .he-eyebrow:not(.he-native) {
	margin-bottom: 12px;
}

.he-redesign .he-eyebrow--on-dark .elementor-heading-title {
	background: #ffffff;
}

.he-redesign .he-eyebrow--red .elementor-heading-title {
	background: var(--he-red);
}

/* --- Section head (design :851-852) ------------------------------------- */

/* Type and colour are bound to `che_h2` / che_text_strong|che_white in
   che_section_head(). Measure and wrapping have no widget control. */
.he-redesign .he-h2 .elementor-heading-title {
	margin: 0;
	text-wrap: balance;
}

/*
 * PRE-NATIVE FALLBACK. 14em is not a design value — the design states a measure
 * on three h2s only (18em :403, 16em :530, and the centred heads' 640px/560px)
 * and leaves the rest to the column. Rebuilt sections get the design's own
 * measure below; everything not yet rebuilt keeps the old blanket value.
 */
.he-redesign .he-h2:not(.he-native) .elementor-heading-title {
	max-width: 14em;
}

/* Type and colour bound to `che_lede` / che_text_muted. The MEASURE has no
   widget control and stays here; the margin is native on rebuilt pages.
   34em is the design's most common measure; the sections that state another
   get a modifier rather than a per-section rule. */
.he-redesign .he-lede {
	max-width: 34em;
}

.he-redesign .he-lede--36em { max-width: 36em; }   /* :963-965 built pricing, :532 visit */
.he-redesign .he-lede--38em { max-width: 38em; }   /* :643 */
.he-redesign .he-lede--40em { max-width: 40em; }   /* :1730 clearance hero, :466 steps foot */
.he-redesign .he-lede--none { max-width: none; }

.he-redesign .he-lede:not(.he-native) {
	margin-top: 16px;
}

.he-redesign .he-lede p {
	margin: 0;
}

/*
 * REMOVED, and the removal is the fix.
 *
 * This rule claimed the design's on-dark lede was `rgba(255,255,255,.78)`. It
 * is not: that string appears ZERO times in `Home Envy Redesign.dc.html`. Every
 * on-ink paragraph the design writes is flat `#ffffff` — :448 the how-it-works
 * intro, :918 "Endless options", :1141/:1146 the Made pillars. The alpha was
 * invented, and at 0,3,0 it beat every widget's own `che_white` binding
 * (0,2,0), so three views ran their on-dark body copy at 78%.
 *
 * `che_section_head()` used to leave `text_color` unbound on dark BECAUSE of
 * this rule. It now binds `che_white` like everything else, which is the whole
 * point of the kit.
 *
 * (Left as a comment rather than deleted silently: the next person will find
 * the .78 in git history and should know it was never a design value.)
 */

.he-redesign .he-sectionhead--center {
	text-align: center;
}

.he-redesign .he-sectionhead--center .he-h2 .elementor-heading-title,
.he-redesign .he-sectionhead--center .he-lede {
	max-width: 640px;   /* :444 */
	margin-inline: auto;
}

/* :504 — the testimonials head runs on a 560px measure, not 640. */
.he-redesign .he-sectionhead--narrow .he-h2 .elementor-heading-title,
.he-redesign .he-sectionhead--narrow .he-lede {
	max-width: 560px;
}

/* --- "Ask us anything" split (design :846-872) -------------------------- */

/*
 * auto-fit / minmax(300px,1fr) is the design's own rule, and it is what makes
 * the split collapse to one column without a hand-written breakpoint. The
 * display:contents unwrap is required here and ONLY here: a boxed container's
 * single .e-con-inner would otherwise be the grid's only child, so
 * grid-template-columns would compute against one item (skill rule 5). The
 * cost of the unwrap — native gap and vertical padding stop applying to the
 * inner box — is paid for deliberately, because this pattern's padding comes
 * from .he-band__inner above and its gap from the grid below.
 */
/*
 * The ask band's grid, its gap and its alignment are native container settings
 * now (`che_ask_us_anything()`), so the CSS grid and the `display: contents`
 * unwrap that went with it are gone — the unwrap voided native padding and gap
 * on that container for as long as it was there (project notes §54).
 *
 * Kept behind `:not(.he-native)` for any page still on the pre-native build.
 */
.he-redesign .he-ask__grid:not(.he-native) {
	display: grid !important;
	grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)) !important;
	gap: clamp(32px, 5vw, 64px) !important;
	align-items: start !important;
}

.he-redesign .he-ask__grid:not(.he-native) > .e-con-inner {
	display: contents;
}

.he-redesign .he-ask__copy,
.he-redesign .he-ask__panel {
	min-width: 0 !important; /* skill rule 7: flex/grid children that must shrink */
}

/* Type and colour bound to `che_body_lg` / che_text_body. */
.he-redesign .he-ask__phone {
	margin-top: 24px;
}

.he-redesign .he-ask__phone p {
	margin: 0;
}

.he-redesign .he-ask__phone a {
	color: var(--he-ink);
	font-weight: 700;
}

.he-redesign .he-ask__phone a:hover {
	color: var(--he-link);
}

.he-redesign .he-ask__panel {
	background: var(--he-white);
	border: 1px solid var(--he-border);
	padding: clamp(22px, 2.6vw, 30px);
}

/*
 * THE FIELD BOX, TAKEN FROM THE DESIGN SYSTEM'S OWN `Input`, NOT GUESSED.
 *
 * The design does not write these fields inline — it imports
 * `FlightPlanMarketingDesignSystem_9ecabb.Input` (:859-862) and gives only
 * `hint-size="100%,72px"`. The component's definition is in the bundle
 * (`_ds/…/_ds_bundle.js`, `function Input`), and it is the spec:
 *
 *   wrapper   display:flex; flex-direction:column; gap:6; width:100%
 *   label     font-family:var(--font-body); font-size:14; font-weight:var(--weight-bold)
 *   field     width:100%; height:46; padding:0 14px; font-size:15; border:1.5px solid var(--border-default)
 *   Textarea  same, and the design's `hint-size` for it is 100%,130px
 *
 * So the 72px hint is label (14px) + the 6px gap + the 46px field, and the
 * field itself is 46 — which answers the audit's open question: the hint
 * INCLUDES the label row. The built 46 / 1.5px / 0 14px / 130px were already
 * right; the label gap was 7 and is now the component's 6.
 *
 * COLOUR AND RADIUS ARE NOT TAKEN FROM THE DS. The bundled design system is a
 * different brand's (project notes: its colour tokens are 0% applicable and the
 * design overrides every one inline), and this design is radius-0 throughout,
 * where the component asks for `var(--radius-md)`. Structure from the
 * component; palette from the kit; radius from the design.
 */
.he-redesign .he-ask__form .elementor-field-group > label {
	margin-bottom: 6px;
}

/* Type, text colour AND background are bound (`che_body_lg`,
   che_text_body, che_white). The border stays: the form widget's own border
   control is a group whose width/colour the design's 1.5px hairline would need
   three settings to express, and no kit swatch matches --he-border-input. */
.he-redesign .he-ask__form .elementor-field-textual {
	min-height: 46px;
	border: 1.5px solid var(--he-border-input);
	padding: 0 14px;
}

.he-redesign .he-ask__form textarea.elementor-field-textual {
	padding: 12px 14px;
	min-height: 130px;
}

.he-redesign .he-ask__form .elementor-field-textual:focus {
	border-color: var(--he-green);
	outline: 2px solid rgba(118, 187, 0, .25);
	outline-offset: 0;
}

/*
 * Green, Mulish 600 16px and the hover green all come from the KIT's button
 * Theme Style — this button IS the design's large CTA, so the kit already owns
 * every one of those values. Only the design's full-width 52px box is left.
 */
.he-redesign .he-ask__form .elementor-button {
	width: 100%;
	height: 52px;
	border: none;
}

/* ==========================================================================
   4. HEADER  (design :165-259)

   THE BREAKPOINT: 1000/1001, everywhere, deliberately.
   The design switches nav to burger at 1040px. On Elementor 4.2.2 the Pro Nav
   Menu widget switches to dropdown mode at the KIT's tablet breakpoint (1000px)
   — the old "hardcodes 1024px" behaviour this file previously standardised on
   no longer holds, and 1024/1025 left a 1001-1024 band where the burger and the
   desktop nav were both visible (the nav wrapping to two rows). The whole build
   therefore standardises on the kit's number.

   TYPOGRAPHY AND COLOUR ARE NOT HERE ANY MORE (Step 3).
   Every size, weight, tracking and colour in the header is a Kit global bound
   on the widget (build-header.php). What is left below is geometry — the flex
   rows, the sticky bar, the mega grid, the tile — plus the handful of values
   that provably have no widget or kit control, each of which says so where it
   sits. A CSS copy of a bound value would silently win over the binding and the
   Elementor panel would then lie about what the site does, so a rule that
   reappears here is a regression, not a tidy-up.
   ========================================================================== */

.he-redesign .he-header {
	position: sticky;
	top: 0;
	z-index: 50;
}

@media (max-width: 1000px) {
	.he-redesign .he-hide-sm {
		display: none !important;
	}
}

@media (min-width: 1001px) {
	.he-redesign .he-only-sm {
		display: none !important;
	}
}

/* --- The bar's burger (design :179-184) --------------------------------- */

/*
 * A real button widget, first child of `.he-bar`. Elementor's Theme Style
 * paints every button solid Accent green (skill rule 9), so the design's
 * `border:none;background:transparent` has to be said here; the glyph colour is
 * bound on the widget. Padding is the design's 6px, set as `text_padding`.
 */
.he-redesign .he-burger .elementor-button {
	background: transparent;
	display: inline-flex;
	align-items: center;
	min-height: 44px;   /* :117 the design's phone tap-target floor */
	min-width: 44px;
	justify-content: center;
}

.he-redesign .he-burger .elementor-button-icon svg,
.he-redesign .he-burger .elementor-button-icon i {
	font-size: 24px;    /* :180 */
	line-height: 1;
}

/* The label is the accessible name only; the design shows the bars glyph. */
.he-redesign .he-burger .elementor-button-text {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
}

@media (min-width: 1001px) {
	.he-redesign .he-burger {
		display: none !important;
	}
}

/*
 * With a dedicated burger in the bar, Elementor's own nav-menu toggle would be
 * a SECOND visible burger in the wrong place. It is hidden only once the drawer
 * script has run — same contract as the native dropdown below: if the script
 * fails, the old toggle is still there and still opens the native menu.
 */
.he-drawer-ready .he-redesign .he-nav .elementor-menu-toggle {
	display: none !important;
}

/* --- Top bar (design :167-174) ------------------------------------------ */

.he-redesign .he-topbar__inner {
	max-width: var(--he-container);
	margin-inline: auto;
	padding: 8px clamp(20px, 5vw, 48px);
	display: flex !important;
	flex-direction: row !important;
	align-items: center !important;
	justify-content: space-between !important;
	gap: 16px !important;
	width: 100%;
}

.he-redesign .he-topbar__inner > .e-con-inner {
	display: contents;
}

/*
 * Type and colour are bound to `che_topbar` / `che_topbar_bold` and che_white
 * in build-header.php. The anchor takes the bound colour through the cascade
 * repair at the top of this file; all that is left here is the phone's icon
 * row, which is a layout concern.
 */
.he-redesign .he-topbar__phone .elementor-heading-title a {
	display: inline-flex;
	align-items: center;
	gap: 6px;
}

/*
 * The phone glyph before the number (design :170).
 *
 * A ::before rather than an icon widget: it is pure decoration that no client
 * will ever edit, and an icon widget here would need its own container and
 * would let the two drift apart in the editor. currentColor is baked into the
 * data URI as #ffffff because a background-image cannot inherit it; the hover
 * rule below re-states it in the green.
 */
.he-redesign .he-topbar__phone .elementor-heading-title a::before {
	content: "";
	flex: 0 0 14px;
	width: 14px;
	height: 14px;
	background-repeat: no-repeat;
	background-position: center;
	background-size: 14px 14px;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.9.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92z'/%3E%3C/svg%3E");
}

.he-redesign .he-topbar__phone .elementor-heading-title a:hover::before {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%2396d42b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.9.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92z'/%3E%3C/svg%3E");
}

/*
 * STAYS CSS, and it is a real limit of the binding model rather than an
 * oversight: a `__globals__` binding replaces the WHOLE typography group, so a
 * widget bound to `che_topbar` cannot also carry a `typography_font_size_mobile`
 * override — the global wins at every breakpoint. Responsive type steps that
 * belong to one widget and not to the global therefore stay here.
 */
/*
 * :119 — the whole top bar drops to 12px at phone. The promo's size comes from
 * the kit global bound on the widget, which Elementor writes as
 * `.elementor-<post> .elementor-element.elementor-element-<id> .elementor-heading-title`
 * — (0,4,0). The rule below carried three classes, lost, and the promo stayed
 * at the global's 13.5px. `.he-topbar` in the chain makes it (0,4,0) too, and
 * this stylesheet loads last (note 52), so it now lands.
 */
@media (max-width: 560px) {
	.he-redesign .he-topbar {
		font-size: 12px;
	}

	.he-redesign .he-topbar .he-topbar__promo .elementor-heading-title {
		font-size: 12px;
	}
}

/* --- Main bar (design :177-214) ----------------------------------------- */

.he-redesign .he-headerbar {
	background: rgba(253, 251, 247, .92);
	backdrop-filter: blur(12px);
	border-bottom: 1px solid var(--he-border-header);
}

.he-redesign .he-bar {
	max-width: var(--he-container);
	margin-inline: auto;
	padding: 14px clamp(20px, 5vw, 48px);
	display: flex !important;
	flex-direction: row !important;
	align-items: center !important;
	gap: 18px !important;
	width: 100%;
}

.he-redesign .he-bar > .e-con-inner {
	display: contents;
}

.he-redesign .he-logo {
	flex: 0 0 auto !important;
}

.he-redesign .he-logo img {
	height: 34px;
	width: auto;
	display: block;
}

/*
 * CLIENT DIRECTIVE 2026-08-25: centre the logo on mobile. The design keeps the
 * bar as [burger][logo] … [actions] at every width (:179-186) — it is
 * left-aligned by design, not by defect — so this is a deliberate override.
 *
 * Scoped to <=1000 because that is where `.he-only-sm` brings the burger in and
 * `.he-hide-sm` takes the desktop nav out; above it the logo must stay left of
 * the nav.
 *
 * Absolute centring rather than a three-column grid, because the bar has a
 * FOURTH child that must not claim a column: the Nav Menu widget is still in
 * the row at these widths, rendering the Elementor toggle that is the
 * no-JS fallback for the drawer. A grid would give it a track and shove the
 * logo off centre the moment the drawer script failed — i.e. exactly when the
 * header most needs to still make sense. Taking the logo out of flow leaves
 * burger and actions to divide the row between them and cannot be disturbed by
 * a sibling appearing or disappearing.
 *
 * `.he-bar` is the containing block: every Elementor container carries
 * `position: relative` via `.e-con { --position: relative }`. Restated here so
 * this does not silently depend on that.
 */
@media (max-width: 1000px) {
	.he-redesign .he-bar {
		position: relative;
	}

	.he-redesign .he-logo {
		position: absolute !important;
		left: 50% !important;
		top: 50% !important;
		transform: translate(-50%, -50%);
		margin: 0 !important;
	}

	/* The auto margin was pushing against the logo's flex box, which no longer
	   exists in the row. Without this the actions cluster stays put anyway, but
	   only by accident of there being nothing left to push. */
	.he-redesign .he-bar .he-actions {
		margin-inline-start: auto !important;
	}
}

/*
 * Elementor gives nested containers flex-grow:1 through its own variables
 * (skill rule 6), so the nav would otherwise eat the bar and shove the actions
 * off the right edge.
 */
.he-redesign .he-nav {
	flex: 0 1 auto !important;
	margin-left: 22px !important;
	min-width: 0 !important;
}

/*
 * THE NAV GAP — fixed at the source, not here. See build-header.php for the
 * mechanism. In short: this file used to carry
 *
 *   .he-nav .elementor-nav-menu--main > li:not(:last-child) { margin-right: 28px }
 *
 * and `.elementor-nav-menu--main` is the <nav>, whose only child is the <ul>.
 * The rule matched zero elements and the nav rendered "PromotionsContactBlog".
 * Spacing is now the widget's own `menu_space_between` control (28px), which
 * drives Elementor's `--e-nav-menu-horizontal-menu-item-margin`. Item padding,
 * item colour, hover colour and dropdown colours are all widget controls too,
 * bound to the kit.
 *
 * Hover BACKGROUND is the one thing left: the design's #f1eadd flyout hover
 * tint has no kit swatch, and `background_color_dropdown_item_hover` would need
 * one. Reported, not invented.
 */
.he-redesign .he-nav .elementor-nav-menu--main .elementor-item:hover,
.he-redesign .he-nav .elementor-nav-menu--main .elementor-item.highlighted,
.he-redesign .he-nav .elementor-nav-menu--main .elementor-item:focus {
	background: transparent;
}

/* About Us dropdown box (design :191-197). Border and min-width have no
   widget control on this widget; the item colours and padding do, and are
   bound in build-header.php. */
.he-redesign .he-nav .elementor-nav-menu--dropdown {
	border: 1px solid var(--he-border-header);
	padding: 8px;
	min-width: 250px;
}

.he-redesign .he-nav .elementor-nav-menu--dropdown a:hover {
	background: #f1eadd;
}

/*
 * Above the breakpoint the Products item opens the bespoke mega panel, so its
 * native submenu must not also drop down. Scoped to the desktop media query
 * (skill rule: media-query-scope every compensating hack) — below it, that same
 * submenu IS the mobile products accordion the design specifies.
 */
@media (min-width: 1001px) {
	.he-redesign .he-nav .he-mega-toggle > .elementor-nav-menu--dropdown,
	.he-redesign .he-nav .he-mega-toggle .sub-menu {
		display: none !important;
	}
}

/* --- Actions cluster (design :207-213) ---------------------------------- */

/*
 * `width: auto` is load-bearing, not tidiness. Elementor gives every container
 * `--width: 100%` and `.e-con { width: var(--width) }`, so this cluster's
 * flex-basis:auto resolves to the FULL bar width (1104px at 1320). It then
 * claims the whole row, and the nav — the only item here with flex-shrink:1 —
 * is squeezed to width:0, wrapping every menu item onto its own line on top of
 * these buttons. `flex: 0 0 auto` alone does not save it: with flex-basis auto
 * the 100% width IS the basis.
 */
.he-redesign .he-actions {
	margin-left: auto !important;
	display: flex !important;
	flex-direction: row !important;
	align-items: center !important;
	gap: 12px !important;
	flex: 0 0 auto !important;
	width: auto !important;
}

/* Colour bound to che_ink (`primary_color`). Size/padding stay: the icon
   widget's own size control writes font-size on a different selector and the
   design's 21px is the glyph, not the box. */
.he-redesign .he-search .elementor-icon {
	font-size: 21px;
	padding: 6px;
}

/*
 * `.he-btn` is the design's COMPACT button. The kit's button Theme Style is the
 * design's LARGE one (54px via 19/30 padding, 16px type), so this modifier
 * carries the compact BOX only — height and padding, which have no kit control
 * — while type comes from the `che_btn_sm` binding on each button widget.
 */
.he-redesign .he-btn .elementor-button {
	display: inline-flex;
	align-items: center;
	height: 42px;
	padding: 0 18px;
	line-height: 1;
}

/*
 * Elementor's Theme Style auto-applies the Kit's Accent as a button background
 * (skill rule 9), so an outline button needs the background killed explicitly
 * or it renders as a solid Kit-coloured block.
 */
/*
 * Border and text colour are bound (border_border/border_width/border_color and
 * button_text_color). The transparent BACKGROUND is not bindable — the control
 * takes a colour and the kit has no transparent swatch — and killing it is what
 * stops Elementor's Theme Style painting this button solid Accent green
 * (skill rule 9). The hover pair is the design's one-off #efe6d7, likewise not
 * a kit colour.
 */
.he-redesign .he-btn--outline .elementor-button {
	background: transparent;
}

.he-redesign .he-btn--outline .elementor-button:hover {
	border-color: var(--he-ink);
	background: #efe6d7;
	color: var(--he-ink);
}

/* Background, border and text colour are bound (background_color = che_green,
   border_border = none, button_text_color = che_text_strong); hover green comes
   from the kit's button Theme Style. Only the design's 20px inset is left. */
.he-redesign .he-btn--green .elementor-button {
	padding: 0 20px;
}

/*
 * Narrow desktop (1025–1200). Above the nav's 1025 desktop threshold the row
 * still has to hold the logo, five nav items and both CTAs, and it does not
 * fit: at 1025 the content box is 929px and the row needs 1010px, so the nav
 * wraps onto a second line over the buttons. The design already drops the
 * secondary CTA below 1024 (`he-hide-sm`); dropping it 176px earlier keeps one
 * nav row all the way down to the burger switch. Measured: at 1200 the nav
 * needs 416px and has 674px; at 1201, with the CTA back, it has 511px.
 */
@media (max-width: 1200px) {
	.he-redesign .he-bar .he-btn--outline {
		display: none !important;
	}
}

/* Phone: bar tightens, the quote CTA is dropped entirely (design :114-118). */
@media (max-width: 560px) {
	.he-redesign .he-bar {
		padding-top: 10px;
		padding-bottom: 10px;
		gap: 8px !important;
	}

	.he-redesign .he-bar .elementor-button,
	.he-redesign .he-bar .elementor-item {
		min-height: 44px;
	}

	/* The HEADER's quote CTA only — scoped to the bar so it cannot reach the
	   testimonial cards, which is what the unscoped selector used to do. */
	.he-redesign .he-bar .he-quote {
		display: none !important;
	}

	.he-redesign .he-actions {
		min-width: 0 !important;
	}
}

/* --- Products mega panel (design :216-256) ------------------------------ */

/*
 * Closed by default and opened by a class, not by a JS style write: if the
 * script fails the panel simply stays shut, which is the harmless state. The
 * panel is only ever revealed above the dropdown breakpoint.
 */
/*
 * CLIENT DIRECTIVE 2026-08-25, overrides the design: the panel is a POPOVER,
 * not an in-flow band. The design authors it as a sibling of `.he-bar` inside
 * the header bar (:216-256), so opening it pushed the whole page down.
 *
 * `.he-headerbar` is the containing block — it is an Elementor container, so
 * `.e-con { position: relative }` already positions it, AND it carries
 * `backdrop-filter: blur(12px)`, which forms a containing block for absolute
 * descendants on its own. Two independent reasons it resolves here; `position`
 * is restated below so the panel does not depend on either one silently
 * staying true. `top: 100%` is then the bar's own bottom edge.
 *
 * The panel keeps its opaque `#fdfbf7` background (bound on the widget) — it
 * now overlays the hero, so a translucent one would be unreadable. The shadow
 * is the only new paint: it is what separates a floating panel from a band,
 * and the design has no value for it because the design has no popover.
 */
.he-redesign .he-mega {
	display: none !important;
	border-top: 1px solid var(--he-border-header);
}

@media (min-width: 1001px) {
	.he-redesign .he-mega.he-mega--open {
		display: block !important;
		position: absolute;
		top: 100%;
		left: 0;
		right: 0;
		z-index: 60;
		width: auto !important;
		border-bottom: 1px solid var(--he-border-header);
		box-shadow: 0 18px 40px -12px rgba(20, 16, 13, .28);
		animation: heFade .18s cubic-bezier(.22, .61, .36, 1) both;
	}

	.he-redesign .he-headerbar {
		position: relative;
	}
}

@keyframes heFade {
	from { opacity: 0; transform: translateY(-6px); }
	to   { opacity: 1; transform: none; }
}

.he-redesign .he-mega__inner {
	max-width: var(--he-container);
	margin-inline: auto;
	padding: 28px clamp(20px, 5vw, 48px);
	display: grid !important;
	grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)) !important;
	gap: 28px 24px !important;
	width: 100%;
}

.he-redesign .he-mega__inner > .e-con-inner {
	display: contents;
}

.he-redesign .he-mega__col {
	min-width: 0 !important;
}

/* Type and colour bound to `che_mega_head` / che_green. */
.he-redesign .e-con .elementor-widget.he-mega__head {
	margin-block-end: 12px;
}

/*
 * CLIENT DIRECTIVE 2026-08-25: "should mimic the About Us submenu hovers".
 *
 * The design gives these links no hover surface at all (:221-240) — only a
 * text-colour change, which is bound on the widget (title_hover_color =
 * che_link). The About Us dropdown DOES have one (:192-196):
 * `color:#3f6300; background:#f1eadd`.
 *
 * CORRECTION 2026-08-25: folding the design's 9px flex gap into 9px vertical
 * row padding did NOT preserve the rhythm — it doubled it (9px gap became
 * 18px of stacked padding) and the column read as giant. The design's 9px gap
 * is restored and the hover surface carries NO vertical padding, so hovering
 * cannot change a link's box size. Horizontal 12px stays: it is what gives the
 * hover surface its bleed.
 *
 * The `-12px` inline-start margin is what keeps the text hanging on the
 * column's left edge, aligned with the column head, while the hover surface
 * bleeds out to cover the inset. Without it every link would sit 12px right of
 * its own heading.
 */
.he-redesign .he-mega__links {
	display: flex !important;
	flex-direction: column !important;
	gap: 9px !important;
	margin-inline-start: -12px;
}

.he-redesign .he-mega__link .elementor-heading-title a,
.he-redesign .he-mega__link .elementor-heading-title {
	display: block;
	padding: 0 12px;
}

.he-redesign .he-mega__link .elementor-heading-title a:hover,
.he-redesign .he-mega__link .elementor-heading-title a:focus-visible {
	background: #f1eadd;
}

/* Clearance tile (design :243-253). */
.he-redesign .he-mega__tile {
	position: relative;
	min-width: 190px !important;
	min-height: 184px;
	display: flex !important;
	flex-direction: column !important;
	justify-content: flex-end !important;
	overflow: hidden;
	padding: 16px !important;
}

.he-redesign .he-mega__tile .he-tile__img {
	position: absolute;
	inset: 0;
	margin: 0;
}

.he-redesign .he-mega__tile .he-tile__img img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	opacity: .62;
	display: block;
}

/* The dark scrim the label sits on. A pseudo-element, so it is not an extra
   widget for an editor to trip over. */
.he-redesign .he-mega__tile::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(to top, rgba(20, 16, 13, .9) 0%, rgba(20, 16, 13, .22) 70%, transparent 100%);
	pointer-events: none;
}

.he-redesign .he-mega__tile > *:not(.he-tile__img) {
	position: relative;
	z-index: 1;
}

.he-redesign .he-tile__tag {
	position: absolute !important;
	top: 14px;
	left: 14px;
	z-index: 1;
}

/* Type and colour bound to `che_tile_tag` / che_text_strong. The chip box is
   the same unbindable case as the eyebrow chip. */
.he-redesign .he-tile__tag .elementor-heading-title {
	display: inline-flex;
	align-items: center;
	background: var(--he-green);
	padding: 5px 10px;
}

/* `che_tile_title` / che_white and `che_micro` / che_green_bright. */
.he-redesign .he-tile__cta {
	margin-top: 9px;
}

/* ==========================================================================
   4b. OFF-CANVAS MOBILE DRAWER  (design :261-330)

   Markup: wp-content/themes/hello-elementor-child-2026/includes/mobile-drawer.php,
   rendered at wp_footer so it is a SIBLING of the header, not a descendant.
   The header bar carries `backdrop-filter`, and a non-none backdrop-filter makes
   its element a containing block for fixed-position descendants — a drawer
   authored inside the header template would position against the header instead
   of the viewport. The design's own source comment says exactly this (:261).

   Type reads the Kit's global custom properties rather than repeating literals,
   so the client editing `HE Chrome Link` or `HE Tile Title` moves the drawer
   too. The fallbacks after each var() are the design's values and exist only for
   the case where the Kit stylesheet has not loaded.
   ========================================================================== */

/*
 * The native Nav Menu dropdown is hidden ONLY once the drawer script has run
 * and stamped `he-drawer-ready` on <html>. If the script fails, nothing is
 * hidden and Elementor's own dropdown is still the mobile menu. That is the
 * fallback, and it is why the burger button is Elementor's rather than ours.
 */
.he-drawer-ready .he-redesign .he-nav .elementor-nav-menu--dropdown.elementor-nav-menu__container {
	display: none !important;
}

/*
 * FALLBACK: MAKE THE NATIVE DROPDOWN FULL-BLEED WITHOUT USING ELEMENTOR'S
 * STRETCH ARITHMETIC AT ALL.
 *
 * When the drawer script has not run, Elementor's own dropdown IS the mobile
 * menu and it has to work. Measured at viewport 500 (supervisor, browser): it
 * spanned x=247 to x=747 — half of it off-screen right.
 *
 * MECHANISM. `full_width: stretch` makes Elementor position the dropdown
 * absolutely and then write width/left/top inline from JS
 * (frontend-modules.js, StretchElement::stretch). Those are document-relative,
 * so they are only correct if the dropdown's containing block starts at x=0.
 * It does not: Elementor's frontend.min.css carries a bare
 * `.elementor-widget { position: relative }`, which makes the NAV-MENU WIDGET
 * the containing block. The widget sits at x=247 in the centred, clamp-padded
 * bar, so the inline `left: 0` lands the panel at 247.
 *
 * MEASURED ANCESTOR CHAIN, nearest first (supervisor, viewport 500):
 *     .elementor-widget-container   static    l=247
 *     .he-nav  (the widget)         RELATIVE  l=247   <- the culprit
 *     .e-con-inner                  static    l=0     (display:contents; rect is meaningless)
 *     .he-bar                       relative  l=0     <- the containing block after this fix
 *     .he-headerbar                 relative  l=0     backdrop-filter: blur(12px)
 *     .he-header                    sticky    l=0
 *
 * Note EVERY Elementor container is positioned: `.e-con { --position: relative;
 * position: var(--position) }`. So dropping the widget's own position hands the
 * containing block to `.he-bar` — NOT to `.he-headerbar`, which two earlier
 * versions of this comment claimed. `.he-bar` is `max-width: 1200px` centred,
 * but this rule only ever applies below Elementor's hardcoded 1024px dropdown
 * breakpoint, where the bar is full width and starts at x=0. That bound is why
 * this works.
 *
 * THE FIX REMOVES THE ARITHMETIC RATHER THAN CORRECTING IT. With the widget
 * static, `left/right: 0` gives full width whatever JS wrote, and `top: 100%`
 * resolves to the containing block's bottom edge — directly under the bar —
 * instead of depending on a measured toggle height. Every property
 * StretchElement writes is overridden, so a wrong computation cannot reach the
 * page. (It computes a wrong one: it measures the element while it is still
 * collapsed, jQuery returns offset 0, and it writes `left: 0px`.)
 *
 * WHY NOT `position: fixed`, which was the other candidate: its failure mode is
 * worse. A backdrop-filter ancestor forms a containing block for FIXED
 * descendants too, so on this page it would resolve against `.he-headerbar` and
 * look identical — but if that ever stops being true, `top: 100%` resolves
 * against the VIEWPORT height and throws the panel off the bottom of the
 * screen. The absolute version's worst case is merely a different full-bleed
 * ancestor one step further out (`.he-headerbar`, then `.he-header`), which
 * shifts the panel down by the topbar's height and stays usable. Prefer the
 * option whose degradation is boring.
 *
 * Scoped to `:not(.he-drawer-ready)` so none of it exists once the drawer owns
 * mobile navigation.
 */
html:not(.he-drawer-ready) .he-redesign .he-nav.elementor-widget {
	position: static !important;
}

html:not(.he-drawer-ready) .he-redesign .he-nav .elementor-nav-menu--dropdown.elementor-nav-menu__container {
	left: 0 !important;
	right: 0 !important;
	width: auto !important;
	top: 100% !important;
}


.he-drawer-open,
.he-drawer-open body {
	overflow: hidden;
}

.he-drawer[hidden] {
	display: none;
}

.he-drawer__scrim {
	position: fixed;
	inset: 0;
	z-index: 80;
	background: rgba(20, 16, 13, .55);
	backdrop-filter: blur(2px);
	opacity: 0;
	transition: opacity .22s ease;
}

.he-drawer__panel {
	position: fixed;
	top: 0;
	left: 0;
	bottom: 0;
	z-index: 81;
	width: min(88vw, 400px);
	background: var(--he-offwhite);
	display: flex;
	flex-direction: column;
	box-shadow: 0 0 60px rgba(20, 16, 13, .4);
	transform: translateX(-100%);
	transition: transform .3s cubic-bezier(.22, .61, .36, 1);
}

.he-drawer--open .he-drawer__scrim {
	opacity: 1;
}

.he-drawer--open .he-drawer__panel {
	transform: none;
}

@media (prefers-reduced-motion: reduce) {
	.he-drawer__scrim,
	.he-drawer__panel {
		transition: none;
	}
}

/* Above the nav breakpoint the drawer is never the navigation. */
@media (min-width: 1001px) {
	.he-drawer {
		display: none !important;
	}
}

/* --- Head (:265-271) ---------------------------------------------------- */

.he-drawer__head {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding: 16px 20px;
	border-bottom: 1px solid var(--he-border-header);
	background: var(--he-white);
}

.he-drawer__logo {
	height: 30px;
	width: auto;
	display: block;
}

.he-drawer .he-drawer__close {
	flex: 0 0 auto;
	width: 42px;
	height: 42px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	/* The kit's global button padding (18px 28px, set as `.elementor-kit-* button`,
	 * specificity 0,1,1) otherwise fills the whole 42px box and flex-squeezes the
	 * X icon to zero width — hence the extra .he-drawer in this selector. */
	padding: 0;
	background: var(--he-sand);
	border: none;
	color: var(--he-ink);
	cursor: pointer;
}

.he-drawer__close:hover {
	background: var(--he-ink);
	color: var(--he-white);
}

/* --- Scroll body (:273-320) --------------------------------------------- */

/*
 * CLIENT DIRECTIVE 2026-08-25 — three-stage drill-down.
 *
 * The scroll box is now the STAGE, not the scroller: it clips, and each
 * `.he-drawer__level` inside it does its own scrolling. The padding moved down
 * onto the levels with it, or the panels would slide in already inset from the
 * left edge and the whole stack would look 20px narrower than the drawer.
 *
 * `overflow: hidden` here is what makes the incoming panel appear from the
 * drawer's own edge rather than from somewhere out in the page.
 */
.he-drawer__scroll {
	flex: 1;
	min-height: 0;
	position: relative;
	overflow: hidden;
}

.he-drawer__level {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
	overscroll-behavior: contain;
	scrollbar-width: none;
	padding: 8px 20px 20px;
	background: var(--he-offwhite);
	transform: translateX(100%);

	/*
	 * An off-screen level is `visibility: hidden`, which is what takes it out
	 * of the tab order — the accessibility half of "off screen".
	 *
	 * The obvious way to hold it visible for the 240ms it spends sliding away
	 * is `transition: visibility 0s linear .24s`. That was tried and it does
	 * not reliably fire: the outgoing panel's transform animated to completion
	 * while its visibility never flipped, leaving levels stacked and visible.
	 * So the timing is driven from JS instead (`is-leaving`, removed on
	 * transitionend), and visibility here is a plain state with no transition
	 * of its own. A CSS trick that works "usually" is worse than three lines of
	 * script that always do.
	 */
	visibility: hidden;
	transition: transform .24s cubic-bezier(.22, .61, .36, 1);
}

/* Held visible by the script only while it slides out. */
.he-drawer__level.is-leaving {
	visibility: visible;
}

/*
 * Layering matters for the 240ms both panels are on screen. The levels are
 * siblings in collector order, which puts a PARENT panel after its children in
 * the DOM (che_drawer_collect_panels appends depth-first), so paint order alone
 * would draw the panel you are leaving on top of the one you are entering.
 */
.he-drawer__level.is-current {
	z-index: 2;
	transform: none;
	visibility: visible;
}

/* Ancestors park just off the left edge so the incoming panel reads as
   covering them rather than replacing them. */
/*
 * A parked ancestor stays PAINTED, not hidden: it has to be on screen for the
 * 240ms it spends sliding from 0 to -22%, and once parked it is completely
 * covered by the opaque current panel anyway, so there is nothing to gain by
 * hiding it. Keyboard and screen-reader access is handled by `inert`, which
 * the script sets on every level except the current one — `visibility` is not
 * carrying that job here, so it does not have to be timed.
 */
.he-drawer__level.is-past {
	z-index: 1;
	visibility: visible;
	transform: translateX(-22%);
}

@media (prefers-reduced-motion: reduce) {
	.he-drawer__level {
		transition: none;
	}
}

.he-drawer__scroll::-webkit-scrollbar,
.he-drawer__level::-webkit-scrollbar {
	width: 0;
	height: 0;
	display: none;
}

/* The "‹ Dining Room" header of a pushed panel. */
.he-drawer .he-drawer__back {
	display: flex;
	align-items: center;
	gap: 8px;
	width: 100%;
	min-height: 44px;
	padding: 12px 0;
	margin-bottom: 2px;
	background: transparent;
	border: none;
	border-bottom: 1px solid var(--he-border-header);
	color: var(--he-text-body);
	font-family: var(--e-global-typography-che_link_sm-font-family, "Mulish"), sans-serif;
	font-size: 13px;
	font-weight: 700;
	letter-spacing: .08em;
	text-transform: uppercase;
	cursor: pointer;
	text-align: left;
}

.he-drawer .he-drawer__back svg {
	flex: 0 0 auto;
	color: var(--he-link);
}

/* "All Dining Room" — the row that reaches the section's own landing page.
   Without it a branch row would be a pure grouping control and the landing
   page would be unreachable from the drawer entirely. */
.he-drawer .he-drawer__row--all {
	color: var(--he-link);
}

.he-drawer .he-drawer__row--all svg {
	color: currentColor;
}

/*
 * THE `.he-drawer` PREFIX IS LOad-BEARING — same trap the close button already
 * carries a note about, one selector further down.
 *
 * The Kit's button Theme Style emits `.elementor-kit-27618 button { ... }`,
 * which is (0,1,1) and outranks a bare `.he-drawer__row` at (0,1,0). The
 * branch rows are real `<button>` elements, so without the extra class they
 * are painted solid Accent green with 18px/28px kit padding — skill rule 9,
 * arriving through the element selector rather than through `.elementor-button`.
 * Every property the kit sets on `button` has to be answered here, not just
 * the background: font, colour, radius and padding all come with it.
 */
.he-drawer .he-drawer__row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	width: 100%;
	gap: 12px;
	padding: 17px 0;
	background: transparent;
	border-radius: 0;
	border: none;
	border-bottom: 1px solid var(--he-border-header);
	font-family: var(--e-global-typography-che_tile_title-font-family, "Archivo"), sans-serif;
	font-weight: var(--e-global-typography-che_tile_title-font-weight, 600);
	font-size: 17px;
	color: var(--he-text-strong);
	cursor: pointer;
	text-align: left;
}

.he-drawer .he-drawer__row svg {
	color: #b8ac9a;
}

.he-drawer__chip {
	flex: 0 0 auto;
	width: 26px;
	height: 26px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: var(--he-sand);
	color: var(--he-ink);
	transition: background .18s;
}

.he-drawer__chip svg {
	color: currentColor;
	transition: transform .22s cubic-bezier(.22, .61, .36, 1);
}

/*
 * The chip's chevron points RIGHT now — a branch row pushes a panel sideways
 * instead of expanding one underneath itself, so there is no open/closed state
 * left for it to express. The rules that rotated it 180° and painted it green
 * on `aria-expanded="true"` went with the accordion: on the stack, a row reads
 * expanded for as long as you are inside it, and painting the row you came
 * through green on a panel you can no longer see is state nobody can use.
 */

/* Second-level and deeper leaf rows: lighter than a top-level row, which is
   what `.he-drawer__sublink` used to say before the levels were introduced. */
.he-drawer .he-drawer__row--sub {
	font-family: var(--e-global-typography-che_link_sm-font-family, "Mulish"), sans-serif;
	font-size: 15.5px;
	font-weight: 600;
	color: var(--he-text-body);
	padding: 13px 0;
	border-bottom: 1px solid #f0e9dd;
}

.he-drawer .he-drawer__row--sub svg {
	color: #b8ac9a;
}

/*
 * ---------------------------------------------------------------------------
 * CLIENT 2026-08-25: "hover states are broken!" on the mobile menu.
 * ---------------------------------------------------------------------------
 * Two separate faults, and the second is the one that reads as "broken":
 *
 *  1. `.he-drawer__row` — the top-level rows — had NO hover rule at all. Only
 *     the old sublinks did.
 *  2. Every hover rule in the drawer was unguarded. On a touch screen `:hover`
 *     is not a transient state: it latches on tap and stays latched until the
 *     visitor touches something else, so tapping through the menu left a trail
 *     of rows stuck in their hover colour. On the one device this menu exists
 *     for, that is all a bare `:hover` ever does.
 *
 * So hover is gated behind a real pointer, and touch gets `:active` instead —
 * which is genuinely transient. `:focus-visible` rides with hover so keyboard
 * users see the same affordance.
 */
.he-drawer .he-drawer__row:active,
.he-drawer .he-drawer__back:active,
.he-drawer .he-drawer__tile:active {
	background: var(--he-sand);
}

@media (hover: hover) and (pointer: fine) {
	.he-drawer .he-drawer__row:hover,
	.he-drawer .he-drawer__row:focus-visible,
	.he-drawer .he-drawer__back:hover,
	.he-drawer .he-drawer__back:focus-visible {
		background: #f1eadd;
		color: var(--he-link);
	}

	.he-drawer .he-drawer__row:hover .he-drawer__chip,
	.he-drawer .he-drawer__row:focus-visible .he-drawer__chip {
		background: var(--he-green);
	}

	.he-drawer .he-drawer__row:hover svg,
	.he-drawer .he-drawer__row:focus-visible svg {
		color: currentColor;
	}

	.he-drawer__tile:hover .he-drawer__tileimg {
		opacity: .78;
	}
}

/*
 * The rows are full-bleed hover surfaces inside a 20px-padded level, so the
 * highlight has to bleed back out over that padding or it stops short of both
 * edges and reads as a misaligned box rather than a row.
 */
.he-drawer .he-drawer__row,
.he-drawer .he-drawer__back {
	padding-inline: 20px;
	margin-inline: -20px;
	width: calc(100% + 40px);
}

/* Clearance tile (:315-320). */
.he-drawer__tile {
	position: relative;
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
	min-height: 150px;
	margin-top: 22px;
	overflow: hidden;
	background: var(--he-ink);
}

.he-drawer__tileimg {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	opacity: .6;
}

.he-drawer__tile::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(to top, rgba(20, 16, 13, .92) 0%, rgba(20, 16, 13, .2) 72%, transparent 100%);
}

.he-drawer__tilebody {
	position: relative;
	z-index: 1;
	padding: 15px;
}

.he-drawer__tiletag {
	display: inline-flex;
	align-items: center;
	margin-bottom: 9px;
	padding: 5px 9px;
	background: var(--he-green);
	color: var(--he-text-strong);
	font-family: var(--e-global-typography-che_tile_tag-font-family, "Mulish"), sans-serif;
	font-weight: 600;
	font-size: 11px;
	letter-spacing: .1em;
	text-transform: uppercase;
}

.he-drawer__tiletitle {
	display: block;
	font-family: var(--e-global-typography-che_tile_title-font-family, "Archivo"), sans-serif;
	font-weight: 600;
	font-size: 16px;
	line-height: 1.2;
	color: var(--he-white);
}

/* --- Sticky footer (:322-330) ------------------------------------------- */

.he-drawer__foot {
	flex: 0 0 auto;
	padding: 16px 20px 20px;
	border-top: 1px solid var(--he-border-header);
	background: var(--he-sand);
	display: flex;
	flex-direction: column;
	gap: 11px;
}

.he-drawer__cta,
.he-drawer__phone {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 9px;
	width: 100%;
	height: 50px;
	font-family: var(--e-global-typography-che_btn_sm-font-family, "Mulish"), sans-serif;
	font-weight: 600;
	font-size: 15.5px;
}

.he-drawer__cta {
	background: var(--he-green);
	color: var(--he-text-strong);
	border: none;
}

.he-drawer__cta:hover {
	background: var(--he-green-hover);
	color: var(--he-text-strong);
}

.he-drawer__phone {
	border: 1.5px solid var(--he-border-outline);
	color: var(--he-ink);
}

.he-drawer__phone:hover {
	border-color: var(--he-ink);
	background: #e6dcca;
	color: var(--he-ink);
}

.he-drawer__address {
	font-family: var(--e-global-typography-che_legal-font-family, "Mulish"), sans-serif;
	font-size: 12.5px;
	color: var(--he-text-softest);
	text-align: center;
}

/* ==========================================================================
   5. FOOTER  (design :1803-1853)
   ========================================================================== */

.he-redesign .he-footer {
	position: relative;
	overflow: hidden;
	color: #ffffff;
}

.he-redesign .he-ftcols {
	max-width: var(--he-container);
	margin-inline: auto;
	padding: clamp(40px, 4.5vw, 60px) clamp(20px, 5vw, 48px);
	display: grid !important;
	grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)) !important;
	gap: 0 !important;
	width: 100%;
}

.he-redesign .he-ftcols > .e-con-inner {
	display: contents;
}

/* Vertical rules with first/last resets (design :42-44). */
.he-redesign .he-ft__col {
	padding: 0 32px !important;
	border-right: 1px solid var(--he-border-footer);
	min-width: 0 !important;
}

.he-redesign .he-ft__col:first-child {
	padding-left: 0 !important;
}

.he-redesign .he-ft__col:last-child {
	padding-right: 0 !important;
	border-right: none;
}

/* ≤900px the columns lose their gutters and rules (design :45). */
@media (max-width: 900px) {
	.he-redesign .he-ftcols {
		gap: 32px !important;
	}

	.he-redesign .he-ft__col {
		padding: 0 !important;
		border-right: none !important;
	}
}

@media (max-width: 560px) {
	.he-redesign .he-ftcols {
		grid-template-columns: 1fr !important;
		gap: 28px !important;
	}

	/*
	 * :141 says `.he-ftcols a{min-height:38px}` and :144 says
	 * `.he-taplist a{min-height:44px}`. Both match the footer's Shop and Company
	 * links at equal specificity and `.he-taplist` is written later, so the
	 * design's own EFFECTIVE floor is 44 — the two rules were merged here and the
	 * losing value was the one that got kept.
	 */
	.he-redesign .he-taplist a {
		min-height: 44px;
		display: flex;
		align-items: center;
	}
}

.he-redesign .he-ft__logo img {
	height: 34px;
	width: auto;
	/* The design ships one dark-on-light logo and inverts it for the footer
	   rather than shipping a second asset (design :1810). */
	filter: brightness(0) invert(1);
	display: block;
}

.he-redesign .e-con .elementor-widget.he-ft__logo {
	margin-block-end: 16px;
}

/* Type and colour bound to `che_ft_blurb` / che_white. The .72 opacity is the
   design's own way of dimming white on the footer ink; a kit colour cannot
   express it and an rgba swatch would be a fourth near-white in the palette. */
.he-redesign .he-ft__blurb {
	max-width: 22em;
	opacity: .72;
}

.he-redesign .e-con .elementor-widget.he-ft__blurb {
	margin-block-end: 18px;
}

.he-redesign .he-ft__blurb p {
	margin: 0;
}

/* Glyph colour bound to che_white (`icon_secondary_color`). The transparent
   chip and its 1px rule have no kit swatch. */
.he-redesign .he-ft__social .elementor-social-icon {
	width: 38px;
	height: 38px;
	border-radius: 0;
	border: 1px solid var(--he-border-social);
	background: transparent;
	font-size: 17px;
}

.he-redesign .he-ft__social .elementor-social-icon:hover {
	background: var(--he-green);
	border-color: var(--he-green);
	color: var(--he-text-strong);
}

/* Type and colour bound to `che_overline` / che_green_bright. */
.he-redesign .e-con .elementor-widget.he-ft__head {
	margin-block-end: 16px;
}

.he-redesign .he-ft__links {
	display: flex !important;
	flex-direction: column !important;
	gap: 11px !important;
}

/*
 * Client review round 1: the Shop/Company link lists read as too loosely
 * spaced on a phone. The design's own 11px gap (base rule above) STACKS on top
 * of the 44px tap-target row — each link already carries ~15px of vertical
 * padding inside its own box from centring 14.5px text in a 44px line, so the
 * extra gap between rows reads as excessive. Departure from the design's
 * literal value at this one breakpoint: the 44px tap target alone is the
 * spacing.
 *
 * CORRECTION 2026-08-25: this override used to live in the ≤560 block ~60
 * lines EARLIER in the file. Same specificity, both `!important`, so the
 * unconditional base rule below it won at every width and the phone gap stayed
 * at 11px. It has to sit after the rule it overrides.
 */
@media (max-width: 560px) {
	.he-redesign .he-ft__links {
		gap: 0 !important;
	}
}

/*
 * The design draws a pin and a clock beside these two lines. They are
 * ::before glyphs rather than separate icon widgets so the icon cannot drift
 * out of sync when the client edits the address — there is only one element.
 */
/* Type and colour bound to `che_link_sm` / che_white. */
.he-redesign .he-ft__detail {
	position: relative;
	padding-left: 27px;
	line-height: 1.5;
}

.he-redesign .e-con .elementor-widget.he-ft__detail {
	margin-block-end: 12px;
}

.he-redesign .he-ft__detail p {
	margin: 0;
}

.he-redesign .he-ft__detail::before {
	content: "";
	position: absolute;
	left: 0;
	top: 2px;
	width: 17px;
	height: 17px;
	background-repeat: no-repeat;
	background-size: 17px 17px;
}

.he-redesign .he-ft__detail--place::before {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17' viewBox='0 0 24 24' fill='none' stroke='%2376bb00' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z'/%3E%3Ccircle cx='12' cy='10' r='3'/%3E%3C/svg%3E");
}

.he-redesign .he-ft__detail--hours::before {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17' viewBox='0 0 24 24' fill='none' stroke='%2376bb00' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 6v6l4 2'/%3E%3C/svg%3E");
}

/* --- Legal row (design :1841-1852) -------------------------------------- */

.he-redesign .he-ft__legal {
	border-top: 1px solid var(--he-border-footer);
}

.he-redesign .he-ft__legal-inner {
	max-width: var(--he-container);
	margin-inline: auto;
	padding: 24px clamp(20px, 5vw, 48px) 30px;
	display: flex !important;
	flex-direction: row !important;
	flex-wrap: wrap !important;
	align-items: center !important;
	justify-content: space-between !important;
	gap: 12px 22px !important;
	width: 100%;
	/*
	 * The row's own type/colour is inherited by ONE child that cannot bind it:
	 * the `[che_year]` copyright, which is a Shortcode widget and has no
	 * typography or colour control at all. Reported rather than worked around —
	 * the alternative is a heading widget with the year baked in at build time,
	 * which is quietly wrong every 1 January.
	 */
	font-family: "Mulish", sans-serif;
	font-size: 12.5px;
	color: #ffffff;
	opacity: .66;
}

.he-redesign .he-ft__legal-inner > .e-con-inner {
	display: contents;
}

/*
 * Note 60 again, in the one place it was missed. `.he-ft__legal-links` is a
 * `content_width: full` container, and Elementor gives those `width: 100%` plus
 * `flex-grow: 1` — so this row claimed the whole line inside its
 * `space-between` parent and the copyright wrapped above it. Measured: links
 * 1104px wide in a 1104px band, copyright at y+0, links at y+28. The design
 * (:1847) is a `<span style="display:flex;gap:20px;flex-wrap:wrap">` that hugs
 * its content, on ONE line with the copyright. Skill rules 6/7/8: every one of
 * these needs !important, and `min-width: 0` keeps the long credit line from
 * refusing to shrink and pushing the copyright off the band.
 */
.he-redesign .he-ft__legal-links {
	display: flex !important;
	flex-direction: row !important;
	flex-wrap: wrap !important;
	gap: 20px !important;
	align-items: center !important;
	width: auto !important;
	flex-grow: 0 !important;
	flex-shrink: 1 !important;
	flex-basis: auto !important;
	min-width: 0 !important;
}

/* Legal links and the credit bind `che_legal` / che_white / che_green_bright.
   `.he-ft__copyright` is the Shortcode widget — see the note above. */
.he-redesign .he-ft__copyright {
	font-size: 12.5px;
	color: #ffffff;
}

@media (max-width: 560px) {
	.he-redesign .he-ft__legal-inner {
		justify-content: flex-start !important;
	}
}

@media (prefers-reduced-motion: reduce) {
	.he-redesign .he-mega.he-mega--open {
		animation: none !important;
	}
}

/* ==========================================================================
   6. SINGLE PRODUCT  (design "Home Envy Redesign.dc.html" :589-767)

   Layout for the redesign product template built by
   wp-content/che-build/build-product-template.php. Section 7 below reskins the
   configurator that sits inside it.
   ========================================================================== */

/* --- Breadcrumbs (:592-596) --------------------------------------------- */

.he-redesign .he-pdp__crumbs {
	max-width: var(--he-container);
	margin-inline: auto;
	padding: 22px clamp(20px, 5vw, 48px) 6px;
	width: 100%;
}

/*
 * Type and both colours are BOUND on the breadcrumb widget (`che_crumb` /
 * `che_text_crumb`) in build-product-template.php and build-product-archive.php.
 * The literal 13px / 600 / #857c70 that used to live here was a CSS copy of kit
 * values, and a CSS copy silently wins over the kit while the panel claims
 * otherwise. Only the margin reset is left.
 */
.he-redesign .he-crumbs .woocommerce-breadcrumb {
	margin: 0;
}

/*
 * :122-123 — one scrollable line at phone, never wrapping into the title.
 *
 * THREE elements, because the build draws the trail three different ways and
 * only one of them was already nowrap: `.he-crumbs` is the WooCommerce
 * breadcrumb on the PDP and the product archive, `.he-crumbs__bar .he-crumbs`
 * is the collection landings' row of heading widgets (this one was
 * `flex-wrap: wrap`), and `.he-archive__crumbs` / `.he-pdp__crumbbar` are the
 * containers that hold them. Measured at 380 the trails happen to fit on one
 * line today, so this changes nothing visible — it is the design's own guard
 * against the day a deeper category makes one too long, and it matters more now
 * that note 112's fix stops those rows wrapping.
 *
 * `overflow-x: auto` and not `hidden`: the design scrolls the trail rather than
 * truncating it, so a long tail stays reachable by touch.
 */
@media (max-width: 560px) {
	.he-redesign .he-crumbs,
	/* The single-post trail is an e-con whose flex row is the INNER wrapper,
	 * so the guard has to land there too or that shape wraps instead of
	 * scrolling. */
	.he-redesign .he-crumbs > .e-con-inner,
	.he-redesign .he-crumbs__bar .he-crumbs,
	.he-redesign .he-crumbs__bar .he-crumbs > .e-con-inner,
	.he-redesign .he-crumbs .woocommerce-breadcrumb {
		/* Containers auto-stack to column at the mobile tier, which turned
		 * these trails into one crumb per line; the design scrolls one row. */
		flex-direction: row !important;
		flex-wrap: nowrap !important;
		white-space: nowrap;
		overflow-x: auto;
		-webkit-overflow-scrolling: touch;
		padding-bottom: 2px;
	}

	.he-redesign .he-crumbs::-webkit-scrollbar,
	.he-redesign .he-crumbs__bar .he-crumbs::-webkit-scrollbar {
		display: none;
	}
}

/* --- Hero (:598-655) ----------------------------------------------------- */

/*
 * NOTHING HERE LAYS THE HERO OUT ANY MORE.
 *
 * `repeat(auto-fit, minmax(320px,1fr))`, the `clamp(28px,4vw,56px)` gap and
 * `align-items:start` are native grid-container settings on the band's inner
 * (build-product-template.php). This block used to declare them in CSS with the
 * `> .e-con-inner{display:contents}` unwrap, and the unwrap destroyed the box
 * carrying `--container-max-width` — which is why the hero was the one band on
 * the page that did not cap at 1200px (project notes §54, audit #12).
 */

.he-redesign .he-pdp__gallery,
.he-redesign .he-pdp__info {
	min-width: 0 !important; /* skill rule 7 */
}

/* WooCommerce gallery: square main image, 84px thumbnails (:603-612). */
.he-redesign .he-pdp__images .woocommerce-product-gallery__image img {
	width: 100%;
	height: auto;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	display: block;
	background: var(--he-white);
	border: 1px solid var(--he-border);
}

.he-redesign .he-pdp__images .flex-control-thumbs {
	display: flex !important;
	flex-wrap: wrap;
	gap: 12px;
	margin: 12px 0 0;
	padding: 0;
	list-style: none;
}

/*
 * `!important` on the thumbnail box, because WooCommerce's
 * `.woocommerce div.product div.images .flex-control-thumbs li{width:25%;float:left}`
 * is (0,3,2) and outranks anything this file can write with class selectors
 * alone. Without it the thumbs are 25% of whatever the gallery column happens
 * to be — which lands on 84px at desktop BY COINCIDENCE (the column is ~336px)
 * and 113px at 500px, against the design's 84 (:607) and 66 (:127). The rule
 * read correctly and had never applied at any width.
 */
.he-redesign .he-pdp__images .flex-control-thumbs li {
	width: 84px !important;
	margin: 0;
	float: none !important;
}

.he-redesign .he-pdp__images .flex-control-thumbs img {
	width: 84px;
	height: 84px;
	object-fit: cover;
	display: block;
	border: 2px solid var(--he-border);
	opacity: 1;
}

/* :126-127 — 66px thumbs on a 10px gap at phone. */
@media (max-width: 560px) {
	.he-redesign .he-pdp__images .flex-control-thumbs {
		gap: 10px;
	}

	.he-redesign .he-pdp__images .flex-control-thumbs li {
		width: 66px !important;
	}

	.he-redesign .he-pdp__images .flex-control-thumbs img {
		width: 66px;
		height: 66px;
	}
}

.he-redesign .he-pdp__images .flex-control-thumbs img.flex-active {
	border-color: var(--he-green);
}

/*
 * Title (:617).
 *
 * NOTHING BUT THE MARGIN. The H1's typography is bound to the kit's
 * `che_h1_product` global and its colour to `che_text_strong`, both on the
 * widget in build-product-template.php — so both stay client-editable.
 *
 * (An earlier version of this comment said the widget "still binds `che_h1` and
 * must be re-bound when this template is rebuilt". That was already done by the
 * time it was read; the note is corrected rather than deleted, because a stale
 * TODO in a comment costs the next person the same look-up.)
 *
 * `text-transform` is deliberately absent and no longer needs working around:
 * kit 27618 states `text-transform: none` on all six heading levels, verified
 * absent of any uppercase rule in post-27618.css.
 */
.he-redesign .he-pdp__title .elementor-heading-title {
	margin: 0;
}

.he-redesign .he-pdp__cats .elementor-heading-title a {
	color: inherit;
	text-decoration: none;
}

/*
 * Meta strip (:617-619). Direction, wrap, alignment, the `10px 26px` gap and the
 * 16px top margin are native settings on the container now — this block only
 * carries the separator, which is a pseudo-element and has no control.
 */

.he-redesign .he-pdp__metaitem .elementor-heading-title {
	/* :617 — 14px/600. The COLOUR is bound to `che_text_note` on the widgets. */
	font-family: "Mulish", sans-serif;
	font-size: 14px;
	font-weight: 600;
}

/*
 * THE SEPARATOR HAS TO SHARE A LINE BOX WITH THE TEXT.
 *
 * `::before` on the widget WRAPPER is an inline box whose only sibling is
 * `.elementor-widget-container`, a block. CSS therefore wraps the middot in an
 * anonymous block ABOVE the text instead of beside it — the middot got its own
 * line and the meta items ended up flush against each other (audit #13). Nothing
 * about the declaration looked wrong; the box tree was.
 *
 * Making the wrapper a flex row puts the pseudo and the container side by side
 * as flex items. The 26px here is the same value as the container's own column
 * gap, which is what reproduces the design's `<span>·</span>` sitting as its own
 * flex item with 26px on each side (:617-618).
 */
.he-redesign .he-pdp__meta .elementor-widget-heading + .elementor-widget-heading {
	display: flex;
	align-items: center;
	gap: 26px;
}

.he-redesign .he-pdp__meta .elementor-widget-heading + .elementor-widget-heading::before {
	content: "·";
	/* :618 — `che_separator` in the kit now, not a literal. */
	color: var(--e-global-color-che_separator);
}

/*
 * The SKU chip renders only when the product has one. No product on this site
 * has a SKU today (0 of 883), and the heading widget returns before printing a
 * title when its dynamic tag resolves empty (heading.php:435) — leaving an empty
 * wrapper that would still hold a flex slot and drag a separator middot with it.
 */
.he-redesign .he-pdp__meta .elementor-widget-heading:not(:has(.elementor-heading-title)) {
	display: none !important;
}

/*
 * The client-review pass removed the two literal "Solid Canadian hardwood" /
 * "Built to order" chips, leaving the SKU chip as the meta strip's only
 * possible content — and it is empty on all 883 products today (0 SKUs, see
 * above). Without this rule the container's own native 16px top margin (a
 * container setting, not a child's) would survive even when every child is
 * display:none, leaving a dangling gap under the title. Collapses the whole
 * strip, margin included, until a product actually has a SKU.
 */
.he-redesign .he-pdp__meta:not(:has(.elementor-heading-title)) {
	display: none !important;
}

/*
 * The ink panel (:621-634) holds the product's WooCommerce short description,
 * and NOTHING here assumes what is in it.
 *
 * The design's example content is an overline and three ticked lines. The
 * catalogue's content is not that shape and never will be: prose of any length,
 * dimension lists written as loose lines, sale prices in black `<h2>`s, empty
 * `<h2>`s, links, `<del>`, and 38 excerpts with Elementor markup stored inside
 * them. Every rule below therefore keys on an element that is actually in the
 * markup — `li` inside a real list, `table`, `a` — and everything else lands as
 * readable body copy on the ink.
 *
 * THE TICKS BELONG TO REAL LISTS ONLY. They used to be given to the paragraphs
 * between the first `<strong>` and the first list, which ticked four dimension
 * rows on `laguna-dresser` and nothing at all on the 57 products with no
 * top-level `<strong>`. `che_tag_short_description_zones()` in
 * includes/redesign.php marks the lists (`.he-blurb__list`), at any depth.
 */
.he-redesign .he-pdp__bullets {
	position: relative;
	margin: 26px 0 !important;
	padding: 24px 26px !important;
	overflow: hidden;
}

.he-redesign .he-pdp__blurb,
.he-redesign .he-pdp__blurb p,
.he-redesign .he-pdp__blurb li,
.he-redesign .he-pdp__blurb div,
.he-redesign .he-pdp__blurb td,
.he-redesign .he-pdp__blurb th {
	font-family: "Mulish", sans-serif;
	font-size: 15.5px;
	line-height: 1.6;
	color: #ffffff;
}

.he-redesign .he-pdp__blurb > :first-child,
.he-redesign .he-pdp__blurb p:first-child {
	margin-top: 0;
}

.he-redesign .he-pdp__blurb > :last-child,
.he-redesign .he-pdp__blurb p:last-child,
.he-redesign .he-pdp__blurb ul:last-child {
	margin-bottom: 0;
}

/*
 * An empty element still occupies its margins. Four products open their
 * excerpt with four `<h2></h2>` in a row — 100px of nothing above the price.
 */
.he-redesign .he-pdp__blurb p:empty,
.he-redesign .he-pdp__blurb div:empty,
.he-redesign .he-pdp__blurb h1:empty,
.he-redesign .he-pdp__blurb h2:empty,
.he-redesign .he-pdp__blurb h3:empty,
.he-redesign .he-pdp__blurb h4:empty,
.he-redesign .he-pdp__blurb h5:empty,
.he-redesign .he-pdp__blurb h6:empty {
	display: none;
}

/*
 * A heading the client wrote stays a heading — the kit's own heading colour is
 * dark ink, which is invisible here, so only the colour and the scale change.
 */
.he-redesign .he-pdp__blurb h1,
.he-redesign .he-pdp__blurb h2,
.he-redesign .he-pdp__blurb h3,
.he-redesign .he-pdp__blurb h4,
.he-redesign .he-pdp__blurb h5,
.he-redesign .he-pdp__blurb h6 {
	font-family: "Archivo", sans-serif;
	font-weight: 600;
	font-size: 18px;
	line-height: 1.3;
	color: #ffffff;
	margin: 16px 0 8px;
}

/*
 * An inline `color:` a stylesheet cannot otherwise reach (§69). 20 clearance
 * products store `color: #000000` on the "Reg: $2220" line — black on #241f1c.
 * `che_tag_short_description_zones()` adds the class by LUMINANCE, so the
 * `#ff0000` sale price beside it keeps its colour.
 */
.he-redesign .he-pdp__blurb .he-blurb__ink {
	color: #ffffff !important;
}

/* The design's green overline (:43): a `<strong>` that is a line of its own. */
.he-redesign .he-pdp__blurb p > strong:only-child,
.he-redesign .he-pdp__blurb h1 > strong:only-child,
.he-redesign .he-pdp__blurb h2 > strong:only-child,
.he-redesign .he-pdp__blurb h3 > strong:only-child {
	display: inline-block;
	font-family: "Archivo", sans-serif;
	font-weight: 600;
	font-size: 14px;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--he-green-bright);
}

/*
 * THE GREEN TICKS: every `<li>` of a real list, and nothing else.
 */
.he-redesign .he-pdp__blurb .he-blurb__list {
	list-style: none;
	margin: 16px 0 0;
	padding: 0;
}

.he-redesign .he-pdp__blurb .he-blurb__list > li {
	display: flex;
	align-items: center;
	gap: 12px;
	margin: 10px 0 0;
}

.he-redesign .he-pdp__blurb .he-blurb__list > li::before {
	content: "";
	flex: 0 0 auto;
	width: 26px;
	height: 26px;
	background-color: var(--he-green);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 24 24' fill='none' stroke='%2317181a' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: center;
}

/* A nested list is still a list: it keeps its ticks and steps in. */
.he-redesign .he-pdp__blurb .he-blurb__list .he-blurb__list {
	margin-left: 38px;
}

/* A link the client wrote (28 products end with their brand's link). */
.he-redesign .he-pdp__blurb a {
	color: var(--he-green-bright);
	text-decoration: underline;
	text-underline-offset: 2px;
}

/*
 * A stored table keeps every row and scrolls inside the panel rather than
 * bursting it. `display: block` is what makes the overflow possible on a table.
 */
.he-redesign .he-pdp__blurb .he-blurb__table {
	display: block;
	max-width: 100%;
	overflow-x: auto;
	border-collapse: collapse;
	margin: 16px 0 0;
}

.he-redesign .he-pdp__blurb .he-blurb__table td,
.he-redesign .he-pdp__blurb .he-blurb__table th {
	padding: 8px 14px;
	border: 1px solid #3d352e;
	text-align: left;
	vertical-align: top;
}

.he-redesign .he-pdp__blurb .he-blurb__table th {
	font-family: "Archivo", sans-serif;
	font-weight: 600;
	white-space: nowrap;
}

/* An image inside the copy never widens the panel. */
.he-redesign .he-pdp__blurb img {
	max-width: 100%;
	height: auto;
}

/* Hero CTA (:650-652). */
.he-redesign .he-pdp__cta .elementor-button {
	height: 54px;
	padding: 0 30px;
	font-size: 16px;
}

/* --- Configurator band (:657-741) --------------------------------------- */

/*
 * The band's 940px measure is `boxed_width: 844px` on the container now — 940
 * minus its two 48px gutters, because `--content-width` caps the inner INSIDE
 * the padding (project notes §55). It used to be
 * `max-width: var(--he-container-form)` here, which is a stylesheet copy of a
 * container's own width: not editable from the panel, and it loads after the
 * per-element CSS so it wins whatever the control says (§52).
 *
 * Both section heads' margins (44px :654, 30px :746) are native too, via
 * che_section_head()'s own margin argument.
 */
.he-redesign #he-customize {
	scroll-margin-top: 120px;
}

/*
 * :643 the lede's own 38em measure. The shared centred head sets 640px, and at
 * this element's 16px that is 40em — so the two tie on specificity and the
 * stylesheet order decides. `.he-sectionhead` in the selector breaks the tie
 * deliberately rather than by luck.
 */
.he-redesign .he-sectionhead.he-pdp__customize-head .he-lede {
	max-width: 38em;
	margin-inline: auto;
}

/* --- Photographs on the rebuilt pages ------------------------------------ */

/*
 * WHY THESE ARE SELF-CONTAINED RULES AND NOT `.he-split__media img`.
 *
 * The shared split grammar puts `aspect-ratio` on the widget WRAPPER and
 * `height: 100%` on the `img`. Between them sits `.elementor-widget-container`,
 * which has no definite height — so the image's `height: 100%` has nothing to
 * resolve against, and inside the wrapper's `overflow: hidden` the photograph
 * renders as an empty box. That is what `/furniture/` shipped: a 520x390 media
 * column with a real `<img>` in the DOM and nothing visible in it.
 *
 * `.he-archive__hero img` on the category view has always been correct because
 * it states `width` / `aspect-ratio` / `object-fit` on the IMAGE itself, with no
 * dependency on an ancestor's height. These three follow that shape.
 *
 * The wrapper's own aspect-ratio is released for these classes, or its 4/3 box
 * clips a 3/2 image — the same `aspect-ratio: auto` release the pricing and
 * promo splits already use.
 *
 * The shared rule is NOT edited here: `.he-split__media` is the band grammar and
 * belongs to the fidelity pass. It is reported instead.
 */
.he-redesign .he-hub__hero img,
.he-redesign .he-hub__img img,
.he-redesign .he-brand__img img,
.he-redesign .he-legacy__img img {
	width: 100%;
	height: auto;
	aspect-ratio: 3 / 2;   /* :1613 — the category intro's photograph */
	object-fit: cover;
	display: block;
	background: var(--he-image-well);
}

/* The full-width gallery band runs wider than a split column. */
.he-redesign .he-brand__img--wide img {
	aspect-ratio: 21 / 9;
}

/* --- The per-group editorial bands (:1666-1694) -------------------------- */

/*
 * Almost everything on these bands is a control: the head row's direction,
 * alignment, wrap, 20px gap and 28px bottom margin; the copy block's 44em
 * measure; the h2 / tagline / copy type and colour; the CTA's 46px box. What is
 * left here has no control in Elementor 4.2.2.
 *
 * The bands render only on a category whose sub-terms carry editorial fields —
 * see includes/category-groups.php. Nothing below assumes they are present.
 */

/* :1674 `white-space:nowrap` — the CTA must not wrap mid-label when the head
   row is tight, and a button widget has no white-space control. */
.he-redesign .he-group__cta .elementor-button {
	white-space: nowrap;
}

/* The CTA is the head row's second flex item and must not stretch to match the
   copy block's height; `align-items: flex-end` on the row positions it, but a
   widget wrapper still grows (skill rule 6). */
.he-redesign .he-group__head > .he-group__cta {
	flex: 0 0 auto !important;
}

/* skill rule 7 — the copy block is a long-text flex child and would otherwise
   refuse to shrink below its content, pushing the CTA off the row. */
.he-redesign .he-group__copy-block {
	min-width: 0 !important;
}

/* Group copy runs multi-paragraph the same way the archive intro does — same
   14px gap as .he-archive__intro p + p above. */
.he-redesign .he-group__copy p + p {
	margin-top: 14px;
}

/* --- Related products (:743-766) ---------------------------------------- */

/*
 * NO CARD SHELL HERE ANY MORE.
 *
 * This band renders `Product Card — Redesign` (27623), the same card the three
 * archives use and the one the design draws at :748-755. Its background, border,
 * body padding, body gap, title type and green CTA are its own bound controls,
 * so the ~60 lines of shell CSS that used to re-skin the LEGACY card (18487)
 * from outside are gone. They could never have fixed it anyway: 18487's centred
 * title, 70%-wide button and 0px body padding are its own per-element settings.
 */

/* ==========================================================================
   7. THE CONFIGURATOR RESKIN  (design :667-741)

   ///////////////////////////////////////////////////////////////////////////
   READ BEFORE EDITING ANYTHING IN THIS SECTION.
   ///////////////////////////////////////////////////////////////////////////

   `[che_stacked_attribute_selector]` is LIVE dynamic markup (includes/
   functions.productCustomization.php) driven by two scripts with string-literal
   selector contracts. Both break silently — no console error, no visual clue.
   The observable symptom of breaking either one is a submit button that stays
   disabled forever, or a quote email listing the wrong options.

   CONTRACT 1 — product-customizer.js:322
       document.querySelectorAll('.attribute_subtype[style="display: block;"]')
     Matched on the EXACT inline-style string, single space, trailing semicolon.
     The PHP prints that string on top-level groups
     (functions.productCustomization.php:87); the JS reproduces it by assigning
     `.style.display = 'block'` when a parent <select> reveals a nested group.
     => This stylesheet must NEVER set `display` on `.attribute_subtype`.
        A rule of any specificity would reveal every hidden nested group at once
        while the inline-style query keeps counting only the intended ones.
        `.attribute_subtype { display: none }` in style.css is the base state and
        stays exactly as it is.

   CONTRACT 2 — custom-scripts.js:95
       jQuery(stackedCustomizer).find('select:visible,ul:visible')
     The submitted option list is harvested from the VISIBLE selects and ULs.
     jQuery ':visible' is offsetWidth/offsetHeight/getClientRects, so only
     `display: none` (or a display:none ancestor) removes an element from the
     harvest — `visibility: hidden`, `opacity: 0` and `height: 0` do NOT.
     => `display: grid` / `flex` / `block` on `ul.attribute_subtype_options` is
        safe and is what this section uses. `display: contents` is NOT: it zeroes
        the element's own boxes, so the UL drops out of the harvest and its
        selection silently never reaches the quote email.
     => Never hide a group with `visibility`/`opacity`/`height: 0`; it would stay
        in the harvest and submit an option the customer never saw.

   CONTRACT 3 — custom-scripts.js:327 / :114
       subtype.querySelector('li.selected') and jQuery(ul).find('.selected')
     The `.selected` class and the li's data-id / data-name / data-attribute-group
     attributes are the payload. This section restyles `.selected`; it never
     stops rendering it, and it adds no element between the UL and its LIs.

   Everything below is therefore paint only: background, border, colour,
   typography, spacing, grid-template. No markup was changed and no inline style
   is written or overridden.
   ========================================================================== */

.he-redesign .che_stacked_customizer {
	padding: 0;
}

/*
 * The section head above the configurator is real Elementor widgets, so the
 * shortcode's own <h2 class="widget_title"> would print "Customize your
 * furniture" a second time. De-duplication, not content removal: the words live
 * on as an editable heading widget. Nothing the customizer's JS reads is
 * affected — .widget_title is neither a subtype, a select nor a ul.
 */
.he-redesign .che_stacked_customizer .widget_title {
	display: none;
}

.he-redesign .attribute_group_wrapper {
	counter-reset: he-step;
}

/* --- Step heading: the nested case's <label> (:698-704) ------------------ */

.he-redesign .attribute_step > .attribute_step__fields > label,
.he-redesign .attribute_group_wrapper > label {
	display: flex !important;
	align-items: center;
	gap: 14px;
	margin: 34px 0 14px !important;
	padding: 0 !important;
	font-family: "Archivo", sans-serif;
	font-size: 22px !important;
	font-weight: 600 !important;
	line-height: 1.2;
	letter-spacing: 0;
	text-transform: none;
	color: var(--he-text-strong) !important;
}

/* The title is the card's first row now, so it never needs a top margin. */
.he-redesign .attribute_step > .attribute_step__fields > label,
.he-redesign .attribute_group_wrapper > label:first-child {
	margin-top: 0 !important;
}

/*
 * The label is the STEP TITLE and the select sits under it, so the title has to
 * break the grid row rather than share a cell with the control.
 *
 * The title is a grid ITEM here, so the grid's own 20px row-gap already sits
 * between it and the select — a margin on top of that stacks (measured 44px on
 * every step card, browser pass 2026-08-21). The design closes the header row
 * at 22px (:667-681), so the margin carries only the 2px remainder.
 */
.he-redesign .attribute_step > .attribute_step__fields > label {
	grid-column: 1 / -1;
	margin-bottom: 2px !important;
}

/*
 * Step numbers come from a CSS counter rather than from markup: the number of
 * groups is per-product (2 to 14 on the site's real data) and nothing in the
 * PHP emits an index.
 */
/*
 * `:not(.attribute_step__note)` is load-bearing, not tidiness: the counter
 * increments in this rule, so a second direct <p> child — which the sub-note is
 * — would take the next step number and print its own green badge.
 */
.he-redesign .attribute_step > .attribute_step__fields > label::before,
.he-redesign .attribute_group_wrapper > label::before,
.he-redesign .attribute_step > .attribute_subtype > p:not(.attribute_step__note)::before,
.he-redesign .attribute_group_wrapper > .attribute_subtype > p:not(.attribute_step__note)::before {
	counter-increment: he-step;
	content: counter(he-step);
	flex: 0 0 auto;
	width: 38px;
	height: 38px;
	background: var(--he-green);
	color: var(--he-text-strong);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-family: "Archivo", sans-serif;
	font-size: 17px;
	font-weight: 600;
	line-height: 1;
}

/* --- Step heading: the single-attribute case's <p> ----------------------- */

.he-redesign .attribute_step > .attribute_subtype > p:not(.attribute_step__note),
.he-redesign .attribute_group_wrapper > .attribute_subtype > p:not(.attribute_step__note) {
	display: flex !important;
	align-items: center;
	gap: 14px;
	margin: 0 0 22px !important;
	padding: 0 !important;
	font-family: "Archivo", sans-serif;
	font-size: 22px !important;
	font-weight: 600 !important;
	line-height: 1.2;
	text-transform: none;
	color: var(--he-text-strong) !important;
}

/* The step sub-note (:664, :678) — 13.5px, muted, under the step title. */
.he-redesign .attribute_step__note {
	/* :652, :681 — `margin:4px 0 0` under the step title. The note renders only
	   on FLAT groups, whose <p> title carries a 22px bottom margin (not 24 —
	   the old comment's premise); the collapsed 22 + (-18) lands the note 4px
	   below the title, measured 2026-08-21. */
	margin: -18px 0 22px !important;
	padding: 0 !important;
	font-family: "Mulish", sans-serif;
	font-size: 13.5px !important;
	font-weight: 400 !important;
	line-height: 1.5;
	text-transform: none;
	color: var(--he-text-softer) !important;
}

/* Sub-group heading inside a nested step — no number, smaller. */
.he-redesign .attribute_subtype_wrapper .attribute_subtype > p {
	margin: 0 0 14px !important;
	padding: 0 !important;
	font-family: "Archivo", sans-serif;
	font-size: 17px !important;
	font-weight: 600 !important;
	line-height: 1.25;
	text-transform: none;
	color: var(--he-text-strong) !important;
}

.he-redesign .attribute_subtype p .attribute-description-link svg {
	color: var(--he-text-softer);
	width: 20px;
	height: 20px;
}

/* --- The step card (:667-681) -------------------------------------------- */

/*
 * ONE card per step, and the card is `.attribute_step` — the wrapper
 * includes/product-customization.php now emits around each top-level group.
 *
 * It used to be the `.attribute_subtype` / `.attribute_subtype_wrapper` boxes,
 * which meant the step's numbered title and its dropdown sat OUTSIDE the card,
 * floating on the band. That was the divergence on 838 of 883 products; the
 * design draws badge, title, selects and swatches inside one border.
 *
 * NOTE THE CONTINUED ABSENCE OF `display` ON `.attribute_subtype`. It is
 * CONTRACT 1: its visibility is owned by style.css's base `display: none` plus
 * the inline `display: block;` string the PHP and the JS write. The card moving
 * to an ancestor is precisely what lets this file paint a box without going
 * near that property.
 */
.he-redesign .attribute_step {
	background: var(--he-white);
	border: 1px solid var(--he-border);
	padding: clamp(24px, 3vw, 34px);
	margin: 0 0 20px;
	transition: border-color .2s;
}

.he-redesign .attribute_step:hover {
	border-color: var(--he-green);
}

/* Sub-groups inside a nested step are separated by a rule, not by a nested box. */
.he-redesign .attribute_subtype_wrapper .attribute_subtype + .attribute_subtype {
	margin-top: 26px;
	padding-top: 26px;
	border-top: 1px solid var(--he-border);
}

/* --- The select row (:655-658) ------------------------------------------ */

/*
 * The design lays a step's selects out as a grid rather than stacking them, so
 * a step that ever carries two (the design's own "Wood species" + "Table size")
 * sits them side by side. Today every step in this catalogue has exactly one,
 * and auto-fit degrades to a single full-width column — which is also why the
 * old `max-width: 380px` is gone: it made the control narrower than its card
 * for no reason in the design.
 */
.he-redesign .attribute_step__fields {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
	gap: 20px;
	margin-bottom: 24px;
}

/* --- Selects (:677-678) -------------------------------------------------- */

/*
 * 46px, `0 40px 0 14px`, 1.5px border, 15px — read from the design system's own
 * Select component (`_ds/…/_ds_bundle.js`, components/forms/Select.jsx), which
 * is what the design's `<x-import … Select>` renders. The 72px in the design
 * markup is `hint-size`, i.e. label (14) + gap (6) + control (46) — NOT the
 * control's height. Radius stays 0: this colourway is square throughout.
 */
.he-redesign .attribute_step select,
.he-redesign .che_stacked_customizer select {
	display: block;
	width: 100%;
	height: 46px;
	padding: 0 40px 0 14px;
	background-color: var(--he-white);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b6357' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 12px center;
	border: 1.5px solid var(--he-border-input);
	border-radius: 0;
	appearance: none;
	-webkit-appearance: none;
	font-family: "Mulish", sans-serif;
	font-size: 15px;
	font-weight: 600;
	color: var(--he-text-body);
	cursor: pointer;
}

.he-redesign .che_stacked_customizer select:focus {
	border-color: var(--he-green);
	outline: 2px solid rgba(118, 187, 0, .25);
	outline-offset: 0;
}

/* --- Swatch grid (:682-92) ---------------------------------------------- */

/*
 * `display: grid` is deliberate and safe under CONTRACT 2 — the UL keeps real
 * boxes, so jQuery ':visible' still finds it and the selection still reaches the
 * quote email. `display: contents` here would break the submit silently.
 */
/*
 * The design has two swatch measures: `minmax(104px,1fr)` for the stain swatches
 * nested under a wood choice (:660) and `minmax(120px,1fr)` for the flat texture
 * step (:684). Our two shapes map onto them exactly — a sub-grouped list is the
 * stain case, a flat top-level group is the texture case — so both values are
 * used where the design uses them rather than one being picked for everything.
 */
.he-redesign .attribute_subtype .attribute_subtype_options {
	display: grid !important;
	grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
	flex-direction: unset;
	flex-wrap: unset;
	gap: 14px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.he-redesign .attribute_subtype_wrapper .attribute_subtype .attribute_subtype_options {
	grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
}

.he-redesign .attribute_subtype .attribute_subtype_options li {
	position: relative;
	display: flex !important;
	flex-direction: column !important;
	align-items: stretch !important;
	gap: 8px;
	width: auto;
	padding: 0;
	margin: 0;
	border: none;
	border-radius: 0;
	background: transparent;
	text-align: center;
	cursor: pointer;
}

.he-redesign .attribute_subtype .attribute_subtype_options li:hover,
.he-redesign .attribute_subtype .attribute_subtype_options li.selected {
	background: transparent;
	border: none;
}

.he-redesign .attribute_subtype .attribute_subtype_options li img,
.he-redesign .attribute_subtype .attribute_subtype_options li picture {
	width: 100%;
	height: auto;
	aspect-ratio: 1 / 1;
	flex: 0 0 auto;
	object-fit: cover;
	display: block;
	border: 1px solid var(--he-border);
	border-radius: 0;
}

.he-redesign .attribute_subtype .attribute_subtype_options li:hover img {
	border-color: var(--he-border-outline);
}

/*
 * The selected ring (:87 of the design's swatch block): 3px green with a 2px
 * white inset. `outline` rather than a second box-shadow so it paints reliably
 * over a replaced element.
 */
.he-redesign .attribute_subtype .attribute_subtype_options li.selected img {
	border: 3px solid var(--he-green);
	outline: 2px solid var(--he-white);
	outline-offset: -2px;
}

.he-redesign .attribute_subtype .attribute_subtype_options li.selected::after {
	content: "";
	position: absolute;
	top: 6px;
	right: 6px;
	width: 20px;
	height: 20px;
	background-color: var(--he-green);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2317181a' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: center;
	pointer-events: none;
}

.he-redesign .attribute_subtype .attribute_subtype_options li span {
	/* :690 — the kit's `che_swatch_label`. Legacy markup, so it references the
	   kit's variables rather than binding them. */
	font-family: var( --e-global-typography-che_swatch_label-font-family ), "Mulish", sans-serif;
	font-size: var( --e-global-typography-che_swatch_label-font-size );
	font-weight: var( --e-global-typography-che_swatch_label-font-weight );
	line-height: var( --e-global-typography-che_swatch_label-line-height );
	color: var(--e-global-color-che_text_body);
}

/* --- The quote panel (:718-741) ----------------------------------------- */

.he-redesign .che_stacked_customizer .contact-fields {
	position: relative;
	/* :676 — the ink card follows the last step card at that card's own 20px
	   bottom margin, not at a larger gap of its own. */
	margin-top: 20px;
	padding: clamp(28px, 3.4vw, 40px);
	background: var(--he-ink);
	color: #f3ede3;
	overflow: hidden;
}

/* The band hairline, as a pseudo-element like every other one in this build. */
.he-redesign .che_stacked_customizer .contact-fields::before {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: 1px;
	background: linear-gradient(90deg, transparent, #76bb00, #96d42b, #76bb00, transparent);
	pointer-events: none;
}

.he-redesign .che_stacked_customizer .contact-fields .contact-intro {
	margin: 0 0 24px;
}

/*
 * The size/family/weight here override style.css's own `.contact-intro h2`
 * rule (21px Montserrat-ish), which is legacy customizer CSS, not the shared
 * redesign grammar — so they are reskin work and stay.
 *
 * `text-transform` is deliberately NOT set, and does not need to be: the 2026
 * kit sets `text-transform: none` on h1-h6, so "Almost There!" renders in
 * sentence case from the kit. The old kit's uppercase leak, which this comment
 * used to describe, died with the old kit.
 */
.he-redesign .che_stacked_customizer .contact-fields .contact-intro h2 {
	margin: 0;
	font-family: "Archivo", sans-serif;
	font-weight: 600;
	font-size: clamp(24px, 3vw, 32px);
	/* :712 sets no line-height; the kit's own is the design's value. */
	color: #ffffff !important;
}

.he-redesign .che_stacked_customizer .contact-fields .contact-intro p {
	margin: 10px 0 0;
	font-family: "Mulish", sans-serif;
	font-size: 15.5px;
	line-height: 1.6;
	color: #ffffff;
	max-width: 38em;
}

/* --- The selection recap (:715-720) ------------------------------------- */

/*
 * Filled by renderQuoteRecap() in product-customizer.js from the same elements
 * the submit harvest reads. Hidden via the `hidden` ATTRIBUTE when there is
 * nothing chosen yet, not via a CSS `display` rule — the JS owns that state and
 * a stylesheet rule here would fight it.
 */
.he-redesign .che_stacked_customizer .quote-recap {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
	/*
	 * The label row and the value row are the PARENT's rows now (see
	 * `.quote-recap__item` below), so a `row-gap` here would open up between the
	 * label and its own value, not between bands. Both vertical gaps are carried
	 * by margins instead: 5px under the label, 18px under the value.
	 */
	column-gap: 18px;
	row-gap: 0;
	/*
	 * 6px, not 24px: the last value's own 18px bottom margin is inside the grid,
	 * so the gap under the strip is 18 + 6 and the design's 24px is unchanged.
	 */
	margin: 0 0 6px;
	padding-top: 20px;
	border-top: 1px solid #3d352e;
}

.he-redesign .che_stacked_customizer .quote-recap[hidden] {
	display: none;
}

/*
 * Each cell used to be a plain block that stacked its own label over its own
 * value, so a label that wrapped to two lines pushed down ONLY that cell's
 * value and the row lost its shared baseline. "Woods & Stains - Brushwork
 * Maple" wraps at 1320 and long group names are ordinary in this catalogue, so
 * that is the common case, not an edge one.
 *
 * `grid-template-rows: subgrid` puts the label and the value in the PARENT's
 * rows: every label in a band shares one auto row sized by the tallest label,
 * and every value starts at the top of the next one, at any label height and at
 * any column count. It is markup-free — renderQuoteRecap() still emits the same
 * div/span pair and the harvest still sees no <ul> and no <select>.
 *
 * Where subgrid is unsupported the declaration is dropped and the item stays a
 * one-column grid: it degrades to exactly the per-cell stacking it replaces,
 * with the same spacing, not to a collapsed layout. `align-content: start` is
 * what makes that degradation exact — without it the dropped-subgrid fallback
 * stretches its two rows to fill the stretched cell and the label grows taller
 * than its text. It is ignored in the subgridded axis, so it costs the
 * supported path nothing.
 */
.he-redesign .che_stacked_customizer .quote-recap__item {
	display: grid;
	grid-template-rows: subgrid;
	grid-row: span 2;
	align-content: start;
}

.he-redesign .che_stacked_customizer .quote-recap__label {
	display: block;
	margin-bottom: 5px;
	/*
	 * :716 — this is the kit's `che_label_micro` step. The recap is built by JS
	 * into markup no widget owns, so it cannot BIND the global; referencing the
	 * kit's own variables is the nearest equivalent and keeps the client's edit
	 * working.
	 */
	font-family: var( --e-global-typography-che_label_micro-font-family ), "Mulish", sans-serif;
	font-size: var( --e-global-typography-che_label_micro-font-size );
	font-weight: var( --e-global-typography-che_label_micro-font-weight );
	letter-spacing: var( --e-global-typography-che_label_micro-letter-spacing );
	text-transform: uppercase;
	color: var(--e-global-color-che_green_bright);
}

.he-redesign .che_stacked_customizer .quote-recap__value {
	display: block;
	/*
	 * The band separation, carried here rather than by the grid's `row-gap`,
	 * which now falls between a label and its own value. It sizes the value row,
	 * so it also supplies 18 of the 24px under the whole strip.
	 */
	margin-bottom: 18px;
	font-family: "Mulish", sans-serif;
	font-size: 15px;
	font-weight: 600;
	color: #ffffff;
}

/* --- The white field panel (:721-733) ----------------------------------- */

/*
 * The design puts the four fields on a white panel INSIDE the ink card, as one
 * auto-fit grid, so Name / Email / Phone share a row and the textarea and the
 * submit span it. The three fixed `.contact-field-row` wrappers this replaces
 * could not express that — they put Phone on a row of its own.
 */
.he-redesign .che_stacked_customizer .contact-field-panel {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
	gap: 16px;
	padding: 24px;
	background: var(--he-white);
}

.he-redesign .che_stacked_customizer .contact-field-panel .contact-details,
.he-redesign .che_stacked_customizer .contact-field-panel .contact-submit {
	grid-column: 1 / -1;
}

.he-redesign .che_stacked_customizer .contact-fields .contact-field {
	margin: 0;
	min-width: 0;
}

/*
 * 14px / 700 / --text-strong with a 6px gap: the design system's own Input and
 * Select label (`_ds/…/_ds_bundle.js`). These labels used to be the green
 * uppercase 12px treatment, which is the RECAP's type — correct there, wrong
 * here, and only distinguishable once the recap actually existed.
 */
.he-redesign .che_stacked_customizer .contact-fields .contact-field label {
	margin: 0 0 6px !important;
	padding: 0 !important;
	font-family: "Mulish", sans-serif;
	font-size: 14px !important;
	font-weight: 700 !important;
	letter-spacing: 0;
	text-transform: none;
	color: var(--he-text-strong) !important;
}

.he-redesign .che_stacked_customizer .contact-fields .contact-field input,
.he-redesign .che_stacked_customizer .contact-fields .contact-field textarea {
	width: 100%;
	padding: 0 14px;
	height: 46px;
	background: var(--he-white);
	border: 1.5px solid var(--he-border-input);
	border-radius: 0;
	font-family: "Mulish", sans-serif;
	font-size: 15px;
	color: var(--he-text-strong);
}

.he-redesign .che_stacked_customizer .contact-fields .contact-field textarea {
	padding: 12px 14px;
	height: auto;
	min-height: 130px;
	line-height: 1.5;
	resize: vertical;
}

.he-redesign .che_stacked_customizer .contact-fields .contact-field input:focus,
.he-redesign .che_stacked_customizer .contact-fields .contact-field textarea:focus {
	border-color: var(--he-green);
	outline: 2px solid rgba(118, 187, 0, .35);
	outline-offset: 0;
}

.he-redesign .che_stacked_customizer button.submit_to_cart {
	width: 100%;
	height: 54px;
	margin-top: 0;
	background: var(--he-green);
	color: var(--he-text-strong);
	border: none;
	border-radius: 0;
	font-family: "Mulish", sans-serif;
	font-weight: 600;
	font-size: 16px;
	cursor: pointer;
}

.he-redesign .che_stacked_customizer button.submit_to_cart:hover {
	background: var(--he-green-hover);
}

/*
 * The disabled state must stay VISIBLY disabled: it is the customer's only
 * feedback that a group is still unanswered, and it is the state CONTRACT 2
 * governs. Opacity only — `display`/`visibility` here would be a contract
 * violation and would also hide the one control the customer needs to find.
 */
.he-redesign .che_stacked_customizer button.submit_to_cart.disabled,
.he-redesign .che_stacked_customizer button.submit_to_cart.disabled:hover {
	background: var(--he-green);
	opacity: .45;
	cursor: not-allowed;
}

/* --- Confirmation (:721-729) -------------------------------------------- */

/*
 * Inline `style="display: none"` on this element is written by the PHP and
 * cleared by jQuery .slideDown() on a successful submit. Paint only — a
 * `display` rule here would either show the thank-you before submission or
 * fight slideDown's inline write.
 */
.he-redesign .che_stacked_customizer_cart_confirmation {
	margin-top: 34px;
	padding: clamp(28px, 3.4vw, 40px);
	background: var(--he-ink);
	color: #ffffff;
	text-align: center;
}

/* :702 — the 64x64 green tick above the heading. */
.he-redesign .che-confirmation__badge {
	width: 64px;
	height: 64px;
	margin: 0 auto 20px;
	background: var(--he-green);
	color: var(--he-text-strong);
	display: flex;
	align-items: center;
	justify-content: center;
}

/* :730, :706 — the two inline arrows this panel and the submit button carry. */
.he-redesign .submit_to_cart__arrow,
.he-redesign .che_stacked_customizer_cart_confirmation .elementor-button-icon {
	display: inline-flex;
	align-items: center;
	margin-left: 9px;
}

.he-redesign button.submit_to_cart {
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

/*
 * :703 — 28px Archivo 600, sentence case, #fff on the ink panel. Replaces the
 * inline `21px / uppercase / var(--e-global-color-primary) !important` that made
 * this heading #241f1c on a #241f1c background.
 */
.he-redesign .che-confirmation__title {
	display: block;
	margin: 0 0 12px;
	padding: 0;
	font-family: "Archivo", sans-serif;
	font-size: 28px;
	font-weight: 600;
	line-height: 1.15;
	text-transform: none;
	color: #ffffff;
}

.he-redesign .che_stacked_customizer_cart_confirmation p {
	font-family: "Mulish", sans-serif;
	font-size: 16px;
	line-height: 1.6;
	color: #ffffff;
}

.he-redesign .che_stacked_customizer_cart_confirmation .elementor-button {
	height: 48px;
	padding: 0 24px;
	background: var(--he-green);
	color: var(--he-text-strong);
	border-radius: 0;
	font-family: "Mulish", sans-serif;
	font-weight: 600;
	font-size: 15px;
	/*
	 * `display` is NOT optional here. The anchor Elementor's own frontend CSS
	 * would make inline-block is only inline in this panel, so `height` and the
	 * vertical padding were dropped and the flex content-wrapper inside it was
	 * laid out as a block above the anchor's own inline background box.
	 */
	display: inline-flex;
	align-items: center;
	justify-content: center;
	vertical-align: middle;
	text-decoration: none;
}

/* --- Phone (design :91-96 rhythm) --------------------------------------- */

@media (max-width: 560px) {
	/*
	 * :104 — `.he-swatch{gap:10px}` at phone. The column formula stays the
	 * build's `auto-fill`, which resolves to the design's 3-up on a phone.
	 *
	 * BOTH selectors, because the nested-attribute case is written one class
	 * deeper (`.attribute_subtype_wrapper .attribute_subtype
	 * .attribute_subtype_options`, 0,4,0) and outranked the single-class form
	 * this block used to carry — so the phone track width never applied on any
	 * nested product and the swatches stayed at their 104px desktop track.
	 */
	.he-redesign .attribute_subtype .attribute_subtype_options,
	.he-redesign .attribute_subtype_wrapper .attribute_subtype .attribute_subtype_options {
		grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
		gap: 10px;
	}

	/* :131 — the swatch caption drops one step at phone. */
	.he-redesign .attribute_subtype .attribute_subtype_options li span {
		font-size: 11.5px;
	}

	/* :128 — `.he-step{padding:20px 18px}`; the desktop clamp bottoms out at 24. */
	.he-redesign .attribute_step {
		padding: 20px 18px;
	}

	/* :129 — `.he-stepnum{width:34px;height:34px;font-size:15px}`. */
	.he-redesign .attribute_step > .attribute_step__fields > label::before,
	.he-redesign .attribute_group_wrapper > label::before,
	.he-redesign .attribute_step > .attribute_subtype > p:not(.attribute_step__note)::before,
	.he-redesign .attribute_group_wrapper > .attribute_subtype > p:not(.attribute_step__note)::before {
		width: 34px;
		height: 34px;
		font-size: 15px;
	}

	.he-redesign .attribute_step > .attribute_step__fields > label,
	.he-redesign .attribute_group_wrapper > label,
	.he-redesign .attribute_step > .attribute_subtype > p:not(.attribute_step__note) {
		font-size: 19px !important;
	}

	.he-redesign .attribute_step > .attribute_step__fields > label {
		margin-bottom: 18px !important;
	}
}

/* ==========================================================================
   8. PRODUCT CARD  (design :834-848 product, :1753-1767 clearance)

   Layout for the loop items built by wp-content/che-build/build-loop-items.php
   ("Product Card — Redesign" and "Clearance Card — Redesign").

   EVERYTHING THE CARD CAN EXPRESS AS A CONTROL IS ALREADY A CONTROL, and this
   block is deliberately only what is left over:

     background, border colour, border width   -> bound to kit globals on the
                                                  containers
     body padding, body gap, button padding    -> native container / widget
                                                  settings
     type and every text colour                -> bound to kit globals

   What remains below has NO widget control at all in Elementor 4.2.2:
   `aspect-ratio`, `overflow`, `flex: 1`, `margin-top: auto`, the hover lift,
   the badge's chip box, and the clearance price row's `<del>`/`<ins>` split
   (the widget's colour control paints the wrapper; the sale price is inside
   it). Each is called out where it appears.
   ========================================================================== */

/*
 * The card must fill its grid cell, or a short card in a row of tall ones
 * leaves its button floating mid-cell. `.e-loop-item` is Elementor's own cell
 * wrapper — the same class the ad splice in includes/loop-grid-ads.php reuses
 * for a promo tile, which is exactly why a promo tile sizes like a product.
 */
.he-redesign .e-loop-item > .he-card,
.he-redesign .he-card {
	overflow: hidden; /* :834 — clips the image to the card's square corners */
	height: 100%;
	transition: transform .2s, border-color .2s;
}

/* :834 style-hover="transform:translateY(-3px)". No widget control. */
.he-redesign .he-card:hover {
	transform: translateY(-3px);
}

@media (prefers-reduced-motion: reduce) {
	.he-redesign .he-card,
	.he-redesign .he-card:hover {
		transition: none;
		transform: none;
	}
}

/*
 * The image well (:835). `position: relative` is what the clearance badge is
 * positioned against — see the badge rule below for why that has to be the
 * CONTAINER and not the widget. Elementor already gives `.e-con` position
 * relative; it is restated here so a future change to that base rule cannot
 * silently move the badge, and so the reason is written next to the thing that
 * depends on it.
 */
.he-redesign .he-card__well {
	position: relative;
	aspect-ratio: 1 / 1;
	overflow: hidden;
}

.he-redesign .he-card__well .he-card__img,
.he-redesign .he-card__well .he-card__img > div,
.he-redesign .he-card__well .he-card__img a {
	display: block;
	width: 100%;
	height: 100%;
}

/* :836 `width:100%;height:100%;object-fit:cover;display:block`. object-fit IS
   a widget control and is set there; the box it fills is not. */
.he-redesign .he-card__img img {
	width: 100%;
	height: 100%;
	display: block;
}

/*
 * The clearance badge (:1756 `position:absolute;top:12px;left:12px`).
 *
 * THE POSITIONED ELEMENT IS THE WIDGET WRAPPER, and that is the whole trick.
 * Elementor's base CSS carries a bare `.elementor-widget { position: relative }`
 * (project notes §28), so anything absolutely positioned INSIDE a widget
 * resolves against that widget rather than against the card. Positioning the
 * wrapper itself sidesteps it: the wrapper's containing block is the well
 * container above, which is the box the design measures from.
 *
 * The chip's red background is CSS for the same reason the eyebrow chip's ink
 * background is: a heading widget's only background control paints the wrapper
 * as a full-width block. Here the wrapper is absolutely positioned and
 * therefore already shrink-wrapped, so painting it is correct — but there is
 * still no colour control on the heading widget to bind, so `--he-red` (the
 * `.he-site` token mirroring the kit's `che_red`) is the source. Type and text
 * colour ARE bound, to `che_badge` / `che_white`.
 */
.he-redesign .he-card__badge {
	position: absolute;
	top: 12px;
	left: 12px;
	z-index: 2;
	padding: 5px 10px;
	background: var(--he-red);
	width: auto !important;
	max-width: calc(100% - 24px);
}

.he-redesign .he-card__badge .elementor-heading-title {
	margin: 0;
	line-height: 1.2;
}

/* :838 `flex:1` — the body absorbs the leftover height so `margin-top:auto` on
   the button has something to push against. */
.he-redesign .he-card__body {
	flex: 1 1 auto !important;
	min-height: 0 !important;
}

.he-redesign .he-card__title .elementor-heading-title {
	margin: 0;
}

/*
 * The clearance card's price row (:1762's slot — the design draws a per-item
 * note there; this site holds a price instead, and clearance is the only place
 * it shows one).
 *
 * The `<del>`/`<ins>` pair is WooCommerce's own `get_price_html()` output,
 * resolved by the `woocommerce-product-price-tag` dynamic tag in
 * che-build/build-loop-items.php. Nothing here composes a price; these rules
 * only decide how WooCommerce's markup sits.
 *
 * THE WIDGET'S OWN CONTROLS COVER THE ROW, NOT THE HALVES. `text_color` and the
 * typography group are bound to `che_text_note` / `che_meta_sm` and paint the
 * whole widget, which is what makes the struck-out regular price muted. There
 * is no control anywhere that reaches INSIDE the widget's content to the
 * `<ins>`, so the sale price's emphasis is the one thing that has to live here
 * — painted from `--he-text-strong`, the `.he-site` token mirroring the kit's
 * `che_text_strong`, the same arrangement the badge's red already uses.
 * Emphasis is colour only: the weight stays the bound global's, because a
 * second weight would be a type step invented outside the kit.
 *
 * `display: block` on both halves is what stacks them, matching the live
 * clearance tile. WooCommerce ships them inline with a space between.
 */
.he-redesign .he-card__price del,
.he-redesign .he-card__price ins {
	display: block;
	text-decoration-thickness: from-font;
}

/* Browsers underline `<ins>` by default and WooCommerce's own stylesheet bolds
   it; neither is this design's emphasis, and the colour below is. */
.he-redesign .he-card__price ins {
	color: var(--he-text-strong);
	text-decoration: none;
	font-weight: inherit;
	background: none;
}

.he-redesign .he-card__price p {
	margin: 0;
}

/*
 * A product with no price at all resolves the tag to an empty string, and
 * Text_Editor::render() then prints nothing (text-editor.php:596). Elementor
 * drops the whole widget wrapper in that case, so the card already closes up
 * with no blank row — VERIFIED, not assumed: one clearance product's prices
 * were blanked, the archive re-fetched, and its tile came back with the badge,
 * title and Enquire button intact and no price element at all, while the other
 * eighteen were untouched.
 *
 * This rule is therefore not for the empty case but for the half-empty one: a
 * render that emits the wrapper with no amount inside it (a filtered price, a
 * product type whose price_html is markup without an amount) would otherwise
 * spend one of the body's 11px gaps on nothing. The test is the RENDERED
 * amount, which is why it is not `:empty`.
 */
.he-redesign .he-card__price:not(:has(.woocommerce-Price-amount)) {
	display: none;
}

/* :842 / :1763 `margin-top:auto` — pins the CTA to the bottom of the card. */
.he-redesign .he-card__cta {
	margin-top: auto;
	width: 100% !important;
}

.he-redesign .he-card__cta .elementor-button {
	width: 100%;
}

/* ==========================================================================
   9. ARCHIVES  (design :1595-1720 category, :1723-1800 clearance)

   Layout for the templates built by wp-content/che-build/build-product-archive.php
   and build-clearance-archive.php. Same division of labour as §8: colour and
   type are bound to the kit on the widgets, and only what has no control lives
   here.
   ========================================================================== */

/* --- Breadcrumb bar (:1597-1601) ---------------------------------------- */

/*
 * Measure and short padding only. Unlike the PDP's crumb bar in §6, the
 * archive's breadcrumb widget binds its own type and colours to the kit
 * (`che_crumb` / `che_text_crumb`), so nothing here paints.
 */
.he-redesign .he-archive__crumbs {
	max-width: var(--he-container);
	margin-inline: auto;
	padding: 22px clamp(20px, 5vw, 48px) 6px;
	width: 100%;
}

/* --- Intro band (:1605-1618) -------------------------------------------- */

/*
 * The design's own `repeat(auto-fit, minmax(320px,1fr))`, which is what
 * collapses the band to one column with no hand-written breakpoint. The
 * display:contents unwrap is required (skill rule 5) or the boxed inner is the
 * grid's only child; its cost — native gap and vertical padding stop applying
 * to the inner — is paid for by `.he-band__inner`, which owns this band's
 * padding.
 */
.he-redesign .he-archive__introgrid {
	display: grid !important;
	grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)) !important;
	gap: clamp(28px, 4vw, 56px) !important;
	align-items: center !important;
}

.he-redesign .he-archive__introgrid > .e-con-inner {
	display: contents;
}

.he-redesign .he-archive__introcopy,
.he-redesign .he-archive__intromedia {
	min-width: 0 !important; /* skill rule 7 */
}

.he-redesign .he-archive__h1 .elementor-heading-title {
	margin: 0;
	max-width: 14em; /* :1610 */
}

.he-redesign .he-archive__intro p {
	margin: 0;
	max-width: 36em; /* :1611 */
}

/* Recovered intros run 2-3 paragraphs; matches the 14px the adjacent
   .he-archive__intro + .he-archive__intro rule already uses. */
.he-redesign .he-archive__intro p + p {
	margin-top: 14px;
}

.he-redesign .he-archive__intro + .he-archive__intro {
	margin-top: 14px; /* :1612 */
}

/* :1614-1616 `aspect-ratio:3/2;overflow:hidden` over a sand placeholder. */
.he-redesign .he-archive__hero img {
	width: 100%;
	aspect-ratio: 3 / 2;
	object-fit: cover;
	display: block;
	background: var(--he-image-well);
}

/* --- Sub-category chooser (:1620-1637) ---------------------------------- */

/*
 * SELF-HIDING BAND. The design gates this section behind `catShowChooser`; a
 * shared Theme Builder template has no per-request switch, and a category with
 * no children would otherwise render a hairline, 120px of padding and a
 * heading above nothing. `:has()` is the only mechanism that can ask "did the
 * widget find any terms?" from CSS, and it is supported in every browser this
 * project targets.
 */
.he-redesign .he-archive__chooser:not(:has(.he-archive__cats li)) {
	display: none !important;
}

.he-redesign .he-archive__chooserhead .elementor-heading-title {
	margin: 0 0 26px; /* :1622 */
}

/*
 * :1624 `repeat(5,1fr);gap:16px`. WooCommerce's own catalogue CSS lays these
 * out with floats and percentage widths, which is why the grid is declared on
 * the list and the floats are cleared off the items.
 */
.he-redesign .he-archive__cats ul.products {
	display: grid !important;
	grid-template-columns: repeat(5, 1fr);
	gap: 16px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.he-redesign .he-archive__cats ul.products li.product {
	width: auto !important;
	margin: 0 !important;
	float: none !important;
	clear: none !important;
}

/* :1626-1628 — a square, cover-cropped tile on white with the card border. */
.he-redesign .he-archive__cats ul.products li.product img {
	width: 100%;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	display: block;
	margin: 0;
	background: var(--he-white);
	border: 1px solid var(--he-border);
	transition: transform .2s;
}

.he-redesign .he-archive__cats ul.products li.product a:hover img {
	transform: translateY(-3px);
}

/*
 * :1630 — the label row under the tile. Type and colour are BOUND on the widget
 * (`title_typography` -> che_card_label, `title_color` -> che_text_strong);
 * both of those controls declare a system-global default (categories.php:323-346)
 * and would otherwise have painted the Primary ink at the Primary size, which is
 * project notes §30 in its widest form. Only the spacing is left here.
 */
.he-redesign .he-archive__cats ul.products li.product h2,
.he-redesign .he-archive__cats ul.products li.product .woocommerce-loop-category__title {
	/* :1629 `display:flex;align-items:center;justify-content:space-between;gap:8px` */
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 8px;
	margin: 11px 0 0;
}

/*
 * :1631 — the 26x26 arrow chip at the end of the label row.
 *
 * A pseudo-element because the tile is `wc-categories` markup: the widget emits
 * the term name and a count span and offers no third slot, so there is no
 * control to bind and nothing in the build script can reach it. Sized, coloured
 * and stroked exactly as the design's inline SVG (`#eff8e0` on `#3f6300`,
 * 14x14 glyph, stroke-width 2.4).
 */
.he-redesign .he-archive__cats ul.products li.product .woocommerce-loop-category__title::after {
	content: "";
	flex: 0 0 auto;
	width: 26px;
	height: 26px;
	background-color: #eff8e0;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%233f6300' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3Cpath d='m13 6 6 6-6 6'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: center;
}

/* The design's chooser tile shows no product count (:1629-1633). */
.he-redesign .he-archive__cats ul.products li.product .woocommerce-loop-category__title .count {
	display: none;
}

@media (max-width: 1000px) {
	.he-redesign .he-archive__cats ul.products {
		grid-template-columns: repeat(3, 1fr);
	}
}

@media (max-width: 560px) {
	.he-redesign .he-archive__cats ul.products {
		grid-template-columns: repeat(2, 1fr);
	}
}

/* --- Grid bands (:1676-1690 / :1752-1775) -------------------------------- */

/*
 * The count meta line (:1760) carries NO type here: it is a heading widget
 * bound to `che_meta_sm` / `che_text_note` (che_archive_count_widget() in
 * che-sections.php), with the live number supplied by the `shortcode` dynamic
 * tag. The Shortcode WIDGET would have forced the step into this file, because
 * it has no typography or colour control at all — which is why it is not used.
 */
.he-redesign .he-archive__count .elementor-heading-title,
.he-redesign .he-search__count .elementor-heading-title {
	margin: 0;
}

.he-redesign .he-archive__gridhead,
.he-redesign .he-search__gridhead {
	margin-bottom: 26px;
}

/* :1750-1761 — head copy left, count right, both bottom-aligned. */
.he-redesign .he-clear__gridhead {
	display: flex !important;
	flex-direction: row !important;
	flex-wrap: wrap !important;
	align-items: flex-end !important;
	justify-content: space-between !important;
	gap: 20px !important;
	margin-bottom: 34px;
}

.he-redesign .he-clear__gridhead-copy {
	min-width: 0 !important;
	flex: 1 1 auto !important;
}

.he-redesign .he-clear__count {
	flex: 0 0 auto !important;
}

/*
 * :1676 / :1767 `repeat(4,1fr);gap:18px`. The Loop Grid's own columns/gap
 * controls are set on the widget and do the work; this only removes the list
 * styling WooCommerce's catalogue CSS puts back on `ul.products`.
 */
.he-redesign .he-archive__grid .elementor-grid,
.he-redesign .he-clear__grid .elementor-grid,
.he-redesign .he-search__grid .elementor-grid {
	list-style: none;
	margin: 0;
	padding: 0;
}

/*
 * Pagination sat flush against the last row of cards on every paginated
 * archive — product categories, clearance, search and the blog all render
 * Elementor's `.elementor-pagination` straight after the grid with no gap of
 * its own. Scoped to the redesign body class so it lands everywhere at once
 * rather than per-template.
 */
.he-redesign .elementor-pagination {
	margin-top: 36px;
}

/* --- Clearance hero and notes (:1725-1750) ------------------------------- */

.he-redesign .he-clear__h1 .elementor-heading-title {
	margin: 0;
}

.he-redesign .he-clear__lede p {
	margin: 0;
	max-width: 40em; /* :1730 */
}

/* :1731 — the CTA pair sits 28px under the lede and wraps as a row. */
.he-redesign .he-clear__ctas {
	flex-direction: row !important;
	flex-wrap: wrap !important;
	margin-top: 28px;
}

/*
 * :1740 — this band alone runs clamp(56px,6vw,88px), not the grammar's
 * clamp(64px,8vw,120px). The band rhythm lives in one CSS class because the
 * native dimensions control cannot express a clamp() (che-sections.php), so the
 * variant is a modifier on the same class rather than a native override.
 */
/* Native on rebuilt pages: `ec_dims_custom()` passes a clamp() through the
   dimensions control verbatim (project notes §25), so the comment above — that
   the control cannot express one — has not been true since. */
.he-redesign .he-band--tight:not(.he-native) .he-band__inner {
	padding: clamp(56px, 6vw, 88px) clamp(20px, 5vw, 48px);
}

/* :1742 `repeat(3,1fr);gap:16px`. */
.he-redesign .he-clear__notegrid {
	display: grid !important;
	grid-template-columns: repeat(3, 1fr) !important;
	gap: 16px !important;
}

.he-redesign .he-clear__notegrid > .e-con-inner {
	display: contents;
}

.he-redesign .he-clear__note {
	min-width: 0 !important;
}

.he-redesign .he-clear__notecopy p {
	margin: 0;
}

@media (max-width: 900px) {
	.he-redesign .he-clear__notegrid {
		grid-template-columns: 1fr !important;
	}
}

/* --- "How clearance works" (:1777-1798) ---------------------------------- */

/* :1779 — the design's own auto-fit split, same mechanism as the intro band. */
/* Native grid on rebuilt pages; the unwrap voided this container's own padding
   and gap for as long as it was here (project notes §54). */
.he-redesign .he-clear__howgrid:not(.he-native) {
	display: grid !important;
	grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)) !important;
	gap: clamp(32px, 5vw, 64px) !important;
	align-items: center !important;
}

.he-redesign .he-clear__howgrid:not(.he-native) > .e-con-inner {
	display: contents;
}

.he-redesign .he-clear__howcopy-col,
.he-redesign .he-clear__howmedia {
	min-width: 0 !important;
}

.he-redesign .he-clear__howcopy p {
	margin: 0;
	max-width: 34em; /* :1781 */
}

.he-redesign .he-clear__howcopy + .he-clear__howcopy {
	margin-top: 14px; /* :1782 */
}

/* :1792 `aspect-ratio:16/12;overflow:hidden`. */
.he-redesign .he-clear__howimg img {
	width: 100%;
	aspect-ratio: 16 / 12;
	object-fit: cover;
	display: block;
}

/* --- Large CTA buttons on the archives ----------------------------------- */

/*
 * `.he-cta` is the design's LARGE button (52px, 16px), which is what the kit's
 * button Theme Style already models — so this modifier carries NO size, no
 * type and no colour. It is deliberately a different class from the header's
 * `.he-btn`, which is the COMPACT variant: reusing `.he-btn--outline` here
 * would have made this section's hover tint (#f1eadd, :1733) silently repaint
 * the header's outline button, whose own design value is #efe6d7 (:211). Two
 * design values, two classes.
 *
 * What is left is only what the kit cannot express.
 */
.he-redesign .he-cta .elementor-button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

/*
 * The transparent background is not bindable — `background_color` takes a
 * colour and the kit has no transparent swatch, nor should it — and killing it
 * is also what stops Elementor's Theme Style painting this button solid Accent
 * green (skill rule 9). Border and text colour ARE bound on the widget.
 */
.he-redesign .he-cta--outline .elementor-button {
	background: transparent;
}

.he-redesign .he-cta--outline .elementor-button:hover,
.he-redesign .he-cta--outline .elementor-button:focus {
	background: #f1eadd; /* :1733 style-hover; no kit swatch for this one-off tint */
	border-color: var(--he-ink);
}

/*
 * The ink button's hover (:1789 style-hover="background:#3a322d"). Its NORMAL
 * background and label are bound to che_ink / che_white on the widget; the
 * hover tint is a one-off the kit has no swatch for.
 */
.he-redesign .he-cta--ink .elementor-button:hover,
.he-redesign .he-cta--ink .elementor-button:focus {
	background: #3a322d;
}

/* ==========================================================================
   10. THE REMAINING TEN VIEWS  (Step 4)

   Layout for the pages and templates built by
   wp-content/che-build/build-home-page.php, build-collection-pages.php,
   build-about-page.php, build-made-page.php, build-built-page.php,
   build-brands-page.php, build-faq-page.php, build-promotions-page.php,
   build-contact-page.php, build-blog-archive.php and build-post-template.php.

   SAME DIVISION OF LABOUR AS §8 AND §9, and it is worth restating because this
   section is the largest: every colour and every type step in these views is
   BOUND to a kit global on its widget. What lives here is only what Elementor
   4.2.2 has no control for —

     - CSS grid / multi-column layout with named breakpoints,
     - aspect-ratio, object-fit boxes and overflow clipping,
     - `flex: 1` and `margin-top: auto` inside a card,
     - the design's clamp() paddings (the dimensions control has no clamp,
       and §25 of the project notes explains why the two are not swapped
       wholesale without a bounding-rect measurement first),
     - ::before / ::after ornament (ticks, rules, quote marks, chips),
     - anything targeting "every child except the last".

   The literals that remain are listed with their reason at the end of this
   section. Anything not listed there is a defect.
   ========================================================================== */

/* --- Page shell ---------------------------------------------------------- */

.he-redesign .he-page {
	display: block;
}

/*
 * The FAQ and the single post run on the design's 900px measure (:1253, :1261)
 * rather than the 1200 every other band uses.
 */
/* The 900px measure is `boxed_width` on the band now. Kept for pre-native pages. */
.he-redesign .he-band--narrow:not(.he-native) > .e-con-inner,
.he-redesign .he-band--narrow:not(.he-native).he-band__inner {
	max-width: var(--he-container-faq);
}

.he-redesign .he-band--narrow:not(.he-native) .he-band__inner:not(.he-native) {
	max-width: var(--he-container-faq);
}

/* --- The two-column split (design :387, :898, :1016, :1146, :1338) -------- */

/*
 * `.e-con-inner { display: contents }` is the unwrap the skill's rule 5
 * describes, and it is used HERE and nowhere else in this section: the grid has
 * to reach the two real column containers, and a boxed container's only CSS
 * child is the single inner wrapper (failure signature: grid-template-columns
 * computing as "1124px 0px").
 *
 * The cost is that this container can no longer use native gap or vertical
 * padding — both would apply to the now-boxless inner element and render at
 * ~0 while JSON and getComputedStyle both look correct. That is why the padding
 * and the gap below are CSS, and why no build script sets `flex_gap` on a
 * `.he-split__grid`.
 */
/*
 * PRE-NATIVE FALLBACK, and the reason the native grammar exists.
 *
 * `display: contents` on a boxed container's inner box is what makes native
 * vertical padding and native gap stop working on that container — the settings
 * apply to an element that no longer generates a box, and both the JSON and
 * `getComputedStyle` still read correctly. Rebuilt splits are real GRID
 * containers (`container_type: 'grid'` + `grid_columns_grid`), which Elementor
 * wires onto BOTH boxes, so they need no unwrap and keep every control.
 */
.he-redesign .he-split__grid:not(.he-native) > .e-con-inner,
.he-redesign .he-twocol:not(.he-native) > .e-con-inner,
.he-redesign .he-mic__grid:not(.he-native) > .e-con-inner {
	display: contents;
}

.he-redesign .he-split__grid:not(.he-native),
.he-redesign .he-twocol:not(.he-native),
.he-redesign .he-mic__grid:not(.he-native) {
	display: grid !important;
	grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
	gap: clamp(32px, 5vw, 64px);
	align-items: center;
	max-width: var(--he-container);
	margin-inline: auto;
	padding: clamp(64px, 8vw, 120px) clamp(20px, 5vw, 48px);
	width: 100%;
}

/* The two-column copy blocks are top-aligned; only picture splits centre. */
.he-redesign .he-twocol {
	align-items: start;
}

.he-redesign .he-split__copy,
.he-redesign .he-split__media,
.he-redesign .he-twocol__col {
	min-width: 0 !important; /* skill rule 7: long copy otherwise refuses to shrink */
}

.he-redesign .he-split__copy:not(.he-native) > * + * {
	margin-top: 18px;
}

.he-redesign .he-split__copy:not(.he-native) > .he-eyebrow + * {
	margin-top: 12px;
}

/*
 * THE SPLIT'S PHOTOGRAPH — SIZED ON THE IMAGE, NOT ON AN ANCESTOR.
 *
 * This rule used to put `aspect-ratio` on the widget WRAPPER and `height:100%`
 * on the image. Between them sits `.elementor-widget-container`, which has no
 * definite height — so the percentage resolved against nothing, and inside the
 * wrapper's `overflow:hidden` the photograph rendered as an empty box. A real
 * `<img>` with a valid `src` painting nothing, which reads as missing markup
 * and is not.
 *
 * It surfaced on `/furniture/` and it was never specific to that page: every
 * split whose image is not already 4/3 hits it. `.he-archive__hero img` on the
 * category view has always been correct precisely because it states its size on
 * the IMAGE, with no dependency on an ancestor. This is now that shape.
 *
 * 4/3 is the design's dominant split ratio (9 of its 32 aspect-ratio
 * declarations); the instances that state another one override BELOW, on the
 * image, and each carries its design line.
 */
.he-redesign .he-split__media img {
	width: 100%;
	height: auto;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	display: block;
}

/* The wrapper keeps the clip and gives up the sizing. */
.he-redesign .he-split__media > .elementor-widget-image {
	overflow: hidden;
}

/* :1058 — About's "Visit us" photograph is 16/10, not the 4/3 default. */
.he-redesign .he-about__visit .he-split__media img {
	aspect-ratio: 16 / 10;
}

/* The pricing panel is a tall portrait render, not a cropped photograph. */
/* A tall portrait render, not a cropped photograph — no ratio at all. */
.he-redesign .he-built__pricing .he-split__media img {
	aspect-ratio: auto;
	height: auto;
}

.he-redesign .he-built__img--auto img {
	height: auto;
}

/*
 * PRE-NATIVE FALLBACK. In the design the red cards are a SIBLING of the
 * Made-in-Canada grid (:409 vs :398), not a cell inside it — `grid-column:1/-1`
 * was compensating for a structure the design does not have. The rebuilt home
 * page nests them correctly and sets columns, gap and margin as controls.
 */
.he-redesign .he-mic__cards:not(.he-native) {
	grid-column: 1 / -1;
	display: grid !important;
	grid-template-columns: repeat(3, 1fr);
	margin-top: clamp(36px, 4.5vw, 60px); /* :409 */
}

/*
 * PRE-NATIVE FALLBACK. The strip is a SEPARATE padded box in the design
 * (:1129, :905), not a spanning third cell of the copy grid — so it needs
 * neither `grid-column:1/-1` nor a stylesheet `margin-top`. `che_band_multi()`
 * builds it as its own band inner with the design's own padding; the rebuilt
 * Made and Built pages take that path and never reach this rule.
 */
.he-redesign .he-madestrip:not(.he-native) {
	grid-column: 1 / -1;
	display: grid !important;
	grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
	margin-top: clamp(8px, 2vw, 24px);
}

/* :1130-1131 — each photo sits in a 2/1 well. */
.he-redesign .he-madestrip__cell {
	overflow: hidden;
	aspect-ratio: 2 / 1;
}

.he-redesign .he-madestrip__cell img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.he-redesign .he-madestrip img {
	width: 100%;
	aspect-ratio: 2 / 1;
	object-fit: cover;
	display: block;
}

.he-redesign .he-madestrip--wide img {
	aspect-ratio: 24 / 10; /* :906 */
}

.he-redesign .he-madestrip__cell--wide {
	aspect-ratio: 24 / 10; /* :906 */
}

@media (max-width: 1000px) {
	.he-redesign .he-mic__cards:not(.he-native) {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 820px) {
	.he-redesign .he-mic__cards:not(.he-native) {
		grid-template-columns: 1fr;
	}
}

/* --- Ruled column groups (design :437, :566, :1044, :1436) ---------------- */

/*
 * Rules between columns, suppressed on the first and last gutter. There is no
 * container control for "every child except the last", so the whole pattern is
 * CSS; the columns themselves are real containers holding real widgets.
 */
.he-redesign .he-ruled:not(.he-native) {
	display: grid !important;
	grid-template-columns: repeat(3, 1fr);
	gap: 0;
	border-top: 1px solid var(--he-border-input);
	width: 100%;
}

.he-redesign .he-ruled--dark:not(.he-native) {
	border-top-color: var(--he-border-on-ink);
}

.he-redesign .he-ruled__col {
	border-right: 1px solid var(--he-border-input);
	min-width: 0 !important;
}

/* Column block/gutter padding is native on rebuilt sections (:441 30/28, :567 28/26). */
.he-redesign .he-ruled__col:not(.he-native) {
	padding: 28px 32px 26px;
}

.he-redesign .he-ruled--dark .he-ruled__col {
	border-right-color: var(--he-border-on-ink);
}

/* No container control expresses "every child except the last", so the
   suppressed outer gutters and the inter-column rules stay CSS. */
.he-redesign .he-ruled__col:first-child {
	padding-left: 0;
	padding-inline-start: 0;
}

.he-redesign .he-ruled__col:last-child {
	border-right: none;
	padding-right: 0;
	padding-inline-end: 0;
}

@media (max-width: 820px) {
	.he-redesign .he-ruled:not(.he-native) {
		grid-template-columns: 1fr;
	}

	.he-redesign .he-ruled__col:not(.he-native) {
		padding: 24px 0;
		border-right: none;
		border-bottom: 1px solid var(--he-border-input);
	}

	.he-redesign .he-ruled--dark .he-ruled__col {
		border-bottom-color: var(--he-border-on-ink);
	}

	.he-redesign .he-ruled__col:last-child {
		border-bottom: none;
	}
}

/* --- The green tick list (design :481, :954, :1039) ----------------------- */

/*
 * The 26px tick square is a ::before on each item, not an icon widget per
 * point: the list is client-editable and a per-point icon would mean two
 * widgets to add for every line, one of which does nothing but decorate.
 */
.he-redesign .he-ticks .he-ticks__item .elementor-heading-title {
	display: flex;
	align-items: center;
	gap: 12px;
	line-height: 1.55;
}

.he-redesign .he-ticks .he-ticks__item .elementor-heading-title::before {
	content: "";
	flex: 0 0 auto;
	width: 26px;
	height: 26px;
	background-color: var(--he-green);
	/* The design's check glyph. A data: URI so it needs no network request and
	   no icon widget; it carries no information the text does not. */
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%2317181a' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: center;
}

/* The About page runs its six points as a ruled three-column grid (:1037). */
.he-redesign .he-why {
	display: grid !important;
	grid-template-columns: repeat(3, 1fr);
	gap: 0 !important;
	border-top: 1px solid var(--he-border-on-ink);
}

.he-redesign .he-why .he-ticks__item {
	padding: 22px 32px;
	border-right: 1px solid var(--he-border-on-ink);
	border-bottom: 1px solid var(--he-border-on-ink);
	min-width: 0 !important;
}

.he-redesign .he-why .he-ticks__item:nth-child(3n + 1) {
	padding-left: 0;
}

.he-redesign .he-why .he-ticks__item:nth-child(3n) {
	border-right: none;
	padding-right: 0;
}

.he-redesign .he-why .he-ticks__item:nth-last-child(-n + 3) {
	border-bottom: none;
}

.he-redesign .he-ticks--on-dark .he-ticks__item .elementor-heading-title {
	align-items: flex-start;
}

@media (max-width: 820px) {
	.he-redesign .he-why {
		grid-template-columns: 1fr;
	}

	.he-redesign .he-why .he-ticks__item {
		padding: 20px 0;
		border-right: none;
	}

	.he-redesign .he-why .he-ticks__item:last-child {
		border-bottom: none;
	}
}

/* --- Media hero (design :332, :880, :1011, :1107, :1321) ------------------ */

/*
 * The photograph and its overlay are NATIVE container controls
 * (background_image + the background_overlay group), so the client swaps the
 * picture in the panel. Only the height and the copy measure are here, because
 * neither is a control: min-height has none, and the design varies it per view.
 */
/*
 * PRE-NATIVE FALLBACK. `min-height` and cross-axis alignment are both real
 * container controls; on a rebuilt hero they are settings. Left unscoped, the
 * `align-items: flex-end` here also shrink-wraps and right-aligns the hero's
 * padded inner box the moment that box stops carrying `width: 100%` from the
 * old `.he-band__inner` rule.
 */
.he-redesign .he-mediahero:not(.he-native) {
	display: flex;
	align-items: flex-end;
	min-height: min(92vh, 880px); /* :332 home */
	overflow: hidden;
}

.he-redesign .he-mediahero {
	overflow: hidden;
}

/*
 * PRE-NATIVE FALLBACKS, and they need `:not(.he-native)` for two separate
 * reasons.
 *
 * Specificity: the base rule above is `.he-redesign .he-mediahero:not(.he-native)`
 * = 0,3,0. These modifiers were 0,2,0, so they LOST and every media hero on the
 * site rendered at the home hero's `min(92vh,880px)` — the About and Made
 * heroes nearly twice their design height. Matching the base's specificity and
 * sitting later in the file is what makes a modifier a modifier.
 *
 * Correctness: `--lg` carried Promotions' value, not Built's. They are two
 * different design heights and now two different modifiers.
 *
 * On a rebuilt hero none of this runs at all: `min_height` is a control and
 * each build script passes its own view's literal.
 */
.he-redesign .he-mediahero--lg:not(.he-native) {
	min-height: min(66vh, 560px); /* :880 built to order */
}

.he-redesign .he-mediahero--xl:not(.he-native) {
	min-height: min(72vh, 620px); /* :1321 promotions */
}

.he-redesign .he-mediahero--md:not(.he-native) {
	min-height: min(56vh, 460px); /* :1010 about, :1106 made */
}

.he-redesign .he-mediahero__inner {
	position: relative;
	z-index: 1;
}

/* :339 — 48px is the design's floor, not 44. Native on rebuilt heroes. */
.he-redesign .he-mediahero__inner:not(.he-native) {
	padding-top: clamp(64px, 9vw, 120px);
	padding-bottom: clamp(44px, 6vw, 80px);
}

.he-redesign .he-mediahero__h1 .elementor-heading-title {
	max-width: 16em;   /* :1112 made, :1010 about */
	text-wrap: balance;
}

/* :886 built, :1328 promotions — 15em, not the shared 16. */
.he-redesign .he-mediahero--lg .he-mediahero__h1 .elementor-heading-title,
.he-redesign .he-mediahero__h1--15em .elementor-heading-title {
	max-width: 15em;
}

/*
 * The media heroes' lede measure varies: 40em on Brands/FAQ/Contact/Clearance,
 * 34em on Promotions (:1329). 40 is the default and Promotions carries the
 * `he-lede--34em` modifier; the margin is native on rebuilt pages.
 */
.he-redesign .he-mediahero__lede {
	max-width: 40em;
}

.he-redesign .he-mediahero__lede:not(.he-native) {
	margin-top: 16px;
}

.he-redesign .he-lede--34em { max-width: 34em; }

.he-redesign .he-mediahero .he-eyebrow:not(.he-native) {
	margin-bottom: 16px;
}

/*
 * THE GRADIENT SCRIM LAYER — verbatim, per view.
 *
 * Every media hero in the design is photo -> flat rgba scrim -> THREE-stop
 * gradient. The flat layer is Elementor's background-overlay control (see
 * che_media_hero()); the gradient is here, because the control's gradient mode
 * carries two stops and a stylesheet gradient has no limit. Stacking order is
 * the design's: flat under gradient. That is not pedantry — on Promotions the
 * top stop is red, and putting the flat layer over it changes the hue.
 *
 * The design writes these `to top`; a `to top` stop at N% is a 180deg stop at
 * (100-N)%. Converted here rather than at read time so the numbers below can be
 * checked against the source line by line.
 *
 * ::after, never ::before — `::before` on a container is where Elementor paints
 * the overlay itself. See §"The band" above.
 */
.he-redesign .he-mediahero::after {
	inset: 0;
	top: 0;
	left: 0;
	right: 0;
	height: auto;
	z-index: 0;
	/* :335 home — the only one the design writes top-down already. */
	background: linear-gradient(180deg,
		rgba(20, 16, 13, 0.55) 0%,
		rgba(20, 16, 13, 0.30) 45%,
		rgba(20, 16, 13, 0.80) 100%);
}

/* :883 built to order — `to top .86 0%, .22 60%, .5 100%`. */
.he-redesign .he-mediahero--lg::after {
	background: linear-gradient(180deg,
		rgba(20, 16, 13, 0.50) 0%,
		rgba(20, 16, 13, 0.22) 40%,
		rgba(20, 16, 13, 0.86) 100%);
}

/* :1013 about, :1109 made in canada — `to top .88 0%, .25 65%, .5 100%`. */
.he-redesign .he-mediahero--md::after {
	background: linear-gradient(180deg,
		rgba(20, 16, 13, 0.50) 0%,
		rgba(20, 16, 13, 0.25) 35%,
		rgba(20, 16, 13, 0.88) 100%);
}

/*
 * :1324 promotions — `to top rgba(20,16,13,.9) 0%, rgba(28,14,16,.34) 58%,
 * rgba(120,14,28,.34) 100%`. Three different hues, and the red one is at the
 * TOP. This is the hero that makes the layer order load-bearing.
 */
.he-redesign .he-mediahero--xl::after {
	background: linear-gradient(180deg,
		rgba(120, 14, 28, 0.34) 0%,
		rgba(28, 14, 16, 0.34) 42%,
		rgba(20, 16, 13, 0.90) 100%);
}

/* Both scrims paint under the hero's real children, never over them. */
.he-redesign .he-mediahero > * {
	position: relative;
	z-index: 1;
}

/*
 * :1325 — the Promotions hero's 5px red foot.
 *
 * It used to live on `.he-promos__hero::after`. That pseudo-element now carries
 * the hero's gradient scrim, and a container has only the two — `::before` is
 * Elementor's overlay. So the foot moves down one level, onto the hero's own
 * padded inner box: that element is `position: relative` already, spans the full
 * band width (only `.e-con-inner` inside it is capped at the measure), and grows
 * to the band's height, so `bottom: 0` is the band's bottom edge.
 *
 * It stays CSS because it is a three-stop gradient on one edge: a container's
 * border control paints four sides in one colour, and would sit under the scrim.
 */
.he-redesign .he-promos__hero .he-mediahero__inner::after {
	content: "";
	position: absolute;
	top: auto;
	left: 0;
	right: 0;
	bottom: 0;
	height: 5px;
	background: linear-gradient(90deg, var(--he-red), var(--he-red-light), var(--he-red));
	z-index: 3;
	pointer-events: none;
}

/* --- Home: hero copy, CTAs and the stats bar (design :339-368) ------------ */

.he-redesign .he-hero__copy:not(.he-native) {
	max-width: var(--he-container);
	width: 100%;
}

.he-redesign .he-hero__badge:not(.he-native) {
	margin-bottom: 24px;
}

.he-redesign .he-hero__badge .elementor-heading-title {
	display: inline-flex;
	align-items: center;
	padding: 9px 15px;
	/* CLIENT DIRECTIVE: black/white, not the design's green (:339). White chip
	 * on the dark hero image; text stays the bound che_text_strong ink. */
	background: var(--he-white);
	line-height: 1.2;
}

/* CLIENT DIRECTIVE: hero badge hidden at the kit's mobile breakpoint (560px).
 * Hidden on the wrapper (not the title) so the badge's own 24px margin-bottom
 * collapses with it — no leftover gap above the H1. */
@media (max-width: 560px) {
	.he-redesign .he-hero__badge {
		display: none !important;
	}
}

.he-redesign .he-hero__h1 .elementor-heading-title {
	max-width: 15em;
	text-wrap: balance;
}

/*
 * :109 — `.he-hero-in button,.he-hero-in a{width:100%;justify-content:center}`.
 * At phone the two hero CTAs each take their own full-width line; they were
 * rendering at their text widths (243px and 229px) side by side.
 *
 * Three elements, because a button widget is three boxes: the widget wrapper is
 * the flex item of the CTA row and is what has to claim the line (skill rule
 * 6 — a nested container/widget defaults to shrink-to-content here), the
 * `.elementor-button-wrapper` is a plain block inside it, and `.elementor-button`
 * is the inline-flex box that draws the button. Sizing only the anchor leaves a
 * 243px wrapper with a full-width button inside it.
 */
@media (max-width: 560px) {
	.he-redesign .he-hero__ctas > .elementor-widget-button {
		width: 100% !important;
		flex: 0 0 100% !important;
	}

	.he-redesign .he-hero__ctas .elementor-button {
		width: 100%;
		justify-content: center;
	}
}

.he-redesign .he-hero__ctas:not(.he-native) {
	margin-top: 36px;
}

/*
 * PRE-NATIVE FALLBACK. This rule never set flex-direction, and Elementor's own
 * default is `--flex-direction: column`, so every CTA row it governs is a
 * COLUMN. Rebuilt sections carry `.he-native` and set direction, wrap, gap and
 * justification as real controls; this is what is left for the views that have
 * not been rebuilt yet, and it goes when they are.
 */
.he-redesign .he-ctarow:not(.he-native) {
	display: flex !important;
	flex-direction: row;
	flex-wrap: wrap;
	align-items: center;
}

/*
 * The stats bar sits UNDER the hero photo, sharing its ink, and is a sibling
 * rather than a child so it can carry its own top hairline and blur without
 * inheriting the hero's min-height flex context.
 */
/*
 * :353 — the panel behind the stats. Colour and the 1px top rule are native
 * controls on the container; `backdrop-filter` has none, so the blur is the
 * only thing left here.
 */
.he-redesign .he-stats__bar {
	-webkit-backdrop-filter: blur(8px);
	backdrop-filter: blur(8px);
}

.he-redesign .he-stats__bar:not(.he-native) {
	background: rgba(20, 16, 13, 0.94);
	border-top: 1px solid rgba(255, 255, 255, 0.16);
}

.he-redesign .he-stats:not(.he-native) {
	display: flex !important;
	flex-wrap: wrap;
	align-items: center;
	gap: 20px 44px;
	padding: 22px clamp(20px, 5vw, 48px);
	max-width: var(--he-container);
	margin-inline: auto;
}

.he-redesign .he-stats__item:not(.he-native) {
	display: flex !important;
	align-items: baseline;
	gap: 9px;
	flex: 0 0 auto !important;
}

@media (max-width: 560px) {
	.he-redesign .he-stats:not(.he-native) {
		gap: 12px 22px;
	}
}

/*
 * :357-359 — the three figures carry `min-width:2.6ch` (years) and `3.4ch`
 * (the other two) so the figure/unit pairs line up on a common column. `ch` is
 * a font-relative unit with no Elementor control; the widths are set on the
 * heading title, which is the box the control's own selectors name.
 */
.he-redesign .he-stats__item:nth-child(1) .he-stats__num .elementor-heading-title {
	min-width: 2.6ch;
}

.he-redesign .he-stats__item:nth-child(2) .he-stats__num .elementor-heading-title,
.he-redesign .he-stats__item:nth-child(3) .he-stats__num .elementor-heading-title {
	min-width: 3.4ch;
}

/* --- Home: shop by room, and every wc-categories grid --------------------- */

/*
 * `wc-categories` renders WooCommerce's own float layout. The column count and
 * both gaps ARE widget controls and are set on the widget; `display: grid` over
 * the float is not, and neither is the tile's overlay.
 */
.he-redesign .he-rooms__grid ul.products,
.he-redesign .he-chooser__grid ul.products {
	display: grid;
	margin: 0;
	padding: 0;
	list-style: none;
	float: none;
}

.he-redesign .he-rooms__grid ul.products::before,
.he-redesign .he-rooms__grid ul.products::after,
.he-redesign .he-chooser__grid ul.products::before,
.he-redesign .he-chooser__grid ul.products::after {
	content: none;
}

.he-redesign .he-rooms__grid li.product-category,
.he-redesign .he-chooser__grid li.product-category {
	width: auto !important;
	margin: 0 !important;
	float: none !important;
	clear: none !important;
}

/* The room tile: a 5/4 photograph with the label sitting on a bottom scrim. */
.he-redesign .he-rooms__grid li.product-category > a {
	position: relative;
	display: block;
	aspect-ratio: 5 / 4;
	overflow: hidden;
	background: var(--he-image-well);
	transition: transform 0.2s ease;
}

.he-redesign .he-rooms__grid li.product-category > a:hover {
	transform: translateY(-3px);
}

/* :79-80 — `.he-tile:hover img{transform:scale(1.05)}` over `.6s`. */
.he-redesign .he-rooms__grid li.product-category > a:hover img {
	transform: scale(1.05);
}

/*
 * `ul.products li.product-category` because WooCommerce ships
 * `.woocommerce ul.products li.product a img{height:auto}` (woocommerce.css),
 * and the tile's `li` carries BOTH `product-category` and `product`. At three
 * classes each, that rule's four element selectors outweighed this rule's one,
 * so `height` lost and every tile photograph sized itself to its own aspect
 * ratio instead of the 5/4 box — `object-fit` then had nothing to crop, because
 * the element box it fills WAS the short box. The band of empty well under
 * Dining, Bedroom, Entertainment and Clearance was that gap; Living Room and
 * Home Office only looked right because their sources are already ~5/4.
 */
.he-redesign .he-rooms__grid ul.products li.product-category > a img {
	transition: transform .6s cubic-bezier(.22, .61, .36, 1);
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	margin: 0;
}

.he-redesign .he-rooms__grid li.product-category > a::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(to top, rgba(20, 16, 13, 0.8) 0%, rgba(20, 16, 13, 0.1) 62%, transparent 100%);
}

/*
 * :386-388 — the 36x36 green arrow chip, bottom-right of every room tile. The
 * rule existed for `.he-chooser__grid` and never for `.he-rooms__grid`, so the
 * home page's six tiles had no chip at all.
 *
 * `> a::before` because `> a::after` is already the tile's bottom scrim, and the
 * anchor is a plain `<a>` — not a container, so `::before` is free here.
 */
.he-redesign .he-rooms__grid li.product-category > a::before {
	content: "";
	position: absolute;
	right: 18px;
	/* Centred on the label — see the label rule below for the arithmetic. */
	bottom: calc(var(--he-tile-inset) + (var(--he-tile-label-h) - var(--he-tile-chip)) / 2);
	z-index: 2;
	width: var(--he-tile-chip);
	height: var(--he-tile-chip);
	background-color: var(--he-green);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17' viewBox='0 0 24 24' fill='none' stroke='%2317181a' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3Cpath d='m13 6 6 6-6 6'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: center;
}

/*
 * THE ARROW CHIP IS CENTRED ON THE LABEL, and both derive that from one
 * number.
 *
 * Client report, 2026-08-31: "the Labels (Dining Room, 384 pieces) does not
 * vert align with the green button... the bottom of the button is lower than
 * the ### pieces line", then "arrow button should sit vert middle of the
 * label".
 *
 * WHY IT WAS OFF. Label and chip were both anchored at `bottom: 16px`, which
 * aligns their BOX bottoms exactly — and still looked wrong, because the two
 * boxes are different heights and neither is what the eye reads. Measured on
 * the rendered page: the label's box is 65px tall against the chip's 36px, so
 * their centres sat 14.5px apart. The label is that tall because Elementor's
 * own generated CSS for the wc-categories widget puts `padding: 11.5px 0` on
 * `.woocommerce-loop-category__title` — invisible padding that pushes the
 * text up off the bottom edge the chip paints down to.
 *
 * THE FIX, in two parts. First normalise the label box to one known height
 * (`--he-tile-label-h`) with `box-sizing: border-box`, so the clearance
 * tile's extra horizontal padding cannot make its label a different height
 * from the other five — every tile's label is the same box. Then position the
 * chip at the height that centres it on that box:
 *
 *     chip bottom = label bottom + (label height - chip height) / 2
 *
 * written as a `calc()` off the same variable, so changing the label height
 * moves the chip with it and the two cannot drift apart. A hand-tuned pixel
 * offset would look right today and break the next time the type, the
 * line-height or the count's size changes — which is exactly how this got
 * off in the first place.
 */
.he-redesign .he-rooms__grid {
	--he-tile-label-h: 54px;
	--he-tile-chip: 36px;
	--he-tile-inset: 16px;
}

.he-redesign .he-rooms__grid li.product-category h2 {
	position: absolute;
	left: 18px;
	/* 18 (design's right inset) + 36 (chip) + 12 (the design's gap :383). */
	right: 66px;
	bottom: var(--he-tile-inset);
	z-index: 1;
	margin: 0;
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 3px;
}

/*
 * Five classes, to beat Elementor's own five.
 *
 * The widget's generated rule is `.elementor-23525 .elementor-element
 * .elementor-element-2c6eace .woocommerce .woocommerce-loop-category__title`
 * — (0,5,0) — and it is what sets the `padding: 11.5px 0` this has to
 * replace. Class count decides first, so a (0,4,2) selector loses to it no
 * matter how many element names it adds; naming `ul.products` and the h2's
 * own `.woocommerce-loop-category__title` brings this to (0,5,3), which ties
 * on classes and wins on elements. Both are real classes in the rendered
 * markup, not hooks invented to win an argument — so no `!important`.
 *
 * `box-sizing: border-box` is the load-bearing part: it makes `min-height`
 * the OUTER height, so the clearance tile's 10px of horizontal padding (and
 * its 6px vertical) cannot change the box the chip is centred against.
 */
.he-redesign .he-rooms__grid ul.products li.product-category h2.woocommerce-loop-category__title {
	box-sizing: border-box;
	min-height: var(--he-tile-label-h);
	padding: 6px 0;
}

.he-redesign .he-rooms__grid li.product-category h2 mark.count {
	background: none;
	color: inherit;
	font-size: 13px;
	font-weight: 600;
	opacity: 0.88;
}

/*
 * §8b — the clearance room tile, in the sale colours.
 *
 * CLIENT DIRECTIVE (2026-08-31): "Restore the old label (Showroom Clearance
 * with product count) instead of transparent bg, it's red/white button and
 * all. so it looks like the others, but holds the sale colours." So this tile
 * keeps the same label, the same count and the same bottom-left position as
 * the other five — the ONLY difference is that the label is painted as a red
 * block with white text, and the arrow chip is red instead of green.
 *
 * An earlier cut of this put a top-left badge on the tile, copying the
 * product card's `.he-card__badge`. It was rejected for the right reason:
 * "the top left placement was a nice idea, but it doesnt work with the rest
 * being inline". Nothing here shares a selector with `.he-card__badge` any
 * more — the two are deliberately different things (a card's corner flag
 * versus this grid's own label), and `--he-red` is the single source of
 * truth they genuinely do share.
 *
 * Keyed by `.he-rooms__tile--clearance`, appended to the `<li>` by
 * `che_clearance_tile_class()` (includes/redesign.php) when the category slug
 * is `furniture-sale`. Never `:last-child` — that would repaint whichever
 * tile happened to render last the moment a room is added or reordered — and
 * never a term id, which means nothing outside the database that issued it.
 *
 * SPECIFICITY, and why the selector names the h2's own class. The
 * wc-categories widget's Elementor-generated CSS (post-23525.css, from
 * build-home-page.php:393 binding `che_tile_title_lg` typography) carries
 * `.elementor-23525 .elementor-element.elementor-element-2c6eace .woocommerce
 * .woocommerce-loop-category__title` — five classes, (0,5,0). A rule of
 * (0,4,2) loses to it on class count no matter how many type selectors it
 * adds, which is exactly how an earlier attempt rendered this label at title
 * size instead of its own. Adding `.woocommerce-loop-category__title` — the
 * h2's real class in the rendered markup, not an invented hook — beats it
 * without `!important`. This rule's own arithmetic is worked out at the
 * bottom of this block, where it also has to beat the label-normalising rule
 * above.
 *
 * ONE BANNER, EDGE TO EDGE, holding both the label and the arrow. Client,
 * 2026-08-31: "The red needs to go full width and wrap around the label and
 * the button. There's a gap between them. it should be one consistant row bg
 * for both. (Making it look like a banner button.)"
 *
 * So the label stops shrink-wrapping and spans the tile instead — `left: 0;
 * right: 0`, overriding the base rule's 18px/66px insets — and the arrow chip
 * (still absolutely positioned at `right: 18px`, painted the same red) sits
 * ON that band rather than beside it. The chip's own red square is then
 * invisible against the banner, which is the point: what reads is one
 * continuous red row with a white label at one end and a white arrow at the
 * other.
 *
 * The 18px inset the text used to get from `left` now comes from `padding`
 * instead, so the text still starts exactly 18px from the tile edge and stays
 * flush with the other five tiles' labels — no adjustment needed on those.
 * That padding is also the "breathing room" the client asked for in the same
 * message: 18px of red either side of the text rather than the 10px a
 * shrink-wrapped chip had.
 *
 * `max-width: none` because the base rule's 66px chip reserve is meaningless
 * once the band runs the full width; `padding-right` keeps the text clear of
 * the arrow.
 *
 * `ul.products` is in this selector for one reason: the label-normalising
 * rule above is (0,5,3) and sets `padding: 6px 0`. Without the extra class
 * this rule is (0,5,2) and LOSES the padding to it — which is exactly what
 * happened, and the banner's text rendered flush against the tile edge at 0
 * instead of the intended 18px. Naming `ul.products` here brings it to
 * (0,6,3) so the banner's own padding wins.
 */
.he-redesign .he-rooms__grid ul.products li.product-category.he-rooms__tile--clearance h2.woocommerce-loop-category__title {
	left: 0;
	right: 0;
	max-width: none;
	padding: 6px 66px 6px 18px;
	background: var(--he-red);
	color: var(--he-white);
}

/*
 * The arrow on the banner: red ground, WHITE glyph. Client: "The black
 * showroom arrow should be red and white."
 *
 * The base chip draws a near-black arrow (stroke `%2317181a`) because it sits
 * on the bright green; on the red banner that reads as a dark smudge. Same
 * inlined SVG, same geometry, only the stroke changes to white — kept as a
 * whole `background-image` because the stroke colour lives inside the data
 * URI and there is no way to recolour part of one.
 */
.he-redesign .he-rooms__grid li.product-category.he-rooms__tile--clearance > a::before {
	background-color: var(--he-red);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3Cpath d='m13 6 6 6-6 6'/%3E%3C/svg%3E");
}

/* The chooser tile: a square well with the label beneath it (:1626-1633). */
.he-redesign .he-chooser__grid li.product-category > a {
	display: block;
	text-decoration: none;
}

.he-redesign .he-chooser__grid li.product-category img {
	width: 100%;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	display: block;
	margin: 0;
	background: #ffffff;
	border: 1px solid var(--he-border);
	transition: transform 0.2s ease;
}

.he-redesign .he-chooser__grid li.product-category > a:hover img {
	transform: translateY(-3px);
}

.he-redesign .he-chooser__grid li.product-category h2 {
	margin: 11px 0 0;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 8px;
}

.he-redesign .he-chooser__grid li.product-category h2::after {
	content: "";
	flex: 0 0 auto;
	width: 26px;
	height: 26px;
	background-color: var(--he-green-tint);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%233f6300' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3Cpath d='m13 6 6 6-6 6'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: center;
}

.he-redesign .he-chooser__grid li.product-category h2 mark.count {
	display: none; /* the chooser label is the name only (:1630) */
}

/* Head rows that put a heading on the left and a link on the right. */
.he-redesign .he-rooms__head:not(.he-native),
.he-redesign .he-showroom__head:not(.he-native),
.he-redesign .he-group__head:not(.he-native),
.he-redesign .he-clear__gridhead:not(.he-native) {
	display: flex !important;
	flex-direction: row;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: 20px;
	margin-bottom: 32px;
}

.he-redesign .he-rooms__headcopy:not(.he-native) > * + * {
	margin-top: 12px;
}

/*
 * The arrow link: a heading widget with no box, an arrow after the label.
 * Type and colour are bound; the glyph and the gap are not controls.
 */
.he-redesign .he-arrowlink .elementor-heading-title {
	display: inline-flex;
	align-items: center;
	gap: 7px;   /* :374 */
}

/* :1219 — the brand card's "Learn more" states 8px and a 17px glyph. */
.he-redesign .he-brand__more .elementor-heading-title {
	gap: 8px;
}

.he-redesign .he-brand__more .elementor-heading-title::after {
	width: 17px;
	height: 17px;
}

.he-redesign .he-arrowlink .elementor-heading-title::after {
	content: "";
	flex: 0 0 auto;
	width: 16px;
	height: 16px;
	background-color: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3Cpath d='m13 6 6 6-6 6'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3Cpath d='m13 6 6 6-6 6'/%3E%3C/svg%3E") center / contain no-repeat;
}

/*
 * :1219 "Learn more" and :1512 (×5) "Read more" — both bound only to
 * `title_color: che_link` (#3f6300), with no widget-level `title_hover_color`.
 * The kit's global Theme Style `link_hover_color` is ALSO #3f6300 (:25 —
 * the design system's own default is a same-colour hover for plain body
 * copy), so these two arrow links inherited a genuinely dead hover: the
 * exact defect the client is describing. #4e7d00 has no kit swatch (one-off,
 * like :1733/:1789 above), so it lands here rather than as a new global.
 * The `::after` arrow glyph is `currentColor` and follows automatically.
 */
.he-redesign .he-brand__more .elementor-heading-title a:hover,
.he-redesign .he-brand__more .elementor-heading-title a:focus-visible,
.he-redesign .he-bcard__more .elementor-heading-title a:hover,
.he-redesign .he-bcard__more .elementor-heading-title a:focus-visible {
	color: #4e7d00;
}

/* --- Home: the Made-in-Canada red cards ---------------------------------- */

/*
 * The red fragment inside "made here." (:403) and inside "one very good sale"
 * (:1345). A heading widget's title_color paints the WHOLE title; there is no
 * control that reaches a span, so the two-tone headline is a class on the span
 * the copy carries. Editing the sentence in the panel keeps the markup.
 */
.he-redesign .he-red {
	color: var(--he-red);
}

.he-redesign .he-mic__card {
	min-width: 0 !important;
}

/* --- Home: how-it-works steps -------------------------------------------- */

.he-redesign .he-steps__grid:not(.he-native) {
	margin-top: 8px;
}

.he-redesign .he-steps__col:not(.he-native) {
	padding-top: 30px;
	padding-bottom: 28px;
}

.he-redesign .he-steps__num .elementor-heading-title {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	background: var(--he-green);
}

/* :443 gives the square margin-bottom:20px; on rebuilt sections that is the
   widget's own `_margin` and this would have added 12px on top of it. */
.he-redesign .he-steps__num:not(.he-native) .elementor-heading-title {
	margin-bottom: 12px;
}

.he-redesign .he-steps__foot:not(.he-native) {
	display: flex !important;
	flex-direction: row;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 22px 32px;
	margin-top: 44px;
	padding-top: 36px;
	border-top: 1px solid var(--he-border-on-ink);
}

.he-redesign .he-steps__footcopy-col {
	max-width: 46em;
	min-width: 0 !important;
}

/*
 * CLIENT 2026-08-25, item 15: "after Request a Quote the gap is doubled" on a
 * phone. The steps stack at 560, so the foot's separation stops being a
 * band-level break between a 3-up row and the CTA and starts competing with the
 * rhythm between the steps themselves. Measured at 390: step 1→2 and 2→3 are
 * 49px (24px column padding + the 1px rule + 24px), while step 3→foot was 105px
 * (24px + 44px margin + 36px padding) — 2.1×, which is exactly what reads as
 * doubled. The desktop values are the design's (:461) and stay; here the foot
 * takes the same 24 | 1px rule | 24 the steps use, so all three gaps match.
 */
@media (max-width: 560px) {
	.he-redesign .he-steps__foot {
		margin-top: 0;
		padding-top: 24px;
	}
}

/*
 * :461-466 puts the copy and the CTA row on one line with no breakpoint of its
 * own — natural `flex-wrap: wrap` on `.he-steps__foot` (native setting) is
 * correct at the design's own reference widths (1200 band, plenty of room),
 * but the row's hypothetical (pre-shrink) width is ~1072px (640px copy column
 * + 32px gap + ~400px button pair), which is WIDER than the band's available
 * content width across the whole 1001-1199px range (band caps at 1200 but the
 * viewport minus section padding is less than that until ~1200) — so it wraps
 * to a stacked, mobile-style layout on ordinary desktop/laptop widths. That is
 * the client-reported defect, not a screenshot artefact: `flex-wrap` decides
 * on hypothetical sizes, so it wraps regardless of the flex-grow that later
 * redistributes the leftover space.
 *
 * Fix: force the row to stay on one line above the kit's tablet breakpoint and
 * let it shrink instead of wrap — the copy column already carries
 * `min-width: 0`, so its paragraph reflows to more lines as the column
 * narrows rather than pushing the CTA row onto its own line.
 */
@media (min-width: 1001px) {
	.he-redesign .he-steps__foot {
		flex-wrap: nowrap !important;
	}
}

/* --- Home: testimonials --------------------------------------------------- */

.he-redesign .he-quotes:not(.he-native) {
	display: grid !important;
	grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}

/*
 * RENAMED from `.he-quote`, which the header's "Request a quote" BUTTON already
 * uses (build-header.php:276, the design's own name at :114). The collision was
 * not cosmetic: the header rule `@media (max-width:560px){.he-quote{display:none
 * !important}}` — meant to drop that one CTA on a phone — hid all four
 * testimonial cards, and the quote-glyph `::before` below painted a 34px green
 * ornament inside the header button. Two live defects from one shared name.
 */
.he-redesign .he-quotecard {
	min-width: 0 !important;
	transition: border-color 0.2s ease;
}

.he-redesign .he-quotecard:hover {
	border-color: var(--he-green) !important;
}

/*
 * The design's quote glyph (:508), as a ::before rather than an icon widget:
 * it is pure ornament and four of them would be four things in the panel a
 * client can delete by accident and never get back.
 *
 * NOTE: this file used to also carry a `.he-quote__q::before` rule painting
 * the design's five-star row (:513-515) as a repeating mask on the quote
 * text's own widget wrapper. build-home-page.php documents (delta #4) that
 * the stars are DELIBERATELY omitted — no rating data exists for these named
 * quotes — but the CSS still rendered them anyway, injected inside the quote
 * paragraph's own box rather than as a sibling flex item. That is the
 * client-reported "quote marks misplaced, spacing off" defect: an orphaned
 * rule for content the build deliberately doesn't emit, sitting inside the
 * text widget and pushing its content down by 17+16px with no flex `gap`
 * accounting for it. Removed; the card is icon-glyph -> quote -> name, each
 * spaced by the native 16px flex gap, matching the shipped content exactly.
 */
/*
 * `position: static` AND `order: -1` ARE THE FIX, NOT TIDINESS.
 *
 * `::before` on an Elementor CONTAINER is not a free pseudo-element: Elementor
 * owns it for the container background overlay and ships
 * `.e-con::before { position: absolute; inset: 0; ... }`. So this badge was
 * being laid out as an absolutely positioned box against the card's padding
 * box — out of flow, taking no space, sitting over the card's top-left corner
 * and bleeding across its border. That is the other half of the client's
 * "quotes are misplaced, padding/spacing is off": the glyph was in the wrong
 * place AND the 26px of top padding it should have been sitting inside was
 * being used by the quote text instead.
 *
 * Returning it to flow makes it a real flex item of the card, which is what
 * the design draws (:508 — first child, then the quote, then the name, on the
 * card's own 16px gap). `order: -1` keeps it first without depending on
 * pseudo-element ordering rules. The inset reset undoes Elementor's overlay
 * geometry; this selector is (0,2,1) and outranks `.e-con::before` at (0,1,1).
 *
 * The cost of borrowing this pseudo-element is that a background OVERLAY set
 * on these cards from the Elementor panel would no longer render. That is
 * acceptable for a testimonial card and is why it is written down here.
 */
.he-redesign .he-quotecard::before {
	content: "";
	position: static;
	inset: auto;
	order: -1;
	width: 34px;
	height: 34px;
	flex: 0 0 auto;
	background-color: var(--he-green-tint);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='%233f6300'%3E%3Cpath d='M7 7h4v4c0 2.8-1.7 4.6-4 5.4V14c1-.5 1.6-1.2 1.7-2H7V7zm7 0h4v4c0 2.8-1.7 4.6-4 5.4V14c1-.5 1.6-1.2 1.7-2H14V7z'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: center;
}

.he-redesign .he-quotecard .he-quote__n {
	margin-top: auto;
}

/* :915 — "Endless options" runs on 640px, not the testimonials' 560. */
.he-redesign .he-sectionhead--640 {
	max-width: 640px;
	margin-inline: auto;
}

.he-redesign .he-sectionhead--640 .he-h2 .elementor-heading-title,
.he-redesign .he-sectionhead--640 .he-lede {
	max-width: 640px;
}

/* The centred section head's measure (:504). */
.he-redesign .he-sectionhead--narrow {
	max-width: 560px;
}

.he-redesign .he-sectionhead--center.he-sectionhead--narrow {
	margin-inline: auto;
}

/* --- Home: showroom details (design :555-580) ----------------------------- */

/*
 * :578 — the phone number is `color:#fff;font-weight:700` in the design, on
 * the same #241f1c ink band as the rest of `.he-showroom__val`. The paragraph
 * widget's own `text_color` binds `che_white` (che-sections.php che_para_dark)
 * and does reach the surrounding text, but the KIT's Theme Style writes
 * `.elementor-kit-27618 a { color: #3f6300 }` — a direct match on the <a>
 * itself, which always beats an inherited value regardless of specificity.
 * #3f6300 (a dark green meant for links on the site's light bands) on #241f1c
 * is ~1.3:1 contrast, which is the "faded phone number" the client reported.
 * This is the same cascade gap already repaired for linked headings
 * (`.elementor-widget-heading .elementor-heading-title a { color: inherit }`
 * above) — text-editor widgets needed the same repair and never got it.
 * Scoped to this one link rather than every text-editor `<a>` site-wide, since
 * only this instance was audited against the design for this pass.
 */
.he-redesign .he-showroom__val a {
	color: var(--he-white);
	font-weight: 700;
}

.he-redesign .he-showroom__val a:hover {
	color: var(--he-green-bright);
}

/* --- The email-capture panel (design :541, :1374) ------------------------- */

.he-redesign .he-capture__panel:not(.he-native) {
	padding: clamp(22px, 2.6vw, 30px) !important;
}

.he-redesign .he-promos__subscribegrid {
	display: flex !important;
	justify-content: center;
}

.he-redesign .he-capture__panel--centred {
	max-width: 520px; /* :1375 */
	width: 100%;
	padding: clamp(24px, 3vw, 34px) !important;
}

.he-redesign .e-con .elementor-widget.he-capture__blurb {
	margin-block-end: 10px;
}

/*
 * The design draws this as an input and a button side by side (:546-549). The
 * Pro Form widget lays its field and its submit out through `column_gap` and
 * per-field `width`, and a one-field form puts the button on its own row; the
 * inline arrangement is the only thing here CSS has to do.
 */
.he-redesign .he-capture__form .elementor-form {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}

.he-redesign .he-capture__form .elementor-form-fields-wrapper {
	display: contents;
}

.he-redesign .he-capture__form .elementor-field-group {
	flex: 1 1 180px;
	padding: 0 !important;
	margin: 0 !important;
	max-width: none;
}

.he-redesign .he-capture__form .elementor-field-group-submit {
	flex: 0 0 auto;
}

.he-redesign .he-capture__form .elementor-field-textual {
	height: 48px;
	border: 1.5px solid var(--he-border-input);
}

.he-redesign .he-capture__form .elementor-button {
	height: 48px;
	padding: 0 22px;
}

/* --- Collection landings -------------------------------------------------- */

.he-redesign .he-crumbs__bar .he-crumbs {
	display: flex !important;
	flex-wrap: wrap;
	align-items: center;
	padding: 22px clamp(20px, 5vw, 48px) 6px; /* :771 */
}

/*
 * A crumb trail is a row at every width. When the trail is an e-con, the flex
 * row is its INNER wrapper, and Elementor auto-stacks that to column across
 * the tablet/mobile tiers — one crumb per line. Forced back to a wrapping row
 * here; the ≤560 guard below then turns the row into one scrollable line.
 */
.he-redesign .he-crumbs > .e-con-inner,
.he-redesign .he-crumbs__bar .he-crumbs > .e-con-inner {
	flex-direction: row !important;
	flex-wrap: wrap;
	align-items: center;
}

.he-redesign .he-crumbs__item + .he-crumbs__item::before {
	content: "/";
	margin-right: 9px;
	color: var(--he-text-softer);
}

.he-redesign .he-crumbs__item .elementor-heading-title {
	display: inline;
}

.he-redesign .he-crumbs__item {
	display: inline-flex !important;
	align-items: center;
	width: auto !important;
	flex: 0 0 auto !important;
}

.he-redesign .he-group__headcopy {
	max-width: 44em;
	min-width: 0 !important;
}

.he-redesign .he-group__grid .elementor-grid,
.he-redesign .he-blog__grid .elementor-grid {
	display: grid;
}

.he-redesign .he-subs__head {
	max-width: 44em;
	margin-bottom: 30px;
}

.he-redesign .he-subs__grid {
	display: grid !important;
	grid-template-columns: repeat(3, 1fr);
}

.he-redesign .he-subcard {
	min-width: 0 !important;
	transition: border-color 0.2s ease, transform 0.2s ease;
}

.he-redesign .he-subcard:hover {
	border-color: var(--he-green) !important;
	transform: translateY(-3px);
}

.he-redesign .e-con .elementor-widget.he-chooser__h2 {
	margin-block-end: 26px; /* :1622 */
}

@media (max-width: 1000px) {
	.he-redesign .he-subs__grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 560px) {
	.he-redesign .he-subs__grid {
		grid-template-columns: 1fr;
	}
}

/* --- Built-to-order option cards (design :920-931) ------------------------ */

.he-redesign .he-btogrid {
	display: grid !important;
	grid-template-columns: repeat(2, 1fr);
}

.he-redesign .he-btocard {
	min-width: 0 !important;
	overflow: hidden;
	transition: border-color 0.2s ease;
}

.he-redesign .he-btocard:hover {
	border-color: var(--he-green) !important;
}

.he-redesign .he-btocard__img img {
	width: 100%;
	aspect-ratio: 1024 / 389; /* :923 */
	object-fit: cover;
	display: block;
}

@media (max-width: 1000px) {
	.he-redesign .he-btogrid {
		grid-template-columns: 1fr;
	}
}

/* The icon chips on the Made-in-Canada pillars (design :1132, :1137). */
.he-redesign .he-iconchip .elementor-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	background: var(--he-green);
}

.he-redesign .he-iconcol {
	min-width: 0 !important;
}

/* --- Brands --------------------------------------------------------------- */

.he-redesign .he-brands__grid {
	display: grid !important;
	grid-template-columns: repeat(2, 1fr);
}

.he-redesign .he-brand {
	min-width: 0 !important;
	transition: border-color 0.2s ease;
}

.he-redesign .he-brand:hover {
	border-color: var(--he-green) !important;
}

.he-redesign .he-brand__head {
	display: flex !important;
	align-items: center;
	flex-wrap: nowrap;
}

.he-redesign .he-brand__initial {
	flex: 0 0 auto !important;
	width: auto !important;
}

.he-redesign .he-brand__initial .elementor-heading-title {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	background: var(--he-green-tint);
}

.he-redesign .he-brand__name {
	min-width: 0 !important;
}

.he-redesign .he-brand__more {
	margin-top: auto;
	padding-top: 4px;
}

@media (max-width: 1000px) {
	.he-redesign .he-brands__grid {
		grid-template-columns: 1fr;
	}
}

/* --- FAQ ------------------------------------------------------------------ */

/*
 * The Nested Accordion's own controls carry the type, both colours and the
 * item spacing. What is left is the card box the design draws around each
 * question, which the widget has no control for at item level.
 */
.he-redesign .he-faq__list .e-n-accordion-item {
	background: #ffffff;
	border: 1px solid var(--he-border);
	overflow: hidden;
	transition: border-color 0.2s ease;
}

.he-redesign .he-faq__list .e-n-accordion-item:hover {
	border-color: var(--he-green);
}

.he-redesign .he-faq__list .e-n-accordion-item-title {
	padding: 20px 24px; /* :1265 */
}

.he-redesign .he-faq__list .e-n-accordion-item[open] > .e-n-accordion-item-title {
	border-bottom: 1px solid #f2ebe0;
}

.he-redesign .he-faq__list .e-n-accordion-item > .e-con {
	padding: 16px 24px 22px; /* :1270 */
}

.he-redesign .he-faq__list .e-n-accordion-item-title-icon {
	width: 30px;
	height: 30px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: var(--he-green-tint);
	flex: 0 0 auto;
}

.he-redesign .he-faq__a + .he-faq__a {
	margin-top: 16px;
}

/* --- Promotions ----------------------------------------------------------- */

.he-redesign .he-promogrid {
	display: grid !important;
	grid-template-columns: repeat(4, 1fr);
}

.he-redesign .he-promos__shotwell {
	min-width: 0 !important;
	overflow: hidden;
}

.he-redesign .he-promos__shot img {
	width: 100%;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	display: block;
}

.he-redesign .he-promos__img img {
	height: auto;
	aspect-ratio: auto;
}

.he-redesign .he-promos__story .he-split__media img {
	aspect-ratio: auto;
	height: auto;
}

@media (max-width: 1000px) {
	.he-redesign .he-promogrid {
		grid-template-columns: repeat(2, 1fr);
	}
}

/* :94 — the promo grid is 1-up from 760, not from 560. */
@media (max-width: 760px) {
	.he-redesign .he-promogrid {
		grid-template-columns: 1fr;
	}
}

/* --- Contact -------------------------------------------------------------- */

.he-redesign .he-contact__cards {
	margin-bottom: clamp(36px, 5vw, 56px);
}

.he-redesign .he-contact__photo {
	position: relative;
	aspect-ratio: 21 / 8; /* :1447 */
	display: flex;
	align-items: flex-end;
	overflow: hidden;
}

.he-redesign .he-contact__photocaption {
	position: relative;
	z-index: 1;
	padding: clamp(18px, 2.4vw, 28px) clamp(20px, 3vw, 34px);
}

@media (max-width: 760px) {
	.he-redesign .he-contact__photo {
		aspect-ratio: 4 / 3;
	}
}

/* --- Blog index ----------------------------------------------------------- */

.he-redesign .he-feat__grid {
	margin-bottom: 26px; /* :1493 */
}

.he-redesign .he-feat {
	display: grid !important;
	grid-template-columns: 1.15fr 1fr; /* :1493 */
	gap: clamp(24px, 3.5vw, 48px);
	align-items: center;
	overflow: hidden;
}

.he-redesign .he-feat > .e-con-inner {
	display: contents;
}

.he-redesign .he-feat__well,
.he-redesign .he-feat__body {
	min-width: 0 !important;
}

.he-redesign .he-feat__img img {
	width: 100%;
	aspect-ratio: 16 / 11; /* :1494 */
	object-fit: cover;
	display: block;
}

.he-redesign .he-feat__cta .elementor-button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

.he-redesign .he-bcard {
	overflow: hidden;
	height: 100%;
	transition: transform 0.2s ease;
}

.he-redesign .he-bcard:hover {
	transform: translateY(-3px);
}

.he-redesign .he-bcard__img img {
	width: 100%;
	aspect-ratio: 4 / 3; /* :1510 */
	object-fit: cover;
	display: block;
}

.he-redesign .he-bcard__body {
	flex: 1;
}

.he-redesign .he-bcard__more {
	margin-top: auto;
	padding-top: 4px;
}

@media (max-width: 900px) {
	.he-redesign .he-feat {
		grid-template-columns: 1fr;
	}

	.he-redesign .he-feat__body {
		padding: clamp(20px, 4vw, 28px) !important;
	}
}

/* :134 — the featured card's body takes its own padding at phone. */
@media (max-width: 560px) {
	.he-redesign .he-feat__body {
		padding: 22px 20px 26px !important;
	}
}

/* --- Single post ---------------------------------------------------------- */

.he-redesign .he-post__head .he-eyebrow {
	margin-bottom: 12px;
}

.he-redesign .he-post__date {
	margin-top: 14px;
}

.he-redesign .he-post__img img {
	width: 100%;
	aspect-ratio: 16 / 9;
	object-fit: cover;
	display: block;
	margin-bottom: 32px;
}

/*
 * The post body is whatever the client wrote. Type and colour come from the
 * widget's bound globals and the kit's Theme Style; only the rhythm between
 * blocks is here, because `theme-post-content` has no control for it.
 */
.he-redesign .he-post__body p + p,
.he-redesign .he-post__body ul,
.he-redesign .he-post__body ol,
.he-redesign .he-post__body blockquote {
	margin-top: 18px;
}

.he-redesign .he-post__body img {
	max-width: 100%;
	height: auto;
}

/* --- CTA colourways added in Step 4 --------------------------------------- */

/*
 * `--outline-light` is the outline button on a dark band (:347, :468, :1332).
 * Its translucent fill and its white border are both rgba values the kit holds
 * no swatch for; its TEXT colour is bound on the widget.
 */
/*
 * :347 — a 10%-white fill, a 42%-white hairline and a 6px backdrop blur. All
 * three are alphas/filters with no kit swatch and no widget control. Height and
 * inline padding ARE controls and are set on the widget (`text_padding`).
 *
 * Worth recording why this button "was invisible": these values are correct and
 * always were. They read as nothing against an unmasked photograph, which is
 * what the hero was while its scrim was `display: none` — a symptom of the
 * ::before collision, not of the button.
 */
.he-redesign .he-cta--outline-light .elementor-button {
	background: rgba(255, 255, 255, 0.1);
	border: 1.5px solid rgba(255, 255, 255, 0.42);
	-webkit-backdrop-filter: blur(6px);
	backdrop-filter: blur(6px);
}

.he-redesign .he-cta--outline-light .elementor-button:hover,
.he-redesign .he-cta--outline-light .elementor-button:focus {
	background: rgba(255, 255, 255, 0.2);
	border-color: #ffffff;
}

/*
 * :1332 — the Promotions hero's secondary CTA is `background:transparent` with
 * no blur, where `he-cta--outline-light` is the HOME hero's 10%-white-over-a-
 * photograph treatment. Same border and text colour, no fill. The Promotions
 * CTA carries BOTH classes, so at equal specificity this has to sit AFTER the
 * outline-light resting rule above to win; it must not move earlier in the file.
 */
.he-redesign .he-cta--ghost .elementor-button {
	background: transparent;
	-webkit-backdrop-filter: none;
	backdrop-filter: none;
}

/*
 * The Promotions hero's ghost CTA (`he-cta--ghost`, :1332) carries this class
 * alongside `he-cta--outline-light` and had no hover of its own — so on hover
 * it silently took the outline-light rule above instead, which is a different
 * design value (:347/:468 vs :1332). Equal specificity, so this has to sit
 * AFTER the outline-light hover to win; it must not move earlier in the file.
 */
.he-redesign .he-cta--ghost .elementor-button:hover,
.he-redesign .he-cta--ghost .elementor-button:focus {
	background: rgba(255, 255, 255, 0.14); /* :1332 style-hover */
	border-color: #ffffff;
}

/*
 * The phone CTA carries the design's green handset glyph before its label
 * (:537, :977). Its colours are the outline colourway's, bound on the widget.
 */
.he-redesign .he-cta--phone .elementor-button-text::before {
	content: "";
	display: inline-block;
	vertical-align: -3px;
	margin-right: 9px;
	width: 18px;
	height: 18px;
	background-color: var(--he-green);
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.9.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92z'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.9.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92z'/%3E%3C/svg%3E") center / contain no-repeat;
}

/*
 * The red colourway's hover. Its NORMAL background and label are bound to
 * che_red / che_white on the widget, and its hover BACKGROUND is bound to
 * che_red_hover — so there is nothing left here. Recorded as a deliberate
 * absence so nobody adds a CSS copy of a kit value back in.
 */

/* --------------------------------------------------------------------------
   LITERALS REMAINING IN §10, AND WHY EACH ONE CANNOT BIND

   | rule                             | literal                  | reason
   |----------------------------------|--------------------------|--------
   | .he-hero__badge chip background  | var(--he-white) (client directive, was var(--he-green)) | a heading widget's background control paints the full-width wrapper; the chip must be inline-flex on the title element, which no control reaches (same exception as .he-eyebrow)
   | .he-steps__num square            | var(--he-green)          | as above
   | .he-brand__initial chip          | var(--he-green-tint)     | as above
   | .he-iconchip square              | var(--he-green)          | the icon widget's own background control paints the wrapper, not the 44px box
   | .he-faq__list item box + hover   | #fff / --he-border / --he-green | the Nested Accordion styles the ACCORDION, not the item card; there is no per-item background or border control
   | .he-faq__list open separator     | #f2ebe0                  | :1270, a one-off tint with no kit swatch
   | .he-quotecard / .he-subcard / .he-brand / .he-btocard :hover border | var(--he-green) | a container's border control has no hover state
   | .he-stats__bar background        | rgba(20,16,13,.94)       | alpha; the kit holds no translucent swatches
   | .he-rooms tile scrim             | rgba gradient            | alpha, and it is a gradient over a photograph
   | .he-cta--outline-light fill+border | rgba(255,255,255,.10/.42) | alpha
   | .he-promos__hero foot rule       | --he-red / --he-red-light gradient | one edge, above the container's own overlay; the border control paints four sides under it
   | tick / arrow / quote / phone glyphs | inline data: URIs     | ornament with no widget behind it; the arrow and phone masks take `currentColor`, so they follow the bound colour rather than carrying one

   Every one of these is the same class of exception §8 and §9 already carry.
   Nothing here is a copy of a value the kit holds and a widget could bind.
   -------------------------------------------------------------------------- */


/* ==========================================================================
   NATIVE GRAMMAR — what is left over after the controls
   --------------------------------------------------------------------------
   Everything a rebuilt (`.he-native`) section can express as an Elementor
   container setting now IS one: padding, margin, gap, direction, wrap,
   justification, alignment, grid template, min-height, borders and background.
   What remains here has no control at all:

     - type MEASURES, which live on `.elementor-heading-title` and on the
       paragraph inside a text-editor, neither of which any control reaches;
     - `backdrop-filter`, which Elementor has no control for;
     - `:first-child` / `:last-child` rules, which no container control can
       express;
     - pseudo-element decoration that carries no content.

   Nothing below sets display, flex-direction, gap or padding on a `.he-native`
   container. If a future edit needs one of those, it is a setting, not a rule.
   ========================================================================== */

/* :403 — "There's a difference when it's made here." */
.he-redesign .he-mic__h2 .elementor-heading-title {
	max-width: 18em;
}

/* :530 — "See the finishes & fabrics in person." */
.he-redesign .he-visit__h2 .elementor-heading-title {
	max-width: 16em;
}

/* :532 — the Visit-us lede runs one em wider than the 34em default. */
.he-redesign .he-visit__lede {
	max-width: 36em;
}

/* :466 — the how-it-works foot copy. */
.he-redesign .he-steps__footcopy {
	max-width: 40em;
}

/*
 * :355 — the hairline between the stats label and the figures, hidden below
 * 1040px. It is a 1px rule with no content, so it is a pseudo-element rather
 * than an empty widget in the client's panel.
 *
 * CORRECTION 2026-08-25 — `::before` on an Elementor container is Elementor's
 * own background overlay: `position:absolute; inset:0`. That rule won, so this
 * hairline was painted at the group's left edge with the flex properties and
 * the margin doing nothing at all, and "35+ years in business" sat flush
 * against it. Resetting position/inset is what makes it a real flex item; the
 * cost of borrowing the pseudo-element is that a panel-set container overlay
 * stops rendering here. The group's own 40px column gap now applies between
 * the hairline and the first figure, so 4px of margin completes the design's
 * 44px (:355) — the earlier 44px would have stacked on top of the gap.
 */
.he-redesign .he-stats__group.he-native::before {
	content: "";
	position: static;
	inset: auto;
	order: -1;
	flex: 0 0 auto;
	align-self: center;
	width: 1px;
	height: 34px;
	background: rgba(255, 255, 255, 0.18);
	margin-inline-end: 4px;
}

@media (max-width: 1040px) {
	.he-redesign .he-stats__group.he-native::before {
		display: none;
	}
}

/*
 * CLIENT 2026-08-25: the trust bar under the header "looks underwhelming
 * stacked/left aligned" on a phone, with a note to check whether it was just
 * broken. It was NOT broken — the build matches the design exactly (:110-112:
 * `gap:12px 0`, `justify-content:flex-start`, figures wrapping at `12px 22px`).
 * The design simply does not survive the content: at 430px the three figures
 * measure 190/200/175px against 386px of usable width, so every one of them
 * takes its own line and the band reads as a four-line left-aligned list.
 *
 * So this is a deliberate departure from the design, on the client's invitation
 * to "restyle all together":
 *
 *  - The long label is dropped below 560. "Trusted locally for over 35 years"
 *    and "35+ years in business" are the same claim twice; the client's own
 *    suggestion was to keep the 35+ figure. Losing the duplicate is what buys
 *    the room for everything else.
 *  - The figures become a three-up row with the number stacked over its unit
 *    and hairline separators between them — the same hairline the desktop bar
 *    uses between label and figures, reused rather than invented.
 *
 * Above 560 nothing changes: the design's row is intact and correct there.
 */
@media (max-width: 560px) {
	.he-redesign .he-stats__label {
		display: none !important;
	}

	.he-redesign .he-stats__group.he-native {
		display: grid !important;
		grid-template-columns: repeat(3, 1fr) !important;
		gap: 0 !important;
		align-items: center !important;
		width: 100% !important;
	}

	.he-redesign .he-stats__item {
		display: flex !important;
		flex-direction: column !important;
		align-items: center !important;
		justify-content: center !important;
		gap: 2px !important;
		text-align: center;
		padding-inline: 6px;
	}

	.he-redesign .he-stats__item + .he-stats__item {
		border-inline-start: 1px solid rgba(255, 255, 255, .18);
	}

	.he-redesign .he-stats__unit .elementor-heading-title {
		line-height: 1.25;
	}
}

/*
 * THE KIT'S MOBILE BREAKPOINT IS 560, NOT 767. The comment that used to sit
 * here said 767 and this query was written to match it; `viewport_mobile` on
 * kit 27618 is 560 (`viewport_md: 768` is a legacy leftover that governs
 * Elementor's own stock container CSS, not the responsive controls). So
 * `grid_columns_grid_mobile` collapses these groups at 560 while the divider
 * flip below fired at 767 — and between 561 and 767 the ruled groups rendered
 * three columns wide with no vertical dividers AND no gutters, text jammed
 * edge to edge. Measured at 700px: three 210px columns, padding 0, no
 * right border.
 *
 * The divider flip now runs to the design's own 820 (:46, :49), together with a
 * hand-authored column collapse for the 561-820 band — see §"THE DESIGN'S OWN
 * BREAKPOINTS" for why that band is hand-written and why it starts at 561
 * rather than 0.
 */
@media (max-width: 820px) {
	.he-redesign .he-ruled__col.he-native {
		border-right: none;
		border-bottom: 1px solid var(--he-border-input);
		padding-left: 0;
		padding-inline-start: 0;
		padding-right: 0;
		padding-inline-end: 0;
	}

	.he-redesign .he-ruled--dark .he-ruled__col.he-native {
		border-bottom-color: var(--he-border-on-ink);
	}

	.he-redesign .he-ruled__col.he-native:last-child {
		border-bottom: none;
	}
}


/* ==========================================================================
   THE DESIGN'S OWN BREAKPOINTS  (design :30-51, :91-151)
   --------------------------------------------------------------------------
   The design steps at EIGHT widths — 1040, 1000, 900, 820, 760, 640, 560, 380.
   Elementor gives a kit two: `viewport_tablet` (1000 here) and `viewport_mobile`
   (560). See note 114. Every responsive CONTROL in the builders therefore lands
   on 1000 or 560 and nowhere else, so the design's 900 / 820 / 760 / 640 / 380
   steps have to be hand-written here or they do not exist.

   Two rules for everything in this section, and they are what keep it honest:

   1. **Band-scope the query to the gap the controls cannot reach.** Where a
      control already owns ≤560, the query starts at `min-width: 561px`. That way
      the client's own responsive control still owns the phone tier and this file
      only fills the band between Elementor's two tiers. A bare `max-width: 820px`
      would silently take the column count out of the panel at every width below
      it.
   2. **Columns and their gutters/dividers move together.** Splitting them across
      two breakpoints is what produced the 561-767 ruled-column window where the
      groups rendered three-up with no dividers and no gutters (note 114).

   NOT ported, deliberately, with the reason stated at each:

   - **`.he-hide-sm` / `.he-only-sm` at 1040/1041** (:28-29), which the build runs
     at 1000/1001. On Elementor 4.2.2 the Pro Nav Menu widget switches at the
     kit's tablet breakpoint (1000px), and no hand-authored query can move that
     without moving the kit tier for everything else. Matching the design's 1040
     would hide the desktop nav between 1001 and 1040 while the Pro widget was
     still in desktop mode — a burger that is not there and a menu that is. The
     40px window is a smaller defect than the one the "fix" creates.
   - **The design's two re-widening rules.** `.he-why` goes 2-up at ≤1000 (:33),
     1-up at ≤820 (:47), then BACK to 2-up at ≤760 (:95), then 1-up at ≤640 (:48);
     `.he-brands` goes 1-up at ≤1000 (:33), back to 2-up at ≤760 (:95), then 1-up
     at ≤560 (:101). Both re-widens come from the ≤760 block sitting later in the
     design's own source and winning at equal specificity — an artefact of how the
     stylesheet is ordered, not an instruction. Shipping them literally would put
     a two-column band inside a one-column range. The monotonic reading is built
     instead.
   ========================================================================== */

/* --- ≤1000: the tier Elementor DOES own, for the two grids it cannot reach -- */

/*
 * :33 — `.he-why` is 2-up from 1000. It is a hand-written CSS grid (not a
 * container control), so it needs the step written here; it was 3-up all the way
 * down to 820.
 */
/*
 * BAND-SCOPED, and it has to be. This section sits near the end of the file, so
 * a bare `max-width: 1000px` here would out-order `.he-why`'s own 1-up rule at
 * 820 and its 1-up-at-640 step, and the About page's six points would render
 * two-up all the way down to 320. Same reason for the `.he-feat` body padding:
 * the design's ≤560 value (:134) lives earlier in this file.
 */
@media (min-width: 821px) and (max-width: 1000px) {
	.he-redesign .he-why {
		grid-template-columns: repeat(2, 1fr);
	}

	.he-redesign .he-why .he-ticks__item:nth-child(3n) {
		border-right: 1px solid var(--he-border-on-ink);
		padding-right: 32px;
	}

	.he-redesign .he-why .he-ticks__item:nth-child(2n) {
		border-right: none;
		padding-right: 0;
	}

	.he-redesign .he-why .he-ticks__item:nth-child(2n + 1) {
		padding-left: 0;
	}

}

/* :34 — the featured blog card stacks at 1000, not at 900. */
@media (max-width: 1000px) {
	.he-redesign .he-feat {
		grid-template-columns: 1fr;
	}
}

@media (min-width: 561px) and (max-width: 1000px) {
	.he-redesign .he-feat__body {
		padding: 0 clamp(22px, 4vw, 32px) clamp(26px, 4vw, 34px) !important;
	}
}

/* --- 561-820: the ruled column groups (:46, :49) ------------------------- */

/*
 * The dividers already flip at 820 (see §"NATIVE GRAMMAR"). This is the column
 * count for the same band. Below 561 `grid_columns_grid_mobile` owns it, which
 * is why the query stops there.
 */
@media (min-width: 561px) and (max-width: 820px) {
	.he-redesign .he-ruled.he-native > .e-con-inner,
	.he-redesign .he-ruled.he-native {
		--e-con-grid-template-columns: 1fr;
		grid-template-columns: 1fr;
	}

	/* :40 — `.he-canada` collapses at 820 and the photograph goes ABOVE the
	   copy. `_flex_order_mobile` on the media column only reaches ≤560. */
	.he-redesign .he-mic__grid.he-native > .e-con-inner,
	.he-redesign .he-mic__grid.he-native {
		--e-con-grid-template-columns: 1fr;
		grid-template-columns: 1fr;
	}

	.he-redesign .he-mic__grid > .e-con-inner > .he-split__media,
	.he-redesign .he-mic__grid > .he-split__media {
		order: -1;
	}
}

/* --- 561-760: the section rhythm (:93) ----------------------------------- */

/*
 * `.he-rise{padding-block: clamp(48px,10vw,64px)}`. The bands carry this as a
 * native `padding_mobile`, which fires at ≤560, so 561-760 kept the desktop
 * `clamp(64px,8vw,120px)`. Written as the two custom properties Elementor's own
 * boxed-container rules consume (`--padding-top` feeds `--padding-block-start`,
 * which is what lands on `.e-con-inner`) rather than as `padding`, so the box
 * model stays Elementor's and only the value changes.
 */
@media (min-width: 561px) and (max-width: 760px) {
	.he-redesign .e-con.he-band__inner {
		--padding-top: clamp(48px, 10vw, 64px);
		--padding-bottom: clamp(48px, 10vw, 64px);
	}

	/* :94 — the promo grid is 1-up from 760. */
	.he-redesign .he-promogrid {
		grid-template-columns: 1fr;
	}
}

/* --- 561-640: the blog grid (:106) --------------------------------------- */

/*
 * `.he-blog` is 1-up from 640; the loop grid's `columns_mobile` only reaches
 * 560, so 561-640 rendered two ~270px cards.
 */
@media (min-width: 561px) and (max-width: 640px) {
	.he-redesign .he-blog__grid .elementor-grid {
		grid-template-columns: 1fr;
	}
}

/* --- ≤380: the small-phone block (:149-151) ------------------------------ */

/*
 * The two grids the design tightens once more below 380. Neither has a control
 * at this width — Elementor's tiers stop at 560 — so both are written here.
 */
@media (max-width: 380px) {
	.he-redesign .he-chooser__grid ul.products {
		grid-template-columns: 1fr;
	}

	.he-redesign .attribute_subtype .attribute_subtype_options,
	.he-redesign .attribute_subtype_wrapper .attribute_subtype .attribute_subtype_options {
		grid-template-columns: repeat(2, 1fr);
	}
}


/* ==========================================================================
   SCROLL REVEAL + FILM GRAIN (design :56-77, :158)
   --------------------------------------------------------------------------
   Two whole systems the design specifies and the build did not have at all.
   Both are pure presentation with no content behind them, so both are CSS plus
   (for the reveal) one IntersectionObserver in `che-redesign.js`.

   THE ARMING CONTRACT IS THE DESIGN'S OWN, and it is the reason nothing here is
   `opacity: 0` by default. The design's comment at :56 reads "armed by JS only
   for below-fold blocks — if the runtime never runs, nothing is hidden". So the
   hidden state is `.he-rise.he-armed:not(.he-in)`: a script failure, a blocked
   file or a crawler with no JS sees every band at full opacity rather than a
   blank page. Do not "simplify" this to `.he-rise{opacity:0}`.
   ========================================================================== */

@keyframes heRise {
	from { opacity: 0; transform: translateY(22px); }
	to   { opacity: 1; transform: none; }
}

@keyframes heFadeUp {
	from { opacity: 0; transform: translateY(16px); }
	to   { opacity: 1; transform: none; }
}

@keyframes heHeroIn {
	from { opacity: 0; transform: translateY(14px); }
	to   { opacity: 1; transform: none; }
}

.he-redesign .he-rise.he-armed:not(.he-in) {
	opacity: 0;
}

.he-redesign .he-rise.he-in {
	animation: heRise .8s cubic-bezier(.22, .61, .36, 1) both;
}

/* Children of a revealed block fade up in sequence (:60-61). */
.he-redesign .he-rise.he-in .he-stagger > *,
.he-redesign .he-rise.he-in .he-stagger.he-rooms__grid ul.products > li {
	animation: heFadeUp .7s cubic-bezier(.22, .61, .36, 1) both;
}

.he-redesign .he-rise.he-armed:not(.he-in) .he-stagger > *,
.he-redesign .he-rise.he-armed:not(.he-in) .he-stagger.he-rooms__grid ul.products > li {
	opacity: 0;
}

/*
 * The rooms grid is a WIDGET, so `.he-stagger > *` reaches its single
 * `.elementor-widget-container`, not the six tiles. WooCommerce's own `<li>`s
 * are the real children, hence the second selector in each rule above and the
 * nth-child aliases below.
 */
.he-redesign .he-stagger.he-rooms__grid ul.products > li:nth-child(1) { animation-delay: .06s; }
.he-redesign .he-stagger.he-rooms__grid ul.products > li:nth-child(2) { animation-delay: .13s; }
.he-redesign .he-stagger.he-rooms__grid ul.products > li:nth-child(3) { animation-delay: .2s; }
.he-redesign .he-stagger.he-rooms__grid ul.products > li:nth-child(4) { animation-delay: .27s; }
.he-redesign .he-stagger.he-rooms__grid ul.products > li:nth-child(5) { animation-delay: .34s; }
.he-redesign .he-stagger.he-rooms__grid ul.products > li:nth-child(6) { animation-delay: .41s; }
.he-redesign .he-stagger.he-rooms__grid ul.products > li:nth-child(n+7) { animation-delay: .46s; }

.he-redesign .he-stagger > *:nth-child(1) { animation-delay: .06s; }
.he-redesign .he-stagger > *:nth-child(2) { animation-delay: .13s; }
.he-redesign .he-stagger > *:nth-child(3) { animation-delay: .2s; }
.he-redesign .he-stagger > *:nth-child(4) { animation-delay: .27s; }
.he-redesign .he-stagger > *:nth-child(5) { animation-delay: .34s; }
.he-redesign .he-stagger > *:nth-child(6) { animation-delay: .41s; }
.he-redesign .he-stagger > *:nth-child(n+7) { animation-delay: .46s; }

/*
 * :72-75 — the hero's own entrance. The design puts `.he-hero-in` on the chip,
 * the H1 and the CTA row; here they are simply the three children of
 * `.he-hero__copy`, so the delays key off nth-child and no markup carries an
 * animation class. Above the fold, so it runs on load with no observer.
 *
 * The design also Ken-Burnses the hero PHOTOGRAPH (`heKen`, :76). Not built:
 * the photo is a container background, not an `<img>`, and there is no element
 * to transform. Reported rather than faked with a wrapper.
 */
.he-redesign .he-hero__copy > * {
	animation: heHeroIn .7s cubic-bezier(.22, .61, .36, 1) both;
}

.he-redesign .he-hero__copy > *:nth-child(1) { animation-delay: .05s; }
.he-redesign .he-hero__copy > *:nth-child(2) { animation-delay: .16s; }
.he-redesign .he-hero__copy > *:nth-child(3) { animation-delay: .27s; }

@media (prefers-reduced-motion: reduce) {
	.he-redesign .he-rise,
	.he-redesign .he-rise.he-armed,
	.he-redesign .he-rise.he-in,
	.he-redesign .he-hero__copy > *,
	.he-redesign .he-stagger > *,
	.he-redesign .he-rise.he-armed:not(.he-in) .he-stagger > *,
	.he-redesign .he-stagger.he-rooms__grid ul.products > li {
		animation: none !important;
		opacity: 1 !important;
		transform: none !important;
	}
}

/*
 * :158 / :163 — a fixed fractal-noise layer over the whole page at .045.
 * `pointer-events:none` so it never intercepts a click, and z-index 1 keeps it
 * under the sticky header (z-index 50) and the drawer, exactly as the design
 * stacks it. Printed by `che_redesign_grain()` in includes/redesign.php.
 */
.he-redesign .he-grain {
	position: fixed;
	inset: 0;
	z-index: 1;
	pointer-events: none;
	opacity: .045;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

@media print {
	.he-redesign .he-grain { display: none; }
}

/* --- The 404 and the search page (no design view; composed from the grammar) - */

/*
 * Two rules, and they are the only two either template needs. Everything else
 * on them -- type, colour, the 1.5px hairline, the 48px box, radius 0 -- is a
 * bound CONTROL on the search widget, so the client can change it in the panel.
 *
 * `.he-search__box` is the same widget in the same shape on the search page's
 * empty and prompt bands, so it shares the rules rather than restating them.
 *
 * The measure cannot be: the widget's own width control is a flex/grid keyword
 * (`_element_width`), not a length, and a search box run to the full 1104px
 * band is a 1104px-wide input. 520px is the width the capture panel already
 * uses for the same shape (`.he-capture__panel--centred`, :1375).
 */
.he-redesign .he-404__search,
.he-redesign .he-search__box {
	max-width: 520px;
	width: 100%;
}

/*
 * Focus lands on the INPUT, and the border being styled is on its parent, so
 * the ring has to come from the container. Same values as `.he-ask__form`.
 */
.he-redesign .he-404__search .elementor-search-form__container:focus-within,
.he-redesign .he-search__box .elementor-search-form__container:focus-within {
	border-color: var(--he-green);
	outline: 2px solid rgba(118, 187, 0, .25);
	outline-offset: 0;
}

/* ==========================================================================
   HEADER SEARCH OVERLAY — client directive 2026-08-25
   --------------------------------------------------------------------------
   Markup: includes/search-overlay.php. Behaviour: initSearch() in
   che-redesign.js. The client asked for search to happen on the page instead
   of navigating to `/?s=`; this is the surface that does it.

   The design has no search overlay to copy — the prototype's icon is inert
   (:208-210) — so every value here is borrowed from a component the design DOES
   specify rather than invented: the scrim from the mobile drawer (:262), the
   panel surface and border from the mega panel (:217), the input frame from the
   quote form's fields, the row hover from the About Us dropdown (:192-196).
   ========================================================================== */

.he-search-open,
.he-search-open body {
	overflow: hidden;
}

.he-search-overlay[hidden] {
	display: none;
}

.he-search-overlay {
	position: fixed;
	inset: 0;
	z-index: 90;
}

.he-search-overlay__scrim {
	position: absolute;
	inset: 0;
	background: rgba(20, 16, 13, .55);
	backdrop-filter: blur(2px);
	opacity: 0;
	transition: opacity .2s ease;
}

.he-search-overlay--open .he-search-overlay__scrim {
	opacity: 1;
}

/*
 * Top-anchored, full-bleed: the panel reads as the header growing downwards,
 * which is where the control that opened it lives. A centred modal would
 * detach the search from its own trigger.
 */
.he-search-overlay__panel {
	position: relative;
	background: var(--he-offwhite);
	border-bottom: 1px solid var(--he-border-header);
	box-shadow: 0 18px 40px -12px rgba(20, 16, 13, .32);
	max-height: 100%;
	overflow-y: auto;
	transform: translateY(-14px);
	opacity: 0;
	transition: transform .2s cubic-bezier(.22, .61, .36, 1), opacity .2s ease;
}

.he-search-overlay--open .he-search-overlay__panel {
	transform: none;
	opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
	.he-search-overlay__scrim,
	.he-search-overlay__panel {
		transition: none;
	}
}

.he-search-overlay__inner {
	max-width: var(--he-container);
	margin-inline: auto;
	padding: 22px clamp(20px, 5vw, 48px) 28px;
}

/* --- the field ---------------------------------------------------------- */

.he-search-form {
	display: flex;
	align-items: center;
	gap: 10px;
	border-bottom: 1.5px solid var(--he-ink);
	padding-bottom: 10px;
}

.he-search-form__icon {
	flex: 0 0 auto;
	display: inline-flex;
	color: var(--he-ink);
}

/*
 * `.he-search-form__input` needs its own reset: Hello Elementor and the Kit
 * both style bare inputs, and a search input additionally gets a UA-drawn
 * clear affordance in WebKit that would sit next to this component's own.
 */
/*
 * The extra `.he-search-overlay` is doing the same job it does on the buttons
 * above: Hello Elementor and the Kit both carry `input[type="search"]` rules
 * that are (0,1,1) and outrank a lone class, and what they draw is a bordered,
 * padded field box inside this component's own underline — a frame within a
 * frame.
 */
.he-search-overlay .he-search-form__input {
	flex: 1 1 auto;
	min-width: 0;
	border: none;
	background: transparent;
	padding: 0;
	font-family: var(--e-global-typography-che_h2_open-font-family, "Archivo"), sans-serif;
	font-size: clamp(20px, 3vw, 28px);
	font-weight: 600;
	line-height: 1.2;
	color: var(--he-text-strong);
	box-shadow: none;
	appearance: none;
	border-radius: 0;
	height: auto;
}

.he-search-overlay .he-search-form__input:focus {
	outline: none;
	box-shadow: none;
}

.he-search-overlay .he-search-form__input::placeholder {
	color: #9c9385;
}

.he-search-overlay .he-search-form__input::-webkit-search-cancel-button,
.he-search-overlay .he-search-form__input::-webkit-search-decoration {
	appearance: none;
}

/*
 * These two are `<button>` elements inside a form, so the Kit's
 * `.elementor-kit-NNNN button` rule paints them solid Accent green with 18/28
 * padding — the same trap the drawer rows document. The extra
 * `.he-search-overlay` class is what outranks it.
 */
.he-search-overlay .he-search-form__clear,
.he-search-overlay .he-search-overlay__close {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	padding: 0;
	border: none;
	border-radius: 0;
	background: transparent;
	color: var(--he-text-body);
	cursor: pointer;
	transition: background .18s, color .18s;
}

.he-search-overlay .he-search-overlay__close {
	background: var(--he-sand);
	color: var(--he-ink);
}

.he-search-overlay .he-search-form__clear[hidden] {
	display: none;
}

@media (hover: hover) and (pointer: fine) {
	.he-search-overlay .he-search-form__clear:hover,
	.he-search-overlay .he-search-form__clear:focus-visible,
	.he-search-overlay .he-search-overlay__close:hover,
	.he-search-overlay .he-search-overlay__close:focus-visible {
		background: #e6dcca;
		color: var(--he-ink);
	}
}

/* --- body: prompt, status, results -------------------------------------- */

.he-search-overlay__body {
	padding-top: 16px;
}

.he-search-shortcuts {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 10px;
}

.he-search-shortcuts[hidden] {
	display: none;
}

.he-search-shortcuts__label {
	font-size: 12px;
	font-weight: 700;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: #7d7466;
	margin-inline-end: 4px;
}

.he-search-shortcuts__link {
	display: inline-flex;
	align-items: center;
	min-height: 34px;
	padding: 0 12px;
	border: 1px solid var(--he-border-line);
	font-size: 14px;
	font-weight: 600;
	color: var(--he-text-body);
	transition: background .18s, border-color .18s, color .18s;
}

@media (hover: hover) and (pointer: fine) {
	.he-search-shortcuts__link:hover,
	.he-search-shortcuts__link:focus-visible {
		background: #f1eadd;
		border-color: var(--he-ink);
		color: var(--he-link);
	}
}

.he-search-overlay__status {
	margin: 0;
	font-size: 13px;
	font-weight: 600;
	color: #7d7466;
}

.he-search-overlay__status:empty {
	display: none;
}

.he-search-results {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 2px 24px;
	margin-top: 10px;
}

@media (max-width: 760px) {
	.he-search-results {
		grid-template-columns: 1fr;
	}
}

.he-search-result {
	display: flex;
	align-items: center;
	gap: 14px;
	padding: 10px 12px;
	margin-inline: -12px;
	color: var(--he-text-body);
	transition: background .18s, color .18s;
}

.he-search-result__fig {
	flex: 0 0 auto;
	width: 56px;
	height: 56px;
	background: var(--he-sand);
	overflow: hidden;
}

.he-search-result__fig img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.he-search-result__body {
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.he-search-result__title {
	font-family: var(--e-global-typography-che_tile_title-font-family, "Archivo"), sans-serif;
	font-weight: 600;
	font-size: 15.5px;
	line-height: 1.25;
	color: var(--he-text-strong);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.he-search-result__meta {
	font-size: 12.5px;
	font-weight: 600;
	color: #7d7466;
}

@media (hover: hover) and (pointer: fine) {
	.he-search-result:hover,
	.he-search-result:focus-visible {
		background: #f1eadd;
	}

	.he-search-result:hover .he-search-result__title,
	.he-search-result:focus-visible .he-search-result__title {
		color: var(--he-link);
	}
}

.he-search-result:active {
	background: var(--he-sand);
}

.he-search-overlay__all {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	margin-top: 16px;
	font-size: 14.5px;
	font-weight: 700;
	color: var(--he-link);
}

.he-search-overlay__all[hidden] {
	display: none;
}

@media (hover: hover) and (pointer: fine) {
	.he-search-overlay__all:hover,
	.he-search-overlay__all:focus-visible {
		color: var(--he-ink);
	}
}

/* ==========================================================================
   BUTTON HOVER — client 2026-08-25: "mostly dead or subtle color changes.
   Need a bit more life without overkill."
   --------------------------------------------------------------------------
   The design DOES specify a hover for every button, and the build already
   implements them: the green CTA goes #76bb00 -> #88d000 (the Kit's button
   Theme Style, `che_green_hover`), the outline button goes to #efe6d7 with an
   ink border, the hero's ghost button to rgba(255,255,255,.14). Measured
   against the design those are correct. They are also, on a large solid-green
   button, close to invisible: #76bb00 and #88d000 differ by about 4% of
   lightness.

   So this is the "matches the design but the concern is real" case. Rather
   than repaint the buttons — which would break the design's colour system and
   the Kit binding with it — the shift is given something to read against: a
   1px lift and a soft shadow on press-able controls. It is one property pair,
   it applies to every Elementor button at once so no variant can be missed,
   and it is the smallest change that turns "did that do something?" into a
   visible response.

   `:focus-visible` rides along so a keyboard user gets the same feedback, and
   the whole thing is dropped under `prefers-reduced-motion`.
   ========================================================================== */

.he-redesign .elementor-button {
	transition:
		background-color .18s ease,
		border-color .18s ease,
		color .18s ease,
		transform .18s ease,
		box-shadow .18s ease;
}

/*
 * Gated on a real pointer. On a touch screen `:hover` latches on tap and stays
 * latched, so an un-gated lift leaves the last button the visitor touched
 * floating above the page until they touch something else.
 */
@media (hover: hover) and (pointer: fine) {
	.he-redesign .elementor-button:hover,
	.he-redesign .elementor-button:focus-visible {
		transform: translateY(-1px);
		box-shadow: 0 6px 16px -6px rgba(20, 16, 13, .45);
	}
}

/* Pressed reads as the button going back down, on touch and pointer alike. */
.he-redesign .elementor-button:active {
	transform: translateY(0);
	box-shadow: none;
}

@media (prefers-reduced-motion: reduce) {
	.he-redesign .elementor-button {
		transition: background-color .18s ease, border-color .18s ease, color .18s ease;
	}

	.he-redesign .elementor-button:hover,
	.he-redesign .elementor-button:focus-visible,
	.he-redesign .elementor-button:active {
		transform: none;
	}
}

/*
 * Text links that act as buttons — the "View all products" / "Read more" /
 * card-footer links the design draws as arrow links (:388, :1043). The design
 * gives them a colour hover; the arrow moving with them is what makes a hover
 * on a bare text link legible at all.
 */
@media (hover: hover) and (pointer: fine) {
	.he-redesign .he-arrowlink:hover svg,
	.he-redesign .he-arrowlink:focus-visible svg,
	.he-redesign .he-brand__more:hover svg,
	.he-redesign .he-brand__more:focus-visible svg,
	.he-redesign .he-bcard__more:hover svg,
	.he-redesign .he-bcard__more:focus-visible svg,
	.he-redesign .he-search-overlay__all:hover svg,
	.he-redesign .he-search-overlay__all:focus-visible svg {
		transform: translateX(3px);
	}
}

.he-redesign .he-arrowlink svg,
.he-redesign .he-brand__more svg,
.he-redesign .he-bcard__more svg,
.he-redesign .he-search-overlay__all svg {
	transition: transform .18s ease;
}

@media (prefers-reduced-motion: reduce) {
	.he-redesign .he-arrowlink svg,
	.he-redesign .he-brand__more svg,
	.he-redesign .he-bcard__more svg,
	.he-redesign .he-search-overlay__all svg {
		transition: none;
		transform: none;
	}
}
