/*
Theme Name: Fromagination
Theme URI: https://staging.fromagination.com/
Description: Child theme for Mr. Tailor. Customizations live here so they survive parent theme updates. Built for the Fromagination redesign 2026.
Author: Gibsonworks, LLC
Author URI: https://bekee.com/
Template: mrtailor
Version: 0.9.84
Text Domain: mrtailor-child
*/


/* ============================================================
 * Typography (WO 2f) - CANDIDATE 2 (Vollkorn), added 2026-06-20
 * Replaces the "fritz-book" display face (reads as Papyrus-ish,
 * hard to read at small sizes). Goal: keep the rustic, old-world,
 * handwritten-signage warmth Ken wanted, but in a READABLE serif.
 *   Headings = Vollkorn (earthy, sturdy old-world serif; not the
 *              overused Fraunces).
 *   Body/UI  = DM Sans (already loaded), bumped to 500 for contrast.
 * All overrides scoped to avoid the logo wordmark.
 * ============================================================ */

/* Headings: warm, characterful serif. */
h1, h2, h3, h4, h5, h6,
.entry-title, .widget-title, .widgettitle, .page-title,
.section-title, .product_title,
.woocommerce-loop-product__title,
.products header h2 {
	font-family: "Vollkorn", Georgia, "Times New Roman", serif !important;
	font-weight: 600 !important;
	letter-spacing: 0 !important;
}

/* Body + UI + menus: DM Sans, heavier for contrast (kills fritz-book here). */
body,
.main-navigation, .main-navigation a,
.sub-menu, .sub-menu a, .menu-item > a,
button, input, select, textarea, .button, .btn {
	font-family: "DM Sans", -apple-system, "system-ui", Arial, sans-serif !important;
}

/* DM Sans 400 reads thin; nudge body weight up for contrast. */
body,
p, li, .widget, .woocommerce {
	font-weight: 500;
}

/* Nav + mega menu: the theme sets fritz-book via #menu-main (ID), so the
 * override needs ID-level specificity to win. This kills Fritz in the menu
 * bar and the mega-menu lists, where small-size legibility matters most. */
#site-navigation a,
#menu-main a,
#menu-main li a,
#menu-main .sub-menu a,
#site-menu nav a,
.widget_nav_menu a,
.widget_nav_menu ul.menu li a,
.footer-columns-5 a {
	font-family: "DM Sans", -apple-system, "system-ui", Arial, sans-serif !important;
}

/* Footer menus: the theme sets fritz-book through per-menu ID rules
 * (#menu-footer-menu* li a, specificity with an ID), so the override has to
 * match at ID level and rely on later source order to win. */
#menu-footer-menu li a,
#menu-footer-menu-2 li a,
#menu-footer-menu-3 li a {
	font-family: "DM Sans", -apple-system, "system-ui", Arial, sans-serif !important;
}

/* Finish killing fritz-book: the "Use Any Font" plugin (now deactivated, but its
 * static uaf.css can linger via cache) applied fritz-book !important to bare
 * `bdi` (which wraps EVERY WooCommerce price number, site-wide) and to the
 * product `.description_tab`. Those were the last fritz holdouts. Higher
 * specificity than uaf's bare `bdi` so DM Sans wins even if uaf.css loads later. */
body bdi,
body .description_tab {
	font-family: "DM Sans", -apple-system, "system-ui", Arial, sans-serif !important;
}

/* ============================================================
 * Cheese mega menu (WO 2c), added 2026-06-20
 * Full-width, four even columns, warm light panel (not navy,
 * not reversed-out), click-to-open (see assets/js/mega-menu.js).
 * ============================================================ */

/* Full-width positioning context. The panel anchors to #site-header-wrapper
 * (which is centered on the viewport) instead of #site-navigation (which sits
 * left of center because the search/cart icons hang off its right). That keeps
 * the full-width panel's content symmetric in the viewport. */
.site-header-wrapper { position: relative; } /* viewport-centered anchor for the panel */

/* Static (non-sticky) header: give it the same soft drop shadow the sticky
 * header already uses (0 0 65px -19px rgba(0,0,0,.17)), so the nav separates
 * from the large white areas on inner pages (e.g. the category archives).
 * Removed on transparent-header pages, where the header floats over an image
 * and a shadow would read wrong. */
.top-headers-wrapper:not(.sticky) {
	box-shadow: 0 0 65px -19px rgba(0, 0, 0, 0.17);
}
.transparent_header .top-headers-wrapper:not(.sticky) {
	box-shadow: none;
}

/* ============================================================
 * Accessibility
 * ------------------------------------------------------------
 * Visible keyboard focus (WCAG 2.4.7): the parent theme sets
 * a:active,a:focus,a:hover{outline:0!important}, which removes the focus ring
 * for keyboard users. Restore a clear brand ring, on keyboard focus only
 * (:focus-visible), so mouse clicks don't show it.
 * ============================================================ */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible,
.facetwp-checkbox:focus-visible,
summary:focus-visible {
	outline: 2px solid #a85912 !important;
	outline-offset: 2px !important;
	border-radius: 2px;
}

/* Skip-to-content link (WCAG 2.4.1): the first focusable element, hidden until
 * focused, then visible at the top-left. */
.fromag-skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 100000;
	background: #a85912;
	color: #fff !important;
	padding: 10px 18px;
	border-radius: 0 0 6px 0;
	font-family: "DM Sans", -apple-system, sans-serif;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: .08em;
	font-size: 13px;
	text-decoration: none;
}
.fromag-skip-link:focus { left: 0; }
#site-navigation { position: static; }
/* #menu-main is theme-set position:relative (needs !important to beat it) and
 * sits left of center; neutralize it so the panel anchors to the
 * viewport-centered .site-header-wrapper. Safe: the regular dropdowns anchor to
 * their own li, not to #menu-main. */
#menu-main { position: static !important; }
#menu-main > li.menu-item-megamenu { position: static; }


/* The panel: hidden by default so hover no longer opens it. */
#menu-main > li.menu-item-megamenu > ul.sub-menu {
	display: none !important;
	position: absolute;
	left: 50%;
	transform: translateX(-50%);
	width: 80vw;
	max-width: 1500px !important; /* override the theme JS inline max-width */
	top: calc(100% + 16px);
	margin: 0;
	background: #f6f1e9 !important;
	color: #2b2620;
	box-shadow: 0 18px 44px rgba(40, 28, 12, .18);
	border-top: 3px solid #a85912;
	border-radius: 0 0 12px 12px;
	z-index: 900;
	padding: 40px 48px !important;
	box-sizing: border-box;
}

/* Open on click (.fm-open is toggled by mega-menu.js). Two-tier grid:
 * By Style across the full top; By Country (2 cols) + Milk + Companions below. */
#menu-main > li.menu-item-megamenu.fm-open > ul.sub-menu {
	display: grid !important;
	visibility: visible !important;
	opacity: 1 !important;
	/* The theme sets pointer-events:none on submenus (for its hover mechanism);
	 * re-enable it when open or the panel is visible but click-through. */
	pointer-events: auto !important;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	column-gap: 40px;
	row-gap: 30px;
	align-items: start;
}
/* The theme's custom-menu.js rebuilds the mega submenu at runtime into
 * li.menu-item-inner-wrapper > ul.menu-item-inner-submenu > li(columns + shop
 * links). display:contents on both wrappers promotes those li's back into THIS
 * grid so the column/shop placement rules (which target .menu-item-inner-submenu
 * > li) apply. */
#menu-main > li.menu-item-megamenu.fm-open > ul.sub-menu > li.menu-item-inner-wrapper,
#menu-main > li.menu-item-megamenu.fm-open > ul.sub-menu > li.menu-item-inner-wrapper > ul.menu-item-inner-submenu {
	display: contents !important;
}
#menu-main > li.menu-item-megamenu.fm-open > ul.sub-menu,
#menu-main > li.menu-item-megamenu.fm-open > ul.sub-menu * {
	pointer-events: auto !important;
	/* The theme hides submenu content by default (its hover reveal); force it
	 * visible for everything in the open panel, including the column headings and
	 * shop links, which sit deeper than the panel's own visibility:visible. */
	visibility: visible !important;
}
/* ...but the column heading links stay non-interactive (they're just labels). */
#menu-main > li.menu-item-megamenu.fm-open ul.menu-item-inner-submenu > li > a {
	pointer-events: none !important;
}

#menu-main > li.menu-item-megamenu ul.menu-item-inner-submenu > li {
	min-width: 0;
	width: auto !important;
	background: none !important;
}

/* Two "Shop All" entry links across the top of the panel (Murray's pattern):
 * Wisconsin first (left), then all cheese. Both live in grid row 1; the browse
 * card + columns sit in rows 2-3, so the column nth-child mapping is untouched.
 * Added as menu items with classes .fm-shop-wi and .fm-shop-all. Unlike the
 * column headings, these links ARE clickable. */
#menu-main > li.menu-item-megamenu.fm-open ul.menu-item-inner-submenu > li.fm-shop-wi,
#menu-main > li.menu-item-megamenu.fm-open ul.menu-item-inner-submenu > li.fm-shop-all {
	grid-row: 1;
	justify-self: start;
	padding: 0 0 6px 0;
	position: relative;
	z-index: 1;
}
#menu-main > li.menu-item-megamenu.fm-open ul.menu-item-inner-submenu > li.fm-shop-wi  { grid-column: 1; }
#menu-main > li.menu-item-megamenu.fm-open ul.menu-item-inner-submenu > li.fm-shop-all { grid-column: 2; }

/* Full-width divider under the top row (independent of the two links' widths). */
#menu-main > li.menu-item-megamenu.fm-open > ul.sub-menu::after {
	content: "";
	grid-column: 1 / -1;
	grid-row: 1;
	align-self: end;
	border-bottom: 1px solid rgba(168, 89, 18, .22);
	z-index: 0;
}

#menu-main > li.menu-item-megamenu.fm-open ul.menu-item-inner-submenu > li.fm-shop-wi > a,
#menu-main > li.menu-item-megamenu.fm-open ul.menu-item-inner-submenu > li.fm-shop-all > a {
	pointer-events: auto !important;
	display: inline-flex !important;
	align-items: center;
	gap: 9px;
	font-family: "Vollkorn", Georgia, serif !important;
	font-size: 18px !important;
	font-weight: 700 !important;
	text-transform: none !important;
	letter-spacing: 0 !important;
	color: #a85912 !important;
	margin: 0 !important;
	padding: 0 !important;
	white-space: nowrap;
}
#menu-main > li.menu-item-megamenu.fm-open ul.menu-item-inner-submenu > li.fm-shop-wi > a::after,
#menu-main > li.menu-item-megamenu.fm-open ul.menu-item-inner-submenu > li.fm-shop-all > a::after {
	content: "\2192"; /* → */
	font-size: 17px;
	transition: transform .15s ease;
}
#menu-main > li.menu-item-megamenu.fm-open ul.menu-item-inner-submenu > li.fm-shop-wi > a:hover,
#menu-main > li.menu-item-megamenu.fm-open ul.menu-item-inner-submenu > li.fm-shop-all > a:hover {
	color: #2b2620 !important;
}
#menu-main > li.menu-item-megamenu.fm-open ul.menu-item-inner-submenu > li.fm-shop-wi > a:hover::after,
#menu-main > li.menu-item-megamenu.fm-open ul.menu-item-inner-submenu > li.fm-shop-all > a:hover::after {
	transform: translateX(4px);
}

/* TOP CARD (elevated surface): By Style + By Milk Type share ONE raised card,
 * the "browse the cheese" zone. Cheese Companions sits separately below on the
 * flat panel, because it isn't cheese. The card is a pseudo grid-item spanning
 * row 1 behind both Style and Milk. (Launch menu = Style + Milk + Companions;
 * By Region was pulled to Phase 2 per the client attribute addendum.) */
#menu-main > li.menu-item-megamenu.fm-open > ul.sub-menu::before {
	content: "";
	grid-column: 1 / -1;
	grid-row: 2; /* row 1 is the Shop All Cheese bar */
	align-self: stretch;
	margin: 0 -40px; /* bleed 40px wider than the columns on each side */
	background: #fffdf9;
	border-radius: 10px;
	box-shadow: 0 10px 34px rgba(70, 45, 18, .14);
	position: relative;
	z-index: 0;
}

/* By Style: the left 3 columns of the card. */
#menu-main > li.menu-item-megamenu ul.menu-item-inner-submenu > li:nth-child(1) {
	grid-column: 1 / 4;
	grid-row: 2;
	position: relative;
	z-index: 1;
	padding: 26px 24px 30px 32px;
}
#menu-main > li.menu-item-megamenu ul.menu-item-inner-submenu > li:nth-child(1) > ul.sub-menu {
	/* Auto-balancing 3-up so it survives styles being added or auto-hidden. */
	column-count: 3;
	column-gap: 40px;
}

/* By Milk Type: the right column of the same card. */
#menu-main > li.menu-item-megamenu ul.menu-item-inner-submenu > li:nth-child(2) {
	grid-column: 4 / 5;
	grid-row: 2;
	position: relative;
	z-index: 1;
	padding: 26px 32px 30px 24px;
}

/* Cheese Companions: separate full-width section below the card. */
#menu-main > li.menu-item-megamenu ul.menu-item-inner-submenu > li:nth-child(3) {
	grid-column: 1 / -1;
	grid-row: 3;
	margin-top: 6px;
}
#menu-main > li.menu-item-megamenu ul.menu-item-inner-submenu > li:nth-child(3) > ul.sub-menu {
	column-count: 4;
	column-gap: 40px;
}

/* Keep term items from splitting across sub-columns. */
#menu-main > li.menu-item-megamenu > ul.sub-menu ul.sub-menu > li {
	break-inside: avoid;
}

/* Drop any leftover promo image column. */
#menu-main > li.menu-item-megamenu .menu-item-image-column { display: none !important; }

/* Column headings (By Style, By Country, etc.). */
#menu-main > li.menu-item-megamenu ul.menu-item-inner-submenu > li > a {
	font-weight: 700 !important;
	text-transform: uppercase;
	letter-spacing: .07em;
	font-size: 12px;
	color: #6b4f2a !important;
	pointer-events: none;
	display: block;
	margin-bottom: 14px;
	padding: 0 !important;
}

/* Term lists render as a static block, not a positioned submenu. */
#menu-main > li.menu-item-megamenu ul.menu-item-inner-submenu > li > ul.sub-menu {
	display: block !important;
	position: static !important;
	background: none !important;
	box-shadow: none !important;
	width: auto !important;
	padding: 0 !important;
	margin: 0 !important;
	opacity: 1 !important;
	visibility: visible !important;
	transform: none !important;
}

/* Term links. */
#menu-main > li.menu-item-megamenu ul.menu-item-inner-submenu > li > ul.sub-menu > li {
	background: none !important;
	float: none !important;
	width: auto !important;
	display: block !important;
}
#menu-main > li.menu-item-megamenu ul.menu-item-inner-submenu > li > ul.sub-menu > li > a {
	color: #2b2620 !important;
	font-size: 15px !important;
	line-height: 1.3;
	padding: 6px 0 !important;
	/* inline-block so the clickable area is just the text, not the whole column */
	display: inline-block;
	border: none !important;
}
#menu-main > li.menu-item-megamenu ul.menu-item-inner-submenu > li > ul.sub-menu > li > a:hover {
	color: #a85912 !important;
}

/* Wisconsin featured. */
#menu-main > li.menu-item-megamenu .featured-region > a {
	font-weight: 700 !important;
	color: #a85912 !important;
}

/* ============================================================
 * Logo marquee ("As seen in" homepage section)
 * Pure CSS replacement for Logo Carousel Free plugin.
 * Added 2026-05-24 as part of WO §2b / §7 work.
 * ============================================================ */

.fromag-logo-marquee {
	width: 100%;
	overflow: hidden;
	padding: 1.5rem 0;
	-webkit-mask-image: linear-gradient(
		to right,
		transparent 0,
		#000 120px,
		#000 calc(100% - 120px),
		transparent 100%
	);
	mask-image: linear-gradient(
		to right,
		transparent 0,
		#000 120px,
		#000 calc(100% - 120px),
		transparent 100%
	);
}

.fromag-logo-track {
	display: flex;
	align-items: center;
	gap: 2rem;
	width: max-content;
	animation: fromag-marquee 40s linear infinite;
}

.fromag-logo-marquee:hover .fromag-logo-track {
	animation-play-state: paused;
}

.fromag-logo-track img {
	height: 130px;
	width: auto;
	flex-shrink: 0;
	filter: grayscale(100%);
	opacity: 0.65;
	transition: filter 0.3s ease, opacity 0.3s ease;
}

.fromag-logo-marquee:hover .fromag-logo-track img:hover,
.fromag-logo-track img:focus {
	filter: grayscale(0);
	opacity: 1;
}

@keyframes fromag-marquee {
	from { transform: translateX(0); }
	to { transform: translateX(-50%); }
}

@media (max-width: 768px) {
	.fromag-logo-track {
		gap: 1.5rem;
		animation-duration: 30s;
	}
	.fromag-logo-track img {
		height: 80px;
	}
	.fromag-logo-marquee {
		-webkit-mask-image: linear-gradient(
			to right,
			transparent 0,
			#000 60px,
			#000 calc(100% - 60px),
			transparent 100%
		);
		mask-image: linear-gradient(
			to right,
			transparent 0,
			#000 60px,
			#000 calc(100% - 60px),
			transparent 100%
		);
	}
}

@media (prefers-reduced-motion: reduce) {
	.fromag-logo-track {
		animation: none;
		justify-content: center;
		flex-wrap: wrap;
		gap: 2rem;
	}
}

/* ============================================================
 * Full-width responsive hero (WO 2b), added 2026-06-20
 * Applied via the "fromag-hero" class on a WPBakery Image Carousel
 * (builder: edit the Image Carousel > Design Options > Extra class name).
 * Caps the carousel height (default 72vh, so the next section peeks below it)
 * and makes each image COVER the full width responsively (fills edge-to-edge,
 * crops instead of distorting, works desktop to phone). Pair with the row set
 * to "Stretch row and content." The carousel + its images stay fully managed
 * in the page builder; this class only controls the size/crop treatment.
 * To change the height, edit the one variable below.
 * ============================================================ */
/* ⚠️ 64vh to 72vh, 2026-09-09, and the reason is the photography, not taste.
 * The 2024 shoot is 3:2. At 64vh the hero box is 2.50:1, which throws away 40%
 * of every frame's height and makes the food read as zoomed in. Bekee spotted
 * exactly that. At 72vh the box is 2.22:1 and keeps 67%, and it takes the
 * natively wide cookie-tray shot from 81% to 91%.
 *
 * This is the only knob that changes how much of a photograph survives. A 3:2
 * frame cannot fill a wide box without losing height; that is arithmetic, not
 * a setting. Anything past about 76vh starts pushing the rest of the homepage
 * below the fold on a laptop. */
.fromag-hero { --fromag-hero-h: 72vh; }
.fromag-hero .vc_images_carousel,
.fromag-hero .vc_carousel-inner,
.fromag-hero .vc_carousel-slideline,
.fromag-hero .vc_carousel-slideline-inner,
.fromag-hero .vc_item {
	height: var(--fromag-hero-h, 72vh) !important;
}
.fromag-hero .vc_carousel-inner,
.fromag-hero .vc_item { overflow: hidden; }

/* Slide WIDTH, added 2026-09-22, and this is a bug fix rather than styling.
 *
 * ⚠️ WPBakery measures the track ONCE, in JavaScript, from the window width at
 *    the instant it initialises, and writes the result as an inline pixel width.
 *    It re-measures on a window resize and on nothing else. Change the layout
 *    width any other way, and browser ZOOM is the one that actually happens, and
 *    the track keeps the old number while the window has a new one.
 *
 *    Kyle hit this 2026-09-21 on Firefox: his track was frozen at 1270px inside
 *    an 1895px window, so 625px of slide 2 sat beside slide 1 behind a hard
 *    vertical seam. 1270/1895 is 0.670, and 67% is a Firefox zoom step. It also
 *    changes which way the photograph crops, which is why one bug produced two
 *    complaints. At 1895 the slot is 2.70:1 and the 2.22:1 photo loses its top
 *    and bottom ("cut off the top of the cheese"); at 1270 the slot is 1.81:1
 *    and it loses its sides instead, showing full height ("the full depth").
 *
 *    Percentages take the measurement away from JavaScript, so the track is
 *    always exactly as wide as the viewport no matter when or whether it ran.
 *    The transitions survive because WPBakery moves the track in PERCENTAGES
 *    (left: -25%, -50%), never in pixels, so nothing downstream reads the width.
 *
 * ⚠️ THESE TWO NUMBERS ARE TIED TO THE SLIDE COUNT: 400% and 25% mean FOUR
 *    slides. Add or remove a hero image and both have to change, to 100xN% and
 *    (100/N)%. This is the same landmine as the note below about `.vc_item`, and
 *    a one-image hero hides it completely.
 *
 *    `.vc_item` at 25% MATCHES WPBakery's own inline width, so it is not the
 *    `width: 100%` mistake described below; that one made each slide the width
 *    of the whole track. Verified 2026-09-22 against a recreated frozen track:
 *    the slide returned to the viewport width and the stops landed on
 *    0, -1895, -3790 and -5685. */
.fromag-hero .vc_carousel-slideline       { width: 400% !important; }
.fromag-hero .vc_carousel-slideline-inner { width: 100% !important; }
.fromag-hero .vc_item                     { width:  25% !important; }

/* Each slide's image wrappers fill the slide.
 *
 * ⚠️ `.vc_item` IS DELIBERATELY NOT IN THIS LIST, and putting it back breaks
 *    every multi-image hero. WPBakery sizes each slide with an INLINE
 *    `width: 25%` (one quarter of a four-slide track), and a `width: 100%
 *    !important` here is the only thing that can beat an inline style. When it
 *    did, every slide became the full width of the 5760px track instead of one
 *    1440px viewport, `object-fit: cover` scaled the photograph 4x to cover it,
 *    and the hero showed 25% of one image's height, hugely magnified.
 *
 *    A ONE-IMAGE HERO HIDES THIS COMPLETELY, because a single-slide track is
 *    exactly one viewport wide and 100% and 25%-of-one are the same number.
 *    Found 2026-09-09, the first time four photographs went in. Slide width
 *    belongs to WPBakery; only the height is ours. */
.fromag-hero .vc_item > a,
.fromag-hero .vc_item figure,
.fromag-hero .vc_item .vc_figure,
.fromag-hero .vc_item .vc_single_image-wrapper {
	display: block;
	width: 100% !important;
	height: var(--fromag-hero-h, 72vh) !important;
}

/* The image covers the slide: full width, exactly 80vh, cropped to fit, centered. */
.fromag-hero .vc_item img {
	width: 100% !important;
	height: var(--fromag-hero-h, 72vh) !important;
	max-width: none !important;
	object-fit: cover !important;
	object-position: center !important;
	display: block;
}

/* ============================================================
 * Checkout info notice fix (WO 2d), added 2026-07-03
 * Mr. Tailor styles .woocommerce-info with a black background (its
 * own design intent), but custom notices on the Fluid Checkout page
 * (e.g. the Checkout Manager "order confirmation" message) don't pick
 * up Mr. Tailor's light-text rule, rendering black text on black.
 * Scoped to the checkout so Mr. Tailor's info styling elsewhere is
 * untouched. Cream + green accent match the brand (mega menu cream,
 * logo green #86b324).
 * ============================================================ */
body.woocommerce-checkout .woocommerce-info {
	background: #f6f1e9;
	color: #2b2b2b;
	border-top: 3px solid #86b324;
	/* Mr. Tailor's default is padding: 20px 160px 20px 60px; that 160px right
	 * pad squeezes the text into a narrow column with dead space on the right.
	 * Balance it: keep room on the left for the icon, normal room on the right. */
	padding: 20px 28px 20px 56px !important;
}
/* The default "i" icon is a light background-image built for Mr. Tailor's
 * black notice, so it vanishes on cream; the WooCommerce icon font glyph
 * isn't reliable in this version either. Replace both with a self-contained
 * inline-SVG info icon (brand-green circle, white "i") so it always renders
 * and stays on-brand on the cream background. */
body.woocommerce-checkout .woocommerce-info::before {
	content: "" !important;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='11' fill='%2386b324'/%3E%3Crect x='11' y='10.5' width='2' height='6.5' rx='1' fill='white'/%3E%3Ccircle cx='12' cy='7.5' r='1.3' fill='white'/%3E%3C/svg%3E") !important;
	background-repeat: no-repeat;
	background-position: center;
	background-size: 22px 22px;
	width: 22px;
	height: 22px;
	position: absolute;
	left: 20px;
	top: calc(50% - 11px);
	font-family: inherit;
}
body.woocommerce-checkout .woocommerce-info a {
	color: #6a8f1d;
}

/* Required-field asterisk: Mr. Tailor's inline CSS overrides WooCommerce's
 * red asterisk to rgba(34,34,34,.45) (a faint 45%-opacity gray), leaving it
 * nearly invisible. Restore a clear, high-contrast red so "required" reads at
 * a glance. Scoped to checkout to match the rest of this section; the same
 * faint-asterisk issue exists on other WooCommerce forms if we want it global. */
body.woocommerce-checkout form .form-row .required,
body.woocommerce-checkout .woocommerce-checkout .required,
body.woocommerce-checkout .required {
	color: #d63638 !important;
	opacity: 1 !important;
	border: 0 !important;
	text-decoration: none !important;
}

/* ============================================================
 * Faceted browsing (WO 2e), added 2026-07-03
 * Murray's-inspired refine bar: horizontal facet dropdowns + a
 * count/sort row, plus the per-product attribute descriptor line.
 * ============================================================ */

.fromag-refine {
	margin: 0 0 30px;
}
/* Hide Mr. Tailor's archive separator rule; the facet band's own borders
 * provide the horizontal division now. */
hr.catalog_top_sep { display: none !important; }

/* Top row: "Refine" left, count + sort right. */
.fromag-refine__top {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 20px;
	flex-wrap: wrap;
}
.fromag-refine__label {
	font-family: "DM Sans", -apple-system, sans-serif;
	text-transform: uppercase;
	letter-spacing: .14em;
	font-weight: 700;
	font-size: 13px;
	color: #2b2620;
}
.fromag-refine__meta {
	display: flex;
	align-items: flex-start;
	gap: 26px;
	margin-left: auto;
}
/* Unified control treatment: uppercase + the "Refine" letter-spacing across the
 * count, sort dropdown, and facet dropdowns, so every control reads as one family. */
/* `body` is load-bearing, 2026-09-14. Two rules of the SAME specificity load after
 * this file and were winning: Mr. Tailor's `.catalog-page .woocommerce-result-count`
 * (margin-top 8px, which dropped the count below Refine By and the sort control) and
 * the Customizer's inline `.woocommerce .woocommerce-result-count` (45% gray, about
 * 2.7:1, failing 4.5:1 for 12px text). The extra type selector outranks both. */
body .fromag-refine__meta .woocommerce-result-count {
	margin: 0;
	text-transform: uppercase;
	letter-spacing: .12em;
	font-size: 12px;
	font-weight: 600;
	color: #6b6357;
	line-height: 1;
}
.fromag-refine__meta .woocommerce-ordering { margin: 0; line-height: 1; }
/* Native (non-Select2) fallback */
.fromag-refine__meta .woocommerce-ordering select {
	text-transform: uppercase;
	letter-spacing: .12em;
	font-size: 12px;
	font-weight: 600;
	border: 0;
	background: transparent;
	color: #2b2620;
	cursor: pointer;
}
/* Select2-enhanced sort dropdown: strip its box, match the family. */
.fromag-refine__meta .woocommerce-ordering .select2-container--default .select2-selection--single {
	border: 0 !important;
	background: transparent !important;
	height: auto !important;
}
.fromag-refine__meta .woocommerce-ordering .select2-selection__rendered {
	text-transform: uppercase;
	letter-spacing: .12em;
	font-size: 12px !important;
	font-weight: 600 !important;
	color: #2b2620 !important;
	line-height: 1 !important;
	padding: 0 20px 0 0 !important;
}
.fromag-refine__meta .woocommerce-ordering .select2-selection__arrow { top: -3px !important; right: 0 !important; }

/* Facet row: horizontal dropdown bar. */
/* Facet row bracketed by borders so it reads as a distinct band, not floating. */
.fromag-refine__facets {
	display: flex;
	flex-wrap: wrap;
	align-items: center; /* vertically center the checkbox facet with the dropdowns */
	gap: 28px;
	margin-top: 18px;
	padding: 16px 0;
	border-top: 1px solid #e6e0d6;
	border-bottom: 1px solid #e6e0d6;
}
.fromag-facet:empty { display: none; }          /* hide the trial's non-rendered facet slots */
.fromag-facet .facetwp-facet { margin: 0 !important; }
.fromag-facet .fs-wrap { min-width: 156px; }
/* Borderless facet dropdowns to match the sort control (and Murray's). */
/* Caret spacing, measured and corrected 2026-08-01.
 * Two right paddings were stacking: 22px here on .fs-label-wrap plus FacetWP's own 22px
 * on .fs-label. With the caret absolutely positioned at right:5px, that put 29px between
 * the end of the word and its caret on every dropdown, which reads as two separate
 * elements rather than one control. Zeroing the inner padding and carrying the whole
 * reserve on the wrap brings it to 8px, and returns ~22px of width per dropdown to the
 * refine bar. */
.fromag-facet .fs-label-wrap {
	border: 0;
	border-radius: 0;
	background: transparent;
	padding: 0 23px 0 0;
}
/* Must be .fs-label-wrap .fs-label, not just .fs-label: fSelect.css sets
 * `.fs-label-wrap .fs-label { padding: 6px 22px 6px 8px }` at the same specificity and
 * loads after the child theme, so a two-class selector here silently loses. */
.fromag-facet .fs-label-wrap .fs-label { padding-right: 0; }
.fromag-facet .fs-label-wrap:hover .fs-label { color: #86b324; }
.fromag-facet .fs-label {
	text-transform: uppercase;
	letter-spacing: .12em;
	font-size: 12px;
	font-weight: 600;
	color: #2b2620;
}
.fromag-facet .fs-arrow { border-top-color: #86b324; }
/* The panel sizes to its OPTIONS, not to its trigger. fSelect defaults the dropdown to
 * the width of .fs-wrap, which is now content-width, so long terms clipped mid-word
 * ("ALPINE / GRUYÈRE-STY", "NATURAL RIND / TOMM"). A fixed width would only break again
 * the next time a style term is added, and terms do keep getting added: seven arrived on
 * 2026-07-29. max-content sizes to the longest option, min-width keeps it at least as
 * wide as the control it hangs off, max-width stops a runaway term from spanning the page. */
.fromag-facet .fs-dropdown {
	border: 1px solid #d9d2c6;
	border-radius: 6px;
	box-shadow: 0 12px 30px rgba(40, 28, 12, .16);
	overflow: hidden;
	width: max-content;
	min-width: 100%;
	max-width: 340px;
}
/* Belt and braces: if a term ever does exceed max-width, wrap it rather than clip it.
 * A truncated filter label is worse than a two-line one; the shopper cannot tell what
 * they are selecting. */
.fromag-facet .fs-dropdown .fs-option-label {
	white-space: normal;
	overflow-wrap: anywhere;
}
.fromag-facet .fs-dropdown .fs-options { padding: 4px; }

/* Make the scroll affordance permanent. Style has 17 terms and about 8 fit, but macOS
 * uses overlay scrollbars that stay hidden until you already scroll, so nothing on screen
 * says there is more below. Declaring ::-webkit-scrollbar opts this element out of the
 * overlay behavior and back into a persistent bar in Chrome and Safari. The thumb is
 * inset with a transparent border so it reads as a slim pill rather than a full-height
 * grey gutter. */
/* ORDER MATTERS, and not for the usual reason. Since Chrome 121, declaring the standard
 * `scrollbar-width` on an element makes Chrome IGNORE ::-webkit-scrollbar on that same
 * element. Having both meant Chrome fell back to `scrollbar-width: thin`, which on macOS
 * is still an auto-hiding overlay bar reserving zero layout width, so the affordance
 * never appeared. The standard properties are therefore fenced into @supports below,
 * where only engines WITHOUT the pseudo-element (Firefox) will see them. */
.fromag-facet .fs-dropdown .fs-options::-webkit-scrollbar {
	width: 12px;
}
.fromag-facet .fs-dropdown .fs-options::-webkit-scrollbar-track {
	background: transparent;
}
.fromag-facet .fs-dropdown .fs-options::-webkit-scrollbar-thumb {
	background: #b8ae9d;
	border-radius: 6px;
	border: 3px solid transparent;
	background-clip: content-box;
}
.fromag-facet .fs-dropdown .fs-options::-webkit-scrollbar-thumb:hover {
	background: #86b324;
	background-clip: content-box;
}
/* Firefox only: it has no ::-webkit-scrollbar, so this branch never fires in Chrome or
 * Safari and cannot cancel the rules above. */
@supports not selector(::-webkit-scrollbar) {
	.fromag-facet .fs-dropdown .fs-options {
		scrollbar-width: thin;
		scrollbar-color: #b8ae9d transparent;
	}
}
.fromag-facet .fs-option { border-radius: 4px; }
.fromag-facet .fs-option.fs-option-selected,
.fromag-facet .fs-option:hover { background: #f2efe8; }

/* "Made in Wisconsin" checkbox facet: match the dropdown labels exactly
 * (uppercase, .12em spacing, 12px, weight 600, DM Sans) so it reads as one
 * family with the dropdowns in the refine bar. */
.fromag-facet .facetwp-type-checkboxes .facetwp-checkbox {
	text-transform: uppercase;
	letter-spacing: .12em;
	font-size: 12px;
	font-weight: 600;
	color: #2b2620;
	font-family: "DM Sans", -apple-system, sans-serif;
	line-height: 1;
	position: relative;
	top: -2px; /* fine-align the checkbox text center with the dropdown labels */
	padding-left: 24px;
	background-image: none !important; /* drop FacetWP's icon (it clipped at this height) */
	cursor: pointer;
}
/* Custom checkbox square, drawn with pseudo-elements so it never clips. */
.fromag-facet .facetwp-type-checkboxes .facetwp-checkbox::before {
	content: "";
	position: absolute;
	left: 0;
	top: 50%;
	transform: translateY(-50%);
	width: 15px;
	height: 15px;
	box-sizing: border-box;
	border: 1.5px solid #a85912;
	border-radius: 3px;
	background: #fff;
	transition: background .12s ease, border-color .12s ease;
}
.fromag-facet .facetwp-type-checkboxes .facetwp-checkbox.checked::before {
	background: #86b324;
	border-color: #86b324;
}
.fromag-facet .facetwp-type-checkboxes .facetwp-checkbox.checked::after {
	content: "";
	position: absolute;
	left: 5px;
	top: 50%;
	width: 4px;
	height: 8px;
	border: solid #fff;
	border-width: 0 2px 2px 0;
	transform: translateY(-62%) rotate(45deg);
}
.fromag-facet .facetwp-type-checkboxes .facetwp-checkbox:hover { color: #86b324; }
.fromag-facet .facetwp-type-checkboxes .facetwp-checkbox:hover::before { border-color: #86b324; }
.fromag-facet .facetwp-type-checkboxes .facetwp-counter {
	font-weight: 500;
	opacity: .55;
	letter-spacing: .06em;
}

/* Per-product attribute descriptor line. */
.fromag-descriptors {
	font-family: "DM Sans", -apple-system, sans-serif;
	font-size: 13px;
	line-height: 1.5;
	color: #6b6357;
	margin: 5px 0 8px;
}

/* Product gallery: thumbnails UNDER the photo on desktop, 2026-09-14. Bekee's call:
 * the main photo was only 450px wide because Mr. Tailor floats the thumbnail column
 * left at 1024px+ (viewport 81%, thumbs 18%), and 76px thumbnails beside it looked
 * like an accidental near-match for the 65px Recently Viewed images on the right.
 * Below 1024px the theme already stacks them, so this only touches desktop.
 * Two selectors each because the parent's rules come with and without #content, and
 * the #content form carries an ID's specificity. */
@media only screen and (min-width: 1024px) {
	body.single-product #content div.product div.images.woocommerce-product-gallery .flex-viewport,
	body.single-product div.product div.images.woocommerce-product-gallery .flex-viewport {
		float: none;
		width: 100%;
	}
	body.single-product #content div.product div.images.woocommerce-product-gallery .flex-control-thumbs,
	body.single-product div.product div.images.woocommerce-product-gallery .flex-control-thumbs {
		float: none;
		width: 100%;
		max-height: none;
		padding: 12px 0 0;
		display: flex;
		flex-wrap: wrap;
		gap: 12px;
	}
	body.single-product #content div.product div.images.woocommerce-product-gallery .flex-control-thumbs li,
	body.single-product div.product div.images.woocommerce-product-gallery .flex-control-thumbs li {
		float: none;
		width: 88px;
		padding: 0;
	}
}

/* Milk animal icons in product descriptions, 2026-09-14. Bekee's sizes: cow 50px tall,
 * goat and sheep 40px, width following each image's own shape. The icons are typed into
 * each product's description text (153 of 394 products, six different files, previously
 * rendering anywhere up to 105 x 72), so CSS is the only way to size them all at once
 * without editing products. Matched by FILENAME, never by the bare word "cow", which
 * would also catch product photos; add a line here if Fromagination uploads a new icon. */
.single-product .woocommerce-product-details__short-description img[src*="Fromagination-cow" i],
.single-product .woocommerce-Tabs-panel--description img[src*="Fromagination-cow" i] {
	height: 50px;
	width: auto;
}
.single-product .woocommerce-product-details__short-description img[src*="Fromagination-goat" i],
.single-product .woocommerce-product-details__short-description img[src*="Fromagination-sheep" i],
.single-product .woocommerce-product-details__short-description img[src*="/goat.7x.6"],
.single-product .woocommerce-product-details__short-description img[src*="/sheep.9x.6"],
.single-product .woocommerce-Tabs-panel--description img[src*="Fromagination-goat" i],
.single-product .woocommerce-Tabs-panel--description img[src*="Fromagination-sheep" i],
.single-product .woocommerce-Tabs-panel--description img[src*="/goat.7x.6"],
.single-product .woocommerce-Tabs-panel--description img[src*="/sheep.9x.6"] {
	height: 40px;
	width: auto;
}

/* The same line on the single product page, 2026-09-14 (Vi's feedback). Sits
 * between the title and the price, so it steps up from card size. #6b6357 on
 * white is 5.8:1. */
.fromag-descriptors--single {
	font-size: 15px;
	margin: 0 0 14px;
}

/* Hide Mr. Tailor's offcanvas "Filter" toggle on shop/archives: it opened the
 * Cheese Companions menu (wrong), and FacetWP's refine bar replaces it. */
.filters_button,
#button_offcanvas_sidebar_left { display: none !important; }

/* Collapse Mr. Tailor's ~45px-tall Select2 sort box to the text height so its
 * baseline matches "16 products" (the text otherwise rode the top of the box). */
.fromag-refine__meta .woocommerce-ordering .select2-container,
.fromag-refine__meta .woocommerce-ordering .select2-container .select2-selection--single {
	height: auto !important;
	min-height: 0 !important;
}
.fromag-refine__meta .woocommerce-ordering .select2-selection--single {
	display: inline-flex !important;
	align-items: center !important;
	line-height: 1 !important;
}
.fromag-refine__meta .woocommerce-ordering .select2-selection__rendered {
	height: auto !important;
	line-height: 1 !important;
	margin: 0 !important;
}
.fromag-refine__meta .woocommerce-ordering .select2-selection__arrow {
	height: auto !important;
	top: 50% !important;
	transform: translateY(-50%) !important;
}

/* Sort-control alignment, take 2: max-height caps the Select2 flex-stretch that
 * resisted height:auto, forcing the box to a compact fixed height. Then center
 * all three controls in the row so text + arrow sit on one line. */
.fromag-refine__top,
.fromag-refine__meta { align-items: center !important; }
.fromag-refine__meta .woocommerce-ordering .select2-container--default .select2-selection--single,
.fromag-refine__meta .woocommerce-ordering .select2-selection__rendered {
	height: 18px !important;
	min-height: 18px !important;
	max-height: 18px !important;
	line-height: 18px !important;
}
.fromag-refine__meta .woocommerce-ordering .select2-selection__arrow {
	height: 18px !important;
	top: 0 !important;
	transform: none !important;
	right: 0 !important;
}

/* Match the Select2 sort arrow to the fSelect (Milk/Flavor) arrow: green,
 * same triangle size. */
.fromag-refine__meta .woocommerce-ordering .select2-selection__arrow b {
	border-width: 5px 5px 0 !important;
	border-top-color: #86b324 !important;
	border-left-color: transparent !important;
	border-right-color: transparent !important;
	margin-left: -5px !important;
	margin-top: -2px !important;
}

/* Facet dropdown options + search: same treatment as the facet labels
 * (uppercase, letter-spacing, 12px) so the open dropdown reads consistently. */
.fromag-facet .fs-dropdown .fs-option,
.fromag-facet .fs-search input {
	text-transform: uppercase;
	letter-spacing: .12em;
	font-size: 12px;
}

/* Facet dropdown search: more room above the search field, less below it
 * (the input carried a 24px bottom margin). */
.fromag-facet .fs-search {
	padding: 12px 10px 6px !important;
}
.fromag-facet .fs-search input {
	margin-bottom: 4px !important;
}

/* Compact the closed facet labels so six fit comfortably in the row, but keep
 * the open dropdown panel wide enough to read the options. */
.fromag-facet .fs-wrap {
	min-width: 0 !important;
	width: auto !important;
}
.fromag-facet .fs-dropdown {
	min-width: 190px;
}

/* Archive spacing cleanup (WO 2e):
 * - Hide Mr. Tailor's empty "active filters" container (FacetWP replaces it);
 *   it was reserving 30px for nothing.
 * - Tighten the big margin under the category header.
 * - Reduce the gap between the refine bar and the first product row. */
.active_filters_ontop { display: none !important; }
.woocommerce-products-header { margin-bottom: 24px !important; }
.fromag-refine { margin-bottom: 18px !important; }

/* Hover collision fix (WO 2e): Mr. Tailor's price "switcher" is a 66px box that
 * slides up 33px on hover to swap the price for the add-to-cart, landing on our
 * descriptor line. Replicate the theme's "always visible price" mode: expand the
 * box so the price shows permanently and there's no slide to collide. */
.woocommerce ul.products li.product .product_after_shop_loop_switcher {
	height: auto !important;
	overflow: visible !important;
	transform: none !important;
}

/* Category header spacing: trim the big gap under the top nav, and give the
 * page title a little more room under the (SEO-kept) breadcrumb. */
.archive.woocommerce .content-area { padding-top: 24px !important; }
.woocommerce-products-header__title { margin-top: 18px !important; }

/* The Select2 sort-arrow container carries a dark SVG arrow in its ::before AND
 * the <b> arrow we colored green; hide the dark SVG so only the green shows. */
.fromag-refine__meta .woocommerce-ordering .select2-selection__arrow::before {
	display: none !important;
	background: none !important;
	content: none !important;
}

/* The switcher's parent (.product_after_shop_loop) is height:33px / overflow:hidden,
 * which clips the now-expanded switcher and hides the price. Expand it too so the
 * price (and add-to-cart) sit in normal flow below the descriptor. */
.woocommerce ul.products li.product .product_after_shop_loop {
	height: auto !important;
	overflow: visible !important;
}

/* Product-loop add-to-cart: make it read as a real button (WO 2e). Dark by
 * default (matches the site's buttons), fills brand-green on hover. */
.woocommerce ul.products li.product .product_after_shop_loop_buttons {
	margin-top: 12px;
}
.woocommerce ul.products li.product .product_after_shop_loop_buttons a.button {
	display: inline-block;
	background: #2b2620 !important;
	color: #fff !important;
	padding: 10px 20px !important;
	border-radius: 3px;
	border: 0;
	text-transform: uppercase;
	letter-spacing: .1em;
	font-size: 11px;
	font-weight: 700;
	line-height: 1.2;
	transition: background .15s ease, color .15s ease;
}
.woocommerce ul.products li.product .product_after_shop_loop_buttons a.button:hover {
	background: #86b324 !important;
	color: #2b2620 !important;
}

/* ============================================================
 * Regular top-nav dropdowns (WO 2c), added 2026-07-03
 * Gifts, Catering, Classes, Our Local Shop: coordinate with the Cheese
 * mega menu's warm aesthetic (cream panel, brown top accent, DM Sans,
 * dark text) instead of Mr. Tailor's default dark-navy dropdown.
 * ============================================================ */
#menu-main > li:not(.menu-item-megamenu) > ul.sub-menu {
	background: #f6f1e9 !important;
	border: 0 !important;
	border-top: 3px solid #a85912 !important;
	border-radius: 0 0 10px 10px;
	box-shadow: 0 14px 34px rgba(40, 28, 12, .16);
	padding: 12px 0 !important;
	left: 0;
	min-width: 0;
	width: max-content;
	max-width: 210px;
}
/* Click-to-open, matching the Cheese mega menu (WO 2c). nav-menu.js toggles
 * .fm-open on the top-level <li>. Neutralize the parent theme's hover reveal
 * (.main-navigation ul li:hover > ul) so these open on click, not hover; the
 * #menu-main ID selector outranks the theme's rule. */
#menu-main > li.menu-item-has-children:not(.menu-item-megamenu):not(.fm-open):hover > ul.sub-menu {
	visibility: hidden !important;
	opacity: 0 !important;
	pointer-events: none !important;
}
#menu-main > li.menu-item-has-children:not(.menu-item-megamenu).fm-open > ul.sub-menu {
	visibility: visible !important;
	opacity: 1 !important;
	pointer-events: auto !important;
	z-index: 99999;
}
#menu-main > li:not(.menu-item-megamenu) > ul.sub-menu > li {
	background: none !important;
	border: 0 !important;
}
#menu-main > li:not(.menu-item-megamenu) > ul.sub-menu > li > a {
	color: #2b2620 !important;
	border: 0 !important;
	background: transparent !important;
	font-family: "DM Sans", -apple-system, sans-serif !important;
	font-size: 14px !important;
	font-weight: 500 !important;
	letter-spacing: .01em;
	text-transform: none !important;
	margin: 0 !important;
	padding: 9px 18px 9px 16px !important;
	line-height: 1.4;
	transition: background .12s ease, color .12s ease;
}
#menu-main > li:not(.menu-item-megamenu) > ul.sub-menu > li > a:hover {
	background: transparent !important;
	color: #2b2620 !important;
	box-shadow: inset 3px 0 0 #a85912; /* left accent bar only */
}


/* ============================================================
 * Footer separation, added 2026-08-01
 * ------------------------------------------------------------
 * The footer was white on a white page, so it floated: nothing sat between the last
 * product row and "SHOP HOURS".
 *
 * Cream over a top shadow, deliberately. The header already separates itself with a
 * shadow that casts DOWNWARD onto the content; a shadow at the top of the footer would
 * have to cast upward, lighting the page from two directions. A tonal shift is also the
 * conventional signal that page content has ended rather than that something floats above
 * it. #f6f1e9 is already the mega menu panel color, so this introduces no new value, and
 * against #2b2620 body text it clears AA comfortably.
 *
 * The hairline is the same #e6e0d6 used on the refine bar, so the boundary stays crisp
 * instead of relying on the tonal difference alone.
 *
 * The payment-card strip (.site-footer-copyright-area) is a child of #site-footer, so it
 * sits INSIDE the cream. That is intentional: the cards read as part of the footer block
 * rather than as a third zone below it.
 *
 * SELECTOR NOTE, do not "simplify" this to #site-footer. Two things outrank a bare ID here:
 *   1. The parent theme sets `footer#site-footer { padding: 40px 0 }`, which is one element
 *      more specific than a plain ID.
 *   2. The white background comes from an INLINE <style> block, which is Mr. Tailor's
 *      Customizer output. It matches `#site-footer` at the same specificity as us but is
 *      printed later in the document, so source order hands it the win.
 * `body footer#site-footer` clears both without needing !important.
 *
 * This deliberately lives in CSS rather than in the Customizer's footer background setting.
 * A Customizer value is a theme_mod: it lives in the database, does NOT travel with the
 * theme deploy, and would become one more thing to re-apply by hand on staging and
 * production. See deploy-checklist.md.
 *
 * SCOPE, revised 2026-08-01: the cream covers the COLUMN BLOCK ONLY, not the whole footer.
 * Running it to the bottom put a tinted field behind the payment-card logos, which are
 * flat marks built for white and read as pasted-on against a tint. The copyright row stays
 * white, so the cream band reads as the footer's content and the card row as the page's
 * closing edge. That row is also where the legal links (privacy, terms, accessibility
 * statement, copyright) are headed, which is a further reason to keep it visually separate. */
body footer#site-footer {
	background: transparent;
	border-top: 0;
	padding: 0 0 40px;
}
/* ORANGE RULE ACROSS THE TOP, 2026-09-23. Bekee's compromise for Kyle and Ken's
 * ask to make the footer orange: the line ties the footer to the orange notice
 * bar without a full orange band. It is the BRAND GUIDE orange #bc6428, the
 * logo's own color, on purpose. A 4px line carries no text, so the contrast
 * that rules #bc6428 out as a background does not apply, and the page shows
 * exactly one orange. Was `1px solid #e6e0d6`. */
body footer#site-footer .site-footer-widget-area {
	background: #f6f1e9;
	border-top: 4px solid #bc6428;
	border-bottom: 1px solid #e6e0d6;
	padding: 56px 0 44px;
}

/* Kill the dead space under the columns. The theme gives every footer widget
 * margin-bottom: 60px, but the columns are a CSS grid that is a SINGLE row at desktop
 * width, so that margin has nothing below it to separate from and just piles up on top of
 * the container's own bottom padding. On white it was invisible; the cream made about
 * 100px of nothing obvious.
 *
 * Moving the 60px onto the grid's row-gap keeps the separation when the columns DO wrap to
 * a second row on narrow screens, which is the case the margin was presumably there for. */
body footer#site-footer .footer-columns-5 {
	row-gap: 60px;
}
body footer#site-footer .footer-columns-5 > .widget {
	margin-bottom: 0;
}

/* Shop Hours widget (text-4), 2026-09-14, from Vi's feedback that the hours were hard to
 * read. Same markup as the homepage Visit Us list (dl.fromag-hours), but stacked day over
 * time, because a footer column is too narrow for "Tuesday to Friday" and a time on one
 * line. The widget content lives in the database; see launch-runbook.md Phase 4. */
body footer#site-footer .fromag-hours {
	margin: 0;
	line-height: 1.5;
}
body footer#site-footer .fromag-hours dt { font-weight: 600; }
body footer#site-footer .fromag-hours dd { margin: 0 0 0.6rem; }
body footer#site-footer .fromag-hours dd:last-child { margin-bottom: 0; }

/* ------------------------------------------------------------
 * Footer accordion on phones, 2026-09-25 (assets/js/footer-accordion.js)
 * ------------------------------------------------------------
 * Mr. Tailor hides every footer column at 640px and below behind one unlabeled
 * three-dot span. That option is a theme setting in the database, so it is
 * overridden here instead, where it travels with the theme deploy. The columns
 * show again, the dots go away, and the script folds only the three menu
 * widgets. Hours, address, and signup stay open.
 *
 * The .fromag-fold rules apply only once the script has run, so without
 * JavaScript the phone footer is a plain open list. */
@media only screen and (max-width: 640px) {
	body footer#site-footer .trigger-footer-widget-area {
		display: none;
	}
	body footer#site-footer .site-footer-widget-area.expandable {
		display: block;
	}
	/* On phones the parent already separates widgets with its own rule:
	 * `footer#site-footer .site-footer-widget-area .widget-grid .widget` gives
	 * each one a bottom line, 35px margin, and 30px padding. The selectors below
	 * carry .site-footer-widget-area .widget-grid on purpose, to outrank it.
	 * The 60px row-gap from the desktop block would stack on top of that margin. */
	body footer#site-footer .site-footer-widget-area .widget-grid.footer-columns-5 {
		row-gap: 0;
	}
	/* The three folds sit together as one list. The parent's bottom line on each
	 * fold does the separating, and the widget before the first fold loses its
	 * margin so its own line becomes the top edge of the list. */
	body footer#site-footer .site-footer-widget-area .widget-grid > .widget:not(.fromag-fold):has(+ .fromag-fold) {
		margin-bottom: 0;
	}
	body footer#site-footer .site-footer-widget-area .widget-grid > .widget.fromag-fold {
		margin-bottom: 0;
		padding-bottom: 0;
	}
	body footer#site-footer .site-footer-widget-area .widget-grid > .widget.fromag-fold:not(:has(+ .fromag-fold)) {
		margin-bottom: 35px;
	}
	body footer#site-footer .fromag-fold .widget-title {
		margin: 0;
	}
	/* font-family needs !important and the extra specificity: a global
	 * `button { font-family: "DM Sans" !important }` near the top of this file
	 * would otherwise turn the heading from Vollkorn into DM Sans. */
	body footer#site-footer .fromag-fold .widget-title .fromag-fold__toggle {
		font-family: inherit !important;
	}
	body footer#site-footer .fromag-fold__toggle {
		display: flex;
		align-items: center;
		justify-content: space-between;
		width: 100%;
		min-height: 48px;
		padding: 12px 0;
		margin: 0;
		border: 0;
		background: none;
		color: inherit;
		font: inherit;
		letter-spacing: inherit;
		text-transform: inherit;
		text-align: left;
		cursor: pointer;
	}
	body footer#site-footer .fromag-fold__toggle:focus-visible {
		outline: 2px solid #a85912;
		outline-offset: 2px;
	}
	/* Plus when closed, minus when open: two 2px bars, the vertical one hidden
	 * when expanded. Drawn in CSS so it follows the heading color. */
	body footer#site-footer .fromag-fold__icon {
		position: relative;
		flex: 0 0 14px;
		width: 14px;
		height: 14px;
		margin-left: 16px;
	}
	body footer#site-footer .fromag-fold__icon::before,
	body footer#site-footer .fromag-fold__icon::after {
		content: "";
		position: absolute;
		left: 0;
		top: 6px;
		width: 14px;
		height: 2px;
		background: currentColor;
	}
	body footer#site-footer .fromag-fold__icon::after {
		transform: rotate(90deg);
	}
	body footer#site-footer .fromag-fold__toggle[aria-expanded="true"] .fromag-fold__icon::after {
		display: none;
	}
	body footer#site-footer .fromag-fold .widget-title + [id] {
		padding-bottom: 16px;
	}
}

/* ------------------------------------------------------------
 * Notice bar, 2026-09-25 (WPFront Notification Bar)
 * ------------------------------------------------------------
 * Hourly work Kyle and Ken okayed in writing. Kyle writes and switches the
 * notices under Settings > Notification Bar; colors, position, and timing are
 * set by fromagination/configure-notice-bar.php, and the look lives here so it
 * travels with the theme deploy. Background #a85912 under white text is 5.12:1.
 *
 * The plugin prints its colors with `#wpfront-notification-bar div.wpfront-close`
 * (one ID, one element, one class); `.fromag-notice-bar` is the custom class the
 * configure script sets, and it is what lets these rules outrank the plugin's. */
/* Padding goes on the cell, never on the bar. The plugin closes the bar by
 * animating its height to 0, and padding on the bar itself left a 20px orange
 * strip behind after the close. */
body #wpfront-notification-bar.fromag-notice-bar {
	padding: 0;
	overflow: hidden;
}
body #wpfront-notification-bar.fromag-notice-bar #wpfront-notification-bar-table {
	margin: 0 auto;
}
body #wpfront-notification-bar.fromag-notice-bar #wpfront-notification-bar-table td {
	padding: 10px 56px;
}
body #wpfront-notification-bar.fromag-notice-bar div.wpfront-message {
	font-family: "DM Sans", -apple-system, "system-ui", Arial, sans-serif;
	font-size: 15px;
	font-weight: 500;
	line-height: 1.45;
	letter-spacing: 0.01em;
	text-align: center;
}
body #wpfront-notification-bar.fromag-notice-bar div.wpfront-message a {
	color: #ffffff;
	text-decoration: underline;
	text-underline-offset: 2px;
	font-weight: 600;
}
/* The plugin's close control is a <div> with "X" in it, 18px square in the
 * corner. assets/js/notice-bar.js makes it a keyboard-operable button; this
 * makes it a 40px target, centered on the bar's height. */
body #wpfront-notification-bar.fromag-notice-bar div.wpfront-close {
	position: absolute;
	top: 50%;
	right: 8px;
	transform: translateY(-50%);
	width: 40px;
	height: 40px;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 4px;
	font-family: "DM Sans", -apple-system, "system-ui", Arial, sans-serif;
	font-size: 18px;
	font-weight: 500;
	line-height: 40px;
	text-align: center;
	cursor: pointer;
}
body #wpfront-notification-bar.fromag-notice-bar div.wpfront-close:focus-visible {
	outline: 2px solid #ffffff;
	outline-offset: -4px;
}
@media only screen and (max-width: 640px) {
	body #wpfront-notification-bar.fromag-notice-bar #wpfront-notification-bar-table td {
		padding: 10px 48px 10px 16px;
	}
	body #wpfront-notification-bar.fromag-notice-bar div.wpfront-message {
		font-size: 14px;
		text-align: left;
	}
}

/* Breathing room between the cream's bottom edge and the payment marks, so the cards do
 * not sit against the hairline. */
body footer#site-footer .site-footer-copyright-area {
	padding-top: 30px;
}


/* ============================================================
 * Active-filter pills, added 2026-08-01
 * ------------------------------------------------------------
 * FacetWP's selections list, styled as removable chips. Requested after noticing that
 * clearing a filter otherwise means reopening the dropdown it came from.
 *
 * FacetWP's own markup already pairs the facet name with the value ("Style: Cheddar"),
 * which is the part the dropdowns lose: fSelect indicates a selection by REPLACING the
 * facet name with the value, so a filtered row reads "CHEDDAR, GOAT, FLAVOR, TEXTURE"
 * and you cannot tell which entries are values and which are filter names.
 *
 * The value span is the click target and carries role=button, tabindex, and an aria-label
 * of "Remove filter Style: Cheddar" from facet-refine.js. The X is decorative only.
 * ============================================================ */
.fromag-refine__active:empty { display: none; }
.fromag-refine__active .facetwp-selections ul {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}
.fromag-refine__active .facetwp-selections { margin-top: 16px; }
.fromag-refine__active .facetwp-selections li {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	margin: 0;
	padding: 6px 6px 6px 12px;
	background: #f6f1e9;
	border: 1px solid #e6e0d6;
	border-radius: 999px;
	font-size: 12px;
	letter-spacing: .06em;
	text-transform: uppercase;
	line-height: 1.2;
}
.fromag-refine__active .facetwp-selection-label {
	color: #5a5a5a;
	font-weight: 600;
}
/* Three classes deep on purpose. FacetWP's front.css uses
 * `.facetwp-selections .facetwp-selection-value` and loads AFTER the child theme, so a
 * two-class selector here loses on source order. That is also what put a second X on the
 * pill: FacetWP draws one as a background PNG (icon-close.png) with padding-right:16px,
 * and my ::after added another. The PNG is switched off below in favour of a text glyph,
 * which scales, inherits color, and can respond to hover and focus. */
.fromag-refine__active .facetwp-selections .facetwp-selection-value {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	color: #2b2620;
	font-weight: 600;
	cursor: pointer;
	border-radius: 999px;
	padding: 2px 8px 2px 2px;
	margin-right: 0;
	background-image: none;
}
/* Decorative X. aria-hidden is unnecessary because ::after content is not exposed to
 * assistive tech; the accessible name comes from the aria-label on the span itself. */
.fromag-refine__active .facetwp-selections .facetwp-selection-value::after {
	content: "\00d7";
	font-size: 15px;
	line-height: 1;
	color: #8a8177;
	transform: translateY(-1px);
}
.fromag-refine__active .facetwp-selections .facetwp-selection-value:hover,
.fromag-refine__active .facetwp-selections .facetwp-selection-value:focus-visible {
	color: #a85912;
}
.fromag-refine__active .facetwp-selections .facetwp-selection-value:hover::after,
.fromag-refine__active .facetwp-selections .facetwp-selection-value:focus-visible::after {
	color: #a85912;
}


/* ============================================================
 * Archive context chip, added 2026-08-01
 * ------------------------------------------------------------
 * On a product-attribute archive the filtering comes from the QUERY, not from a facet, so
 * the Style dropdown reads empty while the page is plainly filtered. This states the
 * context in words instead of faking a selected control.
 *
 * Deliberately NOT styled like the removable pills next to it: no X, square-ish rather
 * than fully rounded, and a left rule instead of a full border. If it looked like a pill
 * people would try to dismiss it, and it cannot be dismissed, because the URL is the
 * filter. The way out is the adjacent "All cheese" link, which is a real link.
 * ============================================================ */
.fromag-refine__context {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 14px;
	margin-top: 16px;
}
.fromag-context-chip {
	display: inline-flex;
	align-items: baseline;
	gap: 6px;
	padding: 6px 12px;
	background: #f6f1e9;
	border-left: 3px solid #a85912;
	border-radius: 0 4px 4px 0;
	font-size: 12px;
	letter-spacing: .06em;
	text-transform: uppercase;
	line-height: 1.2;
}
.fromag-context-chip__label {
	color: #5a5a5a;
	font-weight: 600;
}
.fromag-context-chip__value {
	color: #2b2620;
	font-weight: 700;
}
.fromag-context-clear {
	font-size: 12px;
	letter-spacing: .06em;
	text-transform: uppercase;
	font-weight: 600;
	color: #2b2620;
	text-decoration: underline;
	text-underline-offset: 3px;
}
.fromag-context-clear:hover,
.fromag-context-clear:focus-visible {
	color: #a85912;
}
/* When a context chip is present the selections list follows it on its own line. */
.fromag-refine__context + .facetwp-selections { margin-top: 12px; }


/* ============================================================
 * Product grid wrapping, fixed 2026-08-01
 * ------------------------------------------------------------
 * BUG: with certain filter combinations the last product landed alone in the RIGHT
 * column with a gap beside it, instead of starting a new row on the left. Found by
 * Bekee on ?_style=flavored&_texture=semi-firm, 19 results.
 *
 * CAUSE: ul.products is display:block with float:left items, and the cards are not all
 * the same height. Products WITH a star rating are 424px; products without are 404px.
 * Item 17 had stars, so item 19 could not clear that taller float and got pushed right.
 * Classic float snag. Star ratings are just today's trigger; a title that wraps to two
 * lines would do the same thing.
 *
 * FIX: wrapping flex instead of floats. Flex lines break on WIDTH only, so uneven
 * heights cannot affect where an item wraps. Deliberately does NOT set widths: the
 * theme's own responsive percentage widths still drive how many fit per row, so every
 * breakpoint keeps its existing column count without me having to reverse-engineer them
 * out of the minified parent stylesheet.
 *
 * align-items:flex-start keeps cards top-aligned, matching the current look. Switching to
 * stretch would equalise card heights within a row, which is a separate design decision.
 *
 * SELECTOR NOTE. The child theme is enqueued BEFORE WooCommerce's own stylesheets, so a
 * plain `ul.products li.product` loses to both of these on specificity:
 *   woocommerce-layout.css      .woocommerce ul.products.columns-3 li.product      (0,4,2)
 *   woocommerce-smallscreen.css .woocommerce ul.products[class*="columns-"] li...  (0,4,2)
 * The second one re-applies float:left inside a media query, so a fix that only beats the
 * first still breaks on tablet. Leading with `body` takes these to (0,4,3), which clears
 * both without reaching for !important. Widths are deliberately NOT touched; WooCommerce
 * keeps setting those per breakpoint, so the column counts stay exactly as they are. */
body.woocommerce ul.products[class*="columns-"] {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
}
body.woocommerce ul.products[class*="columns-"] li.product {
	float: none;
}

/* ONE PRODUCT PER ROW ON A PHONE, 2026-09-23. Bekee's call, from Kyle's Pixel 4
 * screenshots. Two across left each card about 170px wide: the home page rail
 * had no gutter at all, and a phone with its text size turned up breaks long
 * names mid-word ("Celebratio / n"), which no hyphenation setting fixes at that
 * width. One across gives every name the full column.
 *
 * Covers the archive grid AND the rails written into page content (the home
 * page does not carry body.woocommerce). Both selectors are (0,4,3), so they
 * clear woocommerce-smallscreen.css's `.woocommerce ul.products[class*=
 * "columns-"] li.product` (0,4,2), which sets the two-across widths. */
@media (max-width: 599px) {
	body.woocommerce ul.products[class*="columns-"] li.product,
	body .vc_row ul.products[class*="columns-"] li.product {
		width: 100%;
		margin-left: 0;
		margin-right: 0;
	}
}

/* ============================================================
 * Homepage: browse band and shop band
 * Added 2026-08-12 with the homepage rebuild. Both sections are
 * written into page content as raw HTML, so all structure lives
 * here in the theme and travels with it.
 *
 * ⚠️ SPECIFICITY: every heading and body selector below is written
 * as `.fromag-browse .fromag-browse__title` rather than the single
 * class, and that is deliberate. The Customizer emits an INLINE
 * typography sheet containing `.content-area h2, .entry-content h2`
 * (0,1,1), which loads after the theme stylesheet and beat every
 * single-class rule here: headings rendered at 33px and 27.6px in
 * #222 with letter-spacing stripped. Class-plus-class is (0,2,0)
 * and wins cleanly, so none of this needs !important. Any new
 * heading rule added to this block must be scoped the same way.
 * ============================================================ */

/* ⚠️ LEAD WITH `body` AND `.vc_row`, 2026-09-07. These bands became WPBakery
 * rows in the rebuild, and Mr. Tailor's css/styles.css loads AFTER the child
 * stylesheet, so a plain `.fromag-browse` (0,1,0) lost and every row computed
 * to zero padding. The sections rendered flush against each other. Same hazard
 * and same remedy as the archive grid and the product rail earlier in this
 * file. `stretch_row_content_no_spaces` also adds `vc_row-no-padding`, which is
 * why the horizontal padding is set here rather than left to the row. */
body .vc_row.fromag-browse {
	background: #f6f1e9;
	padding: 4.5rem 1.25rem;
	border-top: 1px solid #e6e0d6;
	border-bottom: 1px solid #e6e0d6;
}

/* ⚠️ `.fromag-browse__inner` and `.fromag-shop__inner` were divs in the raw
 * HTML and are gone as of 2026-09-07. WPBakery has no equivalent wrapper, so
 * the width cap moves onto the row's own inner element. Kept at 1180px, which
 * is what the two bands measured before the rebuild. */
.fromag-browse > .vc_row,
.fromag-shop > .vc_row,
.fromag-browse .wpb_column > .vc_column-inner,
.fromag-shop .wpb_column > .vc_column-inner {
	max-width: 1180px;
	margin-left: auto;
	margin-right: auto;
}

.fromag-browse .fromag-browse__title {
	margin: 0 0 0.35em;
	text-align: center;
	font-size: clamp(1.9rem, 3.4vw, 2.75rem);
	color: #2b2620;
}

.fromag-browse .fromag-browse__lede {
	margin: 0 auto 3rem;
	max-width: 44ch;
	text-align: center;
	color: #6b6357;
	font-size: 1.0625rem;
	line-height: 1.6;
}

/* ⚠️ The three columns are WPBakery inner columns as of 2026-09-07, not a CSS
 * grid. The band was rebuilt out of raw HTML into real page-builder elements so
 * Kyle can edit it, and WPBakery lays the columns out itself. Declaring
 * `display: grid` here fights that and collapses the row, so this rule now only
 * carries the gutter. If this band is ever reverted to raw HTML, put
 * `display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));` back. */
.fromag-browse__grid {
	margin-bottom: 0;
}

.fromag-browse__grid > .vc_column_container > .vc_column-inner {
	padding-top: 0;
	padding-bottom: 0;
}

.fromag-browse .fromag-browse__label {
	margin: 0 0 1rem;
	padding-bottom: 0.6rem;
	border-bottom: 1px solid #e6e0d6;
	font-size: 0.8125rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: #a85912;
	text-align: center;
}

/* ⚠️ The columns were never the problem, and it is worth writing down so this
 * does not get "fixed" by changing the grid. Each of the three is an exact
 * third, 403px at a 1647px viewport, running edge to edge with no gap. What
 * looked wrong is the CONTENT: the widest link is 187px under By style, 89px
 * under By milk, and 68px under By intensity, so three short left-aligned
 * lists sat in wide columns and the band read as drifting left.
 *
 * Centring the lists answers it, and it also matches the band, whose title and
 * lede are already centred. Bekee's call 2026-09-08 after seeing it on the real
 * page: "the three columns look great now." A fourth column was the other
 * option on the table and is not needed. */
.fromag-browse .fromag-browse__links {
	text-align: center;
}

.fromag-browse__links {
	margin: 0;
	padding: 0;
	list-style: none;
}

.fromag-browse__links li + li {
	margin-top: 0.55rem;
}

.fromag-browse .fromag-browse__links a {
	display: inline-block;
	color: #2b2620;
	font-size: 1.0625rem;
	text-decoration: none;
	border-bottom: 1px solid transparent;
	transition: border-color 0.2s ease, color 0.2s ease;
}

.fromag-browse .fromag-browse__links a:hover,
.fromag-browse .fromag-browse__links a:focus-visible {
	color: #a85912;
	border-bottom-color: #a85912;
}

.fromag-browse__cta {
	margin: 3rem 0 0;
	text-align: center;
}

/* Scoped class-plus-class: the parent theme sets `.content-area a
 * { text-decoration: underline }` (0,1,1), which beats a bare
 * .fromag-btn and put an underline through both button labels. */
.fromag-browse .fromag-btn,
.fromag-shop .fromag-btn,
.fromag-rail .fromag-btn,
.fromag-gifts .fromag-btn,
.fromag-blocks .fromag-btn,
.fromag-story .fromag-btn {
	display: inline-block;
	padding: 0.95rem 2.4rem;
	background: #2b2620;
	color: #fffdf9;
	font-size: 0.9375rem;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	text-decoration: none;
	border: 1px solid #2b2620;
	transition: background 0.2s ease, color 0.2s ease;
}

.fromag-browse .fromag-btn:hover,
.fromag-browse .fromag-btn:focus-visible,
.fromag-shop .fromag-btn:hover,
.fromag-shop .fromag-btn:focus-visible,
.fromag-rail .fromag-btn:hover,
.fromag-rail .fromag-btn:focus-visible,
.fromag-gifts .fromag-btn:hover,
.fromag-gifts .fromag-btn:focus-visible,
.fromag-blocks .fromag-btn:hover,
.fromag-blocks .fromag-btn:focus-visible,
.fromag-story .fromag-btn:hover,
.fromag-story .fromag-btn:focus-visible {
	background: transparent;
	color: #2b2620;
}

/* The shop band. Photograph and copy side by side, photo first on
 * desktop, copy first is avoided so the reading order matches the
 * visual order at every width. */
/* The shop band carries #d3c3ab, so the page reads as alternating bands.
 * Bekee's call 2026-09-07, after looking at three values on the real page:
 *   #f6f1e9  the site cream. Reads 1.12:1 against white, a hint not a band.
 *   #d4c581  the guide's Beige. Right weight, wrong color. Her words: "that
 *            color looks like baby shit." It sits at 49 degrees hue against
 *            the site's 37, and carries roughly twice the saturation.
 *   #d3c3ab  chosen. Same weight as the Beige (1.73:1 against white vs 1.74),
 *            at 36 degrees, so it belongs to the family already in the theme.
 *
 * ⚠️ THE GUIDE'S HEXES ARE NOT ITS COLORS. Five of the seven are exactly the
 * naive CMYK formula, 255*(1-ink)*(1-K), which ignores the ink and lands
 * over-saturated and off-hue. The orange is the one exception, which is why the
 * orange always looked right and the Beige never did. A color-managed
 * conversion was tried and rejected: it gets their orange wrong too. PMS 4525
 * is a solid ink and is not in the Pantone Process book on hand. So this is a
 * screen decision, deliberately, and print keeps using 4525 unchanged. Full
 * write-up for the client: fromagination/kyle-brand-colors-2026-09-07.md
 *
 * ⚠️ BEIGE IS SAFE HERE AND NOWHERE ELSE ON THE PAGE. Nothing orange sits in
 * this band; the heading, address, and button are all near-black. The new
 * orange #a85912 on Beige is 2.95:1 and fails even the 3:1 bar, so this color
 * must not go behind the browse band, the mega menu, or anything carrying an
 * orange link, border, or focus ring.
 *
 * ⚠️ It is painted with a full-bleed pseudo-element rather than by stretching
 * the row. Stretching it (`stretch_row_content_no_spaces`) DOES give an
 * edge-to-edge background, but it also uncaps the two columns and blew the
 * storefront photograph up from 596px to 881px. This keeps the layout exactly
 * as it is and only adds the color. */
body .vc_row.fromag-shop {
	padding: 4.5rem 1.25rem;
	position: relative;
	z-index: 0;
}

/* On Beige the ordinary body grey #6b6357 reads 3.41:1 and fails. Bekee's call
 * 2026-09-07: darken it to the heading's near-black rather than give up the
 * color. That takes it to 8.64:1. This override is scoped to this band, so
 * body copy everywhere else keeps the softer grey. */
body .vc_row.fromag-shop .fromag-shop__body {
	color: #2b2620;
}

body .vc_row.fromag-shop::before {
	content: "";
	/* ⚠️ `display: block` is REQUIRED and is not decoration. WPBakery sets
	 * `.vc_row:before { content:" "; display:table }` as its clearfix, and a
	 * table box ignores the top/bottom stretch: this element rendered 2px tall
	 * instead of 578px, so all that showed was its top and bottom border as two
	 * hairlines with no color between them. Bekee spotted exactly that. */
	display: block;
	position: absolute;
	top: 0;
	bottom: 0;
	left: 50%;
	width: 100vw;
	transform: translateX(-50%);
	background: #d3c3ab;
	border-top: 1px solid #c3b199;
	border-bottom: 1px solid #c3b199;
	z-index: -1;
}

/* ⚠️ Also WPBakery columns as of 2026-09-07, not a CSS grid. `.fromag-shop__media`
 * and `.fromag-shop__text` are now the two column classes rather than divs
 * inside a grid. WPBakery gives them 50/50; the widths below restore the
 * original 1.15 to 1 ratio (601px against 523px at 1647px wide, measured before
 * the rebuild) so the photograph still leads. */
.fromag-shop > .vc_row,
.fromag-shop .vc_row {
	align-items: center;
}

.fromag-shop .fromag-shop__media,
.fromag-shop .fromag-shop__text {
	display: flex;
	align-items: center;
}

@media (min-width: 901px) {
	.fromag-shop .fromag-shop__media { width: 53.5%; }
	.fromag-shop .fromag-shop__text  { width: 46.5%; }
}

.fromag-shop .fromag-shop__media img {
	display: block;
	width: 100%;
	height: auto;
}

/* WPBakery wraps a Single Image in figure > .vc_single_image-wrapper; without
 * this the photo sits at its intrinsic width instead of filling the column. */
.fromag-shop .fromag-shop__media .wpb_single_image,
.fromag-shop .fromag-shop__media .vc_single_image-wrapper,
.fromag-shop .fromag-shop__media figure {
	width: 100%;
	margin: 0;
}

.fromag-shop .fromag-shop__title {
	margin: 0 0 0.5em;
	font-size: clamp(1.75rem, 3vw, 2.4rem);
	color: #2b2620;
}

.fromag-shop .fromag-shop__body {
	margin: 0 0 1.6rem;
	color: #6b6357;
	font-size: 1.0625rem;
	line-height: 1.7;
}

.fromag-shop .fromag-shop__address {
	margin: 0 0 1.8rem;
	font-style: normal;
	color: #2b2620;
	line-height: 1.7;
}

@media (max-width: 900px) {
	.fromag-browse__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.fromag-shop__inner { grid-template-columns: 1fr; gap: 2.25rem; }
}

@media (max-width: 560px) {
	body .vc_row.fromag-browse { padding: 3rem 1.25rem; }
	body .vc_row.fromag-shop   { padding: 3rem 1.25rem; }
	body .vc_row.fromag-rail   { padding-top: 3rem; }
	body .vc_row.fromag-press  { padding-top: 3rem; }
}

/* ------------------------------------------------------------
 * Hero: kill the space between the header and the photograph.
 *
 * Two separate causes, found 2026-08-12 by measuring the boxes:
 * 1. The row carried full_height="yes" with content_placement="middle",
 *    so the row stretched to the viewport, the carousel sat 611px inside
 *    a 715px row, and centering split the leftover 104px into 52px above
 *    and 52px below. That attribute is now removed from the page content.
 * 2. WPBakery gives every .wpb_content_element a 35px bottom margin,
 *    which put a second gap under the hero.
 * ------------------------------------------------------------ */
.fromag-hero.wpb_content_element { margin-bottom: 0; }

/* ------------------------------------------------------------
 * Curated product rail.
 *
 * The child theme's flex fix for WooCommerce grids is scoped to
 * body.woocommerce, and the HOMEPAGE does not carry that class; its body
 * is `home ... woocommerce-no-js` only. So a [products] shortcode dropped
 * into page content still floats its items, the <ul> collapses to zero
 * height, and the next section renders on top of it. Same fix, scoped to
 * the rail instead of to the body.
 *
 * ⚠️ LEAD WITH `body`, 2026-09-07. Written first as a plain `.fromag-rail
 * ul.products` (0,2,1), which SHOULD beat the parent's `.woocommerce
 * ul.products` (0,1,1) and did not. Mr. Tailor's `css/styles.css` loads AFTER
 * the child stylesheet (sheet 35 against sheet 32 in the rendered page), and
 * something in it re-asserts display:block over that selector. The result was
 * four products stacked in a single column on the homepage while the archive
 * grid, which already leads with `body`, was fine. Confirmed in the browser:
 * adding `body` flipped the computed display from block to flex and dropped
 * the four cards onto one row. Same hazard, and same remedy, as the archive
 * grid note earlier in this file.
 * ------------------------------------------------------------ */
body .fromag-rail ul.products {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
}

body .fromag-rail ul.products li.product {
	float: none;
}

/* Same vertical rhythm as the browse band above it, so the three
 * lower sections read as one system rather than three blocks with
 * different breathing room. */
body .vc_row.fromag-rail {
	padding-top: 4.5rem;
	padding-bottom: 2.5rem;
}

/* The press band closes the page, so it needs air above it and room below the
 * logos before the footer starts. Added 2026-09-07 with the padding fix; it had
 * none of its own and sat flush against the shop band. */
body .vc_row.fromag-press {
	padding-top: 4.5rem;
	padding-bottom: 3rem;
}

@media (max-width: 560px) {
	.vc_row.fromag-rail { padding-top: 3rem; }
}

/* The typography block at the top of this file sets `letter-spacing: 0
 * !important` on h1-h6, which is right for real headings but wrong for the
 * uppercase micro-labels in the browse band; at 13px they need tracking or the
 * caps crowd. This is the one deliberate exception, scoped to those labels
 * only, and it needs !important solely to answer the !important above. */
.fromag-browse .fromag-browse__label {
	letter-spacing: 0.14em !important;
}

/* ------------------------------------------------------------
 * Press band ("As seen in" + the logo marquee).
 *
 * The hero's WPBakery bottom margin was zeroed above, which left this
 * label sitting flush against the bottom edge of the photograph. Rather
 * than restore a framework default, the band owns its spacing here, so
 * the rhythm between hero, press, and browse is set in one place.
 * ------------------------------------------------------------ */
.vc_row.fromag-press {
	padding-top: 3.5rem;
	padding-bottom: 1rem;
}

@media (max-width: 560px) {
	.vc_row.fromag-press { padding-top: 2.25rem; }
}

/* ------------------------------------------------------------
 * Links that leave the site.
 *
 * Asked for 2026-09-08. The icon is a CSS mask painted in currentColor, so
 * it inherits the link's own color and keeps whatever contrast that link
 * already passes. A background-image would need a fixed fill, and this site
 * puts links on cream, on tan, and on near-black.
 *
 * ⚠️ The @supports guard is load-bearing. Without mask support the
 * background-color alone renders as a solid square block next to the text,
 * so the icon has to be absent rather than wrong.
 * ------------------------------------------------------------ */
.fromag-sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

@supports ((-webkit-mask-image: none) or (mask-image: none)) {
	.fromag-external__icon {
		display: inline-block;
		width: 0.72em;
		height: 0.72em;
		margin-left: 0.3em;
		background-color: currentColor;
		-webkit-mask: var(--fromag-external-icon) no-repeat center / contain;
		mask: var(--fromag-external-icon) no-repeat center / contain;
		/* The glyph reads as part of the word it follows, so it sits on the
		 * text baseline rather than being centred on the line box. */
		vertical-align: -0.02em;
	}
}

:root {
	--fromag-external-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6.5 3H3.2A1.2 1.2 0 0 0 2 4.2v8.6A1.2 1.2 0 0 0 3.2 14h8.6a1.2 1.2 0 0 0 1.2-1.2V9.5'/%3E%3Cpath d='M9.5 2H14v4.5'/%3E%3Cpath d='M14 2 7.6 8.4'/%3E%3C/svg%3E");
}

/* The mega-menu panels and the footer widgets set their own line-height and
 * font-size, and the icon is sized in em, so it tracks both without a
 * per-context override. Nothing to add for those. */

/* ============================================================
 * Homepage: Ken's section order, 2026-09-09.
 *
 * Added when the homepage was rebuilt to the list Ken sent Kyle on
 * 2026-09-08 (Basecamp to-do 10284394983). Five new bands plus a hero
 * overlay. Everything here follows the two conventions the older
 * homepage block above already established, and both are load-bearing:
 *
 *   1. Row-level rules LEAD WITH `body .vc_row`. Mr. Tailor's
 *      css/styles.css loads after this stylesheet, so a plain
 *      `.fromag-gifts` (0,1,0) loses and the row computes to zero padding.
 *   2. Heading and body rules are written CLASS-PLUS-CLASS. The
 *      Customizer emits an inline `.content-area h2` sheet (0,1,1) that
 *      beats any single class here.
 *
 * ⚠️ The colored bands are painted with a full-bleed ::before, NOT with
 *    `stretch_row_content_no_spaces`. Stretching a row uncaps its columns;
 *    that is what blew the storefront photograph from 596px to 881px on
 *    2026-09-07. And the ::before needs an explicit `display: block`,
 *    because WPBakery's own `.vc_row:before { display: table }` clearfix
 *    collapses it to a 2px sliver otherwise.
 * ============================================================ */

/* ---------- Shared: the width cap ---------- */
.fromag-gifts .wpb_column > .vc_column-inner,
.fromag-blocks .wpb_column > .vc_column-inner,
.fromag-story .wpb_column > .vc_column-inner {
	max-width: 1180px;
	margin-left: auto;
	margin-right: auto;
}

/* ---------- Shared: a photograph that has not been chosen yet ----------
 * Deliberately drawn in CSS rather than pointed at a placeholder
 * attachment. An empty slot needs no media library entry, so it costs
 * nothing to push to staging and it cannot be mistaken for a real photo. */
.fromag-slot {
	display: flex;
	align-items: center;
	justify-content: center;
	aspect-ratio: 4 / 3;
	margin-bottom: 1.4rem;
	background: #f6f1e9;
	border: 2px dashed #c3b199;
	color: #2b2620;
	font-size: 0.8125rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
}

/* Our Story's slot is square rather than portrait. At 4/5 it stood 612px tall
 * against a 267px paragraph and swamped the section; square puts it at 490px,
 * within reach of the shop band's 434px photograph, so the two split sections
 * on the page read as the same device. */
.fromag-slot--tall { aspect-ratio: 1 / 1; margin-bottom: 0; }

/* ---------- Shared: a chosen photograph, 2026-09-14 ----------
 * Ken's photos replaced the slots above as WPBakery Single Images, so Kyle can
 * swap one in the builder. They take the slot's exact footprint: 4:3 in the
 * blocks, square in Our Story. The files are wider than the slot, and this CSS
 * crops them. Where the crop sits is set per photo by the Media Focus Point
 * plugin, which prints an inline object-position that wins over any below.
 * `.wpb_content_element` gives every Single Image a 35px bottom margin, so the
 * margin is set on the element itself at a higher specificity. */
.fromag-blocks .wpb_single_image.fromag-photo,
.fromag-story .wpb_single_image.fromag-photo {
	width: 100%;
	margin: 0 0 1.4rem;
}

.fromag-photo .vc_figure,
.fromag-photo .vc_single_image-wrapper {
	display: block;
	width: 100%;
	margin: 0;
}

.fromag-photo img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 4 / 3;
	object-fit: cover;
}

.fromag-story .wpb_single_image.fromag-photo { margin-bottom: 0; }
.fromag-story .fromag-photo img { aspect-ratio: 1 / 1; }
.fromag-story .fromag-story__media > .vc_column-inner { width: 100%; }

/* ---------- Shared: the quieter in-block link ---------- */
.fromag-blocks .fromag-link,
.fromag-story .fromag-link {
	display: inline-block;
	color: #a85912;
	font-size: 0.9375rem;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	text-decoration: none;
	border-bottom: 1px solid currentColor;
	padding-bottom: 2px;
}

.fromag-blocks .fromag-link:hover,
.fromag-blocks .fromag-link:focus-visible,
.fromag-story .fromag-link:hover,
.fromag-story .fromag-link:focus-visible {
	color: #2b2620;
}

/* ============================================================
 * 1. Hero overlay
 *
 * Ken asked for a headline, a subline, and four buttons centred over the
 * photograph. The <h1> is new; this page carried no h1 at all before.
 *
 * ⚠️ CONTRAST. The overlay carries its own scrim, and the scrim is not
 *    decoration: the text sits over a photograph whose brightness is not
 *    knowable, so the scrim is the only thing holding the ratio up.
 *
 *    MEASURED 2026-09-09, against a control that painted the slide pure
 *    white with the type hidden, so nothing real can be lighter:
 *
 *      headline  64px,      large text,  bar 3.0  ->  5.71:1  PASS
 *      subline   16px bold, normal text, bar 4.5  ->  6.07:1  PASS
 *
 *    The scrim this replaced ran 0.34 to 0.72 and measured 3.13:1 and
 *    3.77:1 under the same control, so the subline was failing.
 *
 *    ⚠️ Do not lighten the scrim without re-running that control. And do
 *    not compute this figure instead of measuring it: the first estimate
 *    here was calculated rather than rendered and was off by a factor of
 *    two in the safe-looking direction.
 * ============================================================ */
body .vc_row.fromag-herorow {
	position: relative;
}

.fromag-herorow .fromag-hero__overlay {
	position: absolute;
	inset: 0;
	z-index: 2;
	display: flex;
	flex-direction: column;
	align-items: center;
	/* ⚠️ BOTTOM-ANCHORED, NOT CENTRED, 2026-09-09. Bekee's call, and it is what
	 * lets the top of the photograph stay clear. The scrim only has to be dark
	 * where the type sits; centring the type forced the dark band into the
	 * middle of the frame, which is where the subject of a food photograph
	 * usually is. Pushing the type down moves the dark band down with it.
	 *
	 * The bottom padding is set so the buttons clear the carousel's own slide
	 * indicators, which sit bottom-centre. Do not reduce it below 4.5rem
	 * without checking that the buttons and the dots do not overlap. */
	justify-content: flex-end;
	margin-bottom: 0;
	padding: 2rem 1.25rem 4.75rem;
	text-align: center;
	/* ⚠️ THE SCRIM IS THE COMPLIANCE, AND IT IS TUNED TO A NUMBER, 2026-09-09.
	 * An earlier version ran 0.34 to 0.72 and was set from a calculation rather
	 * than a rendering. Measured under a control that paints the slide pure
	 * white with the type hidden, it came out at 3.13:1 for the headline and
	 * 3.77:1 for the subline, so the subline was failing 4.5:1.
	 *
	 * The stops are derived. Against a pure-white photograph this scrim colour
	 * has to reach 0.46 opacity for the 64px headline to clear 3:1, and 0.58
	 * for the 16px bold subline to clear 4.5:1. With the type bottom-anchored
	 * it occupies 53% to 87% of the hero's height, so everything from 52% down
	 * is held at 0.66 or darker and the top quarter is left uncovered.
	 *
	 * MEASURED 2026-09-09, worst row of each element over pure white:
	 *
	 *   headline  top at 53%, scrim 0.66  ->  6.01:1   bar 3.0   PASS
	 *   subline   top at 68%, scrim 0.69  ->  6.60:1   bar 4.5   PASS
	 *   top of frame: scrim 0.00 at 0%, 0.08 at 26%
	 *
	 * Moving the type DOWN raised both ratios and uncovered the photograph at
	 * the same time, because the type now sits in the part of the gradient that
	 * was already dark. Centred type forced the dark band into the middle of
	 * the frame, which is where the subject of a food photograph lives.
	 *
	 * RE-TUNED 2026-09-23 (four-column mockup, Local only): the buttons left the
	 * slide, so the type sits lower (headline top 65% to 74%, subline 78% to
	 * 86%) and the scrim starts later. Old stops: 0/.08@26/.38@42/.66@52/.74.
	 * Re-measured with the same white control, worst row of each element:
	 *
	 *   412x780    headline 4.52:1   subline 5.30:1
	 *   1024x700   headline 4.04:1   subline 5.31:1
	 *   1440x900   headline 4.72:1   subline 5.54:1
	 *   1895x1000  headline 5.07:1   subline 5.63:1
	 *   top 35% of the frame: scrim 0.00
	 *
	 * REVERTED 2026-09-23 (evening): Kyle and Ken asked for Shop Cheese back on
	 * the hero, so a button sits under the subline again and the type rises
	 * with it. The 9/09 stops are back: 0/.08@26/.38@42/.66@52/.74.
	 * Re-measured on STAGING with the white control, worst row of each element:
	 *
	 *   352x780    headline 4.22:1   subline 6.46:1
	 *   412x780    headline 6.08:1   subline 6.36:1
	 *   1024x700   headline 4.17:1   subline 6.36:1
	 *   1440x900   headline 6.17:1   subline 6.76:1
	 *   1895x1000  headline 6.26:1   subline 6.86:1
	 *
	 * ⚠️ MOVING THE TYPE MOVES THIS. If the padding above changes, or the
	 * headline wraps to another line, re-run the white control and re-measure.
	 * Do not compute this figure; computing it is what got it wrong once.
	 * The buttons carry their own solid background and need none of it. */
	background: linear-gradient(
		to bottom,
		rgba(20, 17, 13, 0.00) 0%,
		rgba(20, 17, 13, 0.08) 26%,
		rgba(20, 17, 13, 0.38) 42%,
		rgba(20, 17, 13, 0.66) 52%,
		rgba(20, 17, 13, 0.74) 100%
	);
	/* ⚠️ The overlay covers the whole hero, so without this it swallows every
	 * click meant for the carousel underneath. Measured 2026-09-09: the prev
	 * and next arrows were unreachable, hit-testing to .wpb_wrapper instead.
	 * The gradient still paints; only hit testing passes through. Anything in
	 * here that is meant to be clicked has to take pointer events back, which
	 * is what the rule below does. */
	pointer-events: none;
}

.fromag-herorow .fromag-hero__overlay a,
.fromag-herorow .fromag-hero__overlay button {
	pointer-events: auto;
}

/* ⚠️ The flex column has to be repeated on .wpb_wrapper, and it is not
 * redundant. WPBakery puts a plain <div class="wpb_wrapper"> between the text
 * column and its content, so the overlay's only flex item is that wrapper.
 * Centring the overlay therefore centres the wrapper, and the headline inside
 * it stayed a left-aligned block: the title sat 98px left of the buttons on the
 * first build. Centring both levels is what actually lines them up. */
.fromag-herorow .fromag-hero__overlay > .wpb_wrapper {
	display: flex;
	flex-direction: column;
	align-items: center;
	width: 100%;
}

/* ------------------------------------------------------------
 * Hero type: a stroke behind the letterforms.
 *
 * Asked for 2026-09-09, so the headline holds up over whatever photograph
 * is underneath it. This is a text STROKE, not a glow and not a shadow.
 *
 * ⚠️ `paint-order: stroke fill` is the load-bearing half. Without it the
 *    stroke is centred on the glyph edge and eats into the letterform, so
 *    the type looks thinner and muddier the wider the stroke goes. Painting
 *    the stroke first and the fill over it keeps the letter shapes intact
 *    and puts the whole stroke outside them.
 *
 * ⚠️ HONEST LIMIT, worth keeping in writing: a stroke improves legibility
 *    but it does NOT change the measured contrast ratio, which is computed
 *    against the background behind the text. The scrim on the overlay is
 *    what carries the 5.71:1 and 6.07:1 recorded above. The stroke is
 *    insurance on top of that, for a very light patch in one photograph.
 *
 * The fallback is silent and safe. A browser without -webkit-text-stroke
 * renders plain cream type on the scrim, which already passes.
 * ------------------------------------------------------------ */
.fromag-herorow .fromag-hero__title,
.fromag-herorow .fromag-hero__lede {
	paint-order: stroke fill;
	-webkit-text-stroke: 0.055em #14110d;
	text-stroke: 0.055em #14110d;
}

/* The headline takes a lighter stroke than the subline, and the ratio is
 * deliberate. Vollkorn is a serif whose whole character is the contrast
 * between its thick and thin strokes; at 0.055em on 64px the thins filled in
 * and the face started reading as a slab. Small text needs proportionally
 * more stroke to survive a photograph, large text needs less. */
.fromag-herorow .fromag-hero__title {
	-webkit-text-stroke: 0.035em #14110d;
	text-stroke: 0.035em #14110d;
}

.fromag-herorow .fromag-hero__title {
	margin: 0 0 0.3em;
	max-width: 18ch;
	color: #fffdf9;
	font-size: clamp(2.2rem, 5.4vw, 4rem);
	line-height: 1.08;
}

/* ⚠️ LEAD WITH `body`, 2026-09-09, and this one is not optional. The
 * Customizer's inline sheet carries `.site-content p:not([class*="has-"])`
 * at (0,2,1), which BEAT the (0,2,0) this rule had and pinned the lede to
 * 16px no matter what was set here. The clamp that used to be on this rule
 * never once applied. Any new rule on a <p> inside this build needs three
 * classes, or it loses the same way and does so silently.
 *
 * Size and weight are matched to the main nav deliberately, 16px DM Sans at
 * 700, so the two read as the same voice. Bekee's call: the subline has to
 * hold its own over a photograph, and weight does that where size does not. */
body .fromag-herorow .fromag-hero__lede {
	margin: 0 0 2rem;
	/* Wide enough that the sentence sits on one line on a desktop viewport.
	 * At 46ch it broke after "Capitol" and left "Square." alone. */
	max-width: 68ch;
	color: #fffdf9;
	font-size: 1rem;
	font-weight: 700;
	line-height: 1.55;
	/* Where it still has to wrap, even the lines rather than orphaning the
	 * last word. Unsupported browsers just wrap normally. */
	text-wrap: balance;
}

.fromag-herorow .fromag-hero__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	justify-content: center;
	margin: 0;
}

/* The hero buttons are defined here in full rather than joining the shared
 * .fromag-btn list. The shared hover flips to near-black text on a
 * transparent background, which on a dark scrim is unreadable. */
.fromag-herorow .fromag-btn {
	display: inline-block;
	padding: 0.85rem 1.6rem;
	background: #2b2620;
	color: #fffdf9;
	font-size: 0.875rem;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	text-decoration: none;
	border: 1px solid #fffdf9;
	transition: background 0.2s ease, color 0.2s ease;
}

body .fromag-herorow .fromag-btn:hover,
body .fromag-herorow .fromag-btn:focus-visible {
	background: #fffdf9;
	color: #2b2620;
}

@media (max-width: 700px) {
	.fromag-herorow .fromag-hero__lede { margin-bottom: 1.4rem; }
	.fromag-herorow .fromag-btn { padding: 0.7rem 1.15rem; font-size: 0.8125rem; }
}

/* THE WHOLE PHOTOGRAPH IS THE SHOP CHEESE LINK, 2026-09-23. Kyle and Ken asked
 * that a click on the hero image go to Cheese, and Bekee put the Shop Cheese
 * button back on the slide. This does both with ONE link: the button's ::after
 * stretches over the overlay (the nearest positioned ancestor), so the photo
 * is the button's hit area. A second <a> wrapping the slide would nest links.
 * The focus ring stays on the visible button, and a screen reader hears one
 * link, "Shop Cheese."
 *
 * ⚠️ The arrows, dots, and pause control must stay ABOVE this layer, or the
 *    photo swallows their clicks. The pause control is z-index 3 inside the
 *    overlay; the arrows and dots are raised below. Check all three by mouse
 *    after any change to the overlay's stacking. */
.fromag-herorow .fromag-hero__actions .fromag-btn::after {
	content: "";
	position: absolute;
	inset: 0;
}
.fromag-herorow .vc_images_carousel .vc_carousel-control,
.fromag-herorow .vc_images_carousel .vc_carousel-indicators {
	z-index: 5;
}

/* ============================================================
 * 2. Signature cheeses: the existing shelf, now with a call to action
 * ============================================================ */
.fromag-rail .fromag-rail__cta {
	margin: 2.5rem 0 0;
	text-align: center;
}

/* ============================================================
 * 3. Wisconsin gift sets
 * ============================================================ */
body .vc_row.fromag-gifts {
	padding: 4.5rem 1.25rem;
	position: relative;
	z-index: 0;
}

body .vc_row.fromag-gifts::before {
	content: "";
	display: block;                 /* required: see the clearfix note above */
	position: absolute;
	top: 0;
	bottom: 0;
	left: 50%;
	width: 100vw;
	transform: translateX(-50%);
	background: #f6f1e9;
	border-top: 1px solid #e6e0d6;
	border-bottom: 1px solid #e6e0d6;
	z-index: -1;
}

.fromag-gifts .fromag-gifts__title {
	margin: 0 0 0.35em;
	text-align: center;
	font-size: clamp(1.9rem, 3.4vw, 2.75rem);
	color: #2b2620;
}

.fromag-gifts .fromag-gifts__lede {
	margin: 0 auto 3rem;
	max-width: 46ch;
	text-align: center;
	color: #6b6357;
	font-size: 1.0625rem;
	line-height: 1.6;
}

.fromag-gifts .fromag-gifts__cta {
	margin: 2.5rem 0 0;
	text-align: center;
}

/* ============================================================
 * 4 and 5. Corporate gifting & catering, and Experience Fromagination
 *
 * One band pattern serving both. The two-up is the default; the
 * `--three` modifier only changes the anchor offset and the heading,
 * because WPBakery lays the columns out itself from the width attribute.
 * ============================================================ */
body .vc_row.fromag-blocks {
	padding: 4.5rem 1.25rem;
	position: relative;
	z-index: 0;
	/* The hero's fourth button jumps here, and the header is sticky. */
	scroll-margin-top: 6rem;
}

body .vc_row.fromag-blocks--three::before {
	content: "";
	display: block;
	position: absolute;
	top: 0;
	bottom: 0;
	left: 50%;
	width: 100vw;
	transform: translateX(-50%);
	background: #f6f1e9;
	border-top: 1px solid #e6e0d6;
	border-bottom: 1px solid #e6e0d6;
	z-index: -1;
}

.fromag-blocks .fromag-blocks__title {
	margin: 0 0 0.35em;
	text-align: center;
	font-size: clamp(1.9rem, 3.4vw, 2.75rem);
	color: #2b2620;
}

.fromag-blocks .fromag-blocks__lede {
	margin: 0 auto 3rem;
	max-width: 46ch;
	text-align: center;
	color: #6b6357;
	font-size: 1.0625rem;
	line-height: 1.6;
}

/* The head sits above the columns; without this the WPBakery text column
 * keeps its own bottom margin and the gap doubles. */
.fromag-blocks .fromag-blocks__head { margin-bottom: 0; }

.fromag-blocks .fromag-blocks__grid > .vc_column_container > .vc_column-inner {
	padding-top: 0;
}

.fromag-blocks .fromag-blocks__label {
	margin: 0 0 0.5em;
	font-size: 1.25rem;
	color: #2b2620;
	letter-spacing: 0.02em;
}

.fromag-blocks .fromag-blocks__body {
	margin: 0 0 1.2rem;
	color: #6b6357;
	font-size: 1rem;
	line-height: 1.65;
}

.fromag-blocks .fromag-blocks__cta {
	margin: 3rem 0 0;
	text-align: center;
}

/* ============================================================
 * 6. Our story
 *
 * Photo left, copy right, matching the shop band's proportions so the two
 * split sections on the page read as the same device.
 * ============================================================ */
body .vc_row.fromag-story {
	padding: 4.5rem 1.25rem;
}

.fromag-story > .vc_row,
.fromag-story .vc_row {
	align-items: center;
}

.fromag-story .fromag-story__media,
.fromag-story .fromag-story__text {
	display: flex;
	align-items: center;
}

@media (min-width: 901px) {
	.fromag-story .fromag-story__media { width: 46%; }
	.fromag-story .fromag-story__text  { width: 54%; }
}

/* Centre the photo and the copy against each other, in Our Story AND the shop
 * band, 2026-09-14. The `align-items: center` rules above never took effect:
 * both rows are `display: block` (WPBakery floats its columns), so each column
 * sat at the top of the row. It showed once real copy and Ken's shorter winter
 * storefront went in. Desktop only; the columns stack below 901px.
 * The shop band's full-bleed ::before is position:absolute, so it is not a flex
 * item and keeps painting the band. */
@media (min-width: 901px) {
	body .vc_row.fromag-story,
	body .vc_row.fromag-shop {
		display: flex;
		align-items: center;
	}
}

.fromag-story .fromag-story__media .wpb_text_column,
.fromag-story .fromag-story__media .wpb_wrapper { width: 100%; }

.fromag-story .fromag-story__title {
	margin: 0 0 0.5em;
	font-size: clamp(1.75rem, 3vw, 2.4rem);
	color: #2b2620;
}

.fromag-story .fromag-story__body {
	margin: 0 0 1.8rem;
	color: #6b6357;
	font-size: 1.0625rem;
	line-height: 1.7;
}

/* ============================================================
 * 7. Visit us: the shop band's new hours list
 *
 * The band's own colour, padding, and column widths are unchanged and
 * still live in the shop-band block further up this file. Only the hours
 * are new.
 *
 * ⚠️ Body copy in this band is overridden to near-black up in that block,
 *    because the ordinary grey fails on the tan. The same applies here:
 *    do not give the hours a lighter colour.
 * ============================================================ */
.fromag-shop .fromag-shop__hourslabel {
	margin: 0 0 0.5em;
	font-size: 0.8125rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: #2b2620;
}

.fromag-shop .fromag-hours {
	display: grid;
	grid-template-columns: auto 1fr;
	gap: 0.3rem 1.25rem;
	margin: 0 0 1.8rem;
	color: #2b2620;
	font-size: 0.9375rem;
	line-height: 1.5;
}

.fromag-shop .fromag-hours dt { font-weight: 600; }
.fromag-shop .fromag-hours dd { margin: 0; }

@media (max-width: 900px) {
	body .vc_row.fromag-gifts,
	body .vc_row.fromag-blocks,
	body .vc_row.fromag-story { padding: 3rem 1.25rem; }
	.fromag-slot--tall { aspect-ratio: 4 / 3; margin-bottom: 1.4rem; }
	.fromag-story .wpb_single_image.fromag-photo { margin-bottom: 1.4rem; }
	.fromag-story .fromag-photo img { aspect-ratio: 4 / 3; object-position: 50% 30%; }
}

/* ------------------------------------------------------------
 * Homepage hero: the pause control.
 *
 * Added 2026-09-09 with the rotating hero. The button is injected by
 * assets/js/hero-carousel.js and only when the hero holds more than one
 * image, so this block styles something that is often not on the page.
 *
 * It sits bottom-right rather than under the buttons, because the hero's
 * own slide indicators already own the bottom centre.
 * ------------------------------------------------------------ */
.fromag-herorow .fromag-hero__pause {
	position: absolute;
	right: 1.25rem;
	bottom: 1.25rem;
	z-index: 3;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 2.75rem;
	height: 2.75rem;
	padding: 0;
	/* #fffdf9 on this reads 7.9:1, so the glyph clears AA as text and the
	 * control clears the 3:1 non-text minimum against the photograph. */
	background: rgba(20, 17, 13, 0.66);
	color: #fffdf9;
	border: 1px solid #fffdf9;
	border-radius: 50%;
	cursor: pointer;
	line-height: 1;
	transition: background 0.2s ease, color 0.2s ease;
}

.fromag-herorow .fromag-hero__pause:hover,
.fromag-herorow .fromag-hero__pause:focus-visible {
	background: #fffdf9;
	color: #2b2620;
}

.fromag-herorow .fromag-hero__pauseicon {
	font-size: 0.9rem;
	letter-spacing: 0.06em;
}

/* The play triangle is optically heavier and sits off-centre in the circle
 * unless it is nudged. The pause bars do not need it. */
.fromag-herorow .fromag-hero__pause .fromag-hero__pauseicon:only-child {
	transform: translateX(0.03em);
}

@media (max-width: 700px) {
	.fromag-herorow .fromag-hero__pause {
		right: 0.75rem;
		bottom: 0.75rem;
		width: 2.4rem;
		height: 2.4rem;
	}
}

/* ============================================================
 * Homepage spacing corrections, 2026-09-09.
 *
 * ⚠️⚠️ READ THIS BEFORE SETTING margin-bottom ON ANYTHING INSIDE A
 * WPBAKERY TEXT BLOCK. js_composer.min.css ships:
 *
 *     #content .wpb_text_column :last-child { margin-bottom: 0 }
 *
 * That is (1,2,0). An ID beats any number of classes, so EVERY
 * class-based margin-bottom in this file lost to it silently, and the
 * three gaps corrected below were all the same bug wearing different
 * clothes. Note the descendant combinator and the bare `:last-child`:
 * it hits any last child at any depth, not just the direct one.
 *
 * THE FIX IS NOT A SPECIFICITY WAR. Put the space on an element that
 * rule cannot reach: the next box's margin-TOP (it only zeroes bottom),
 * or a wrapper that is not itself a last child. Both are used below.
 * ============================================================ */

/* 1. The photo slots sat flush against the section subhead, because the
 *    subhead is the last child of its text block and lost its 3rem. The
 *    grid is a vc_row_inner, outside any text block, so it can carry the
 *    space instead. This also gives the Experience band the same gap even
 *    though it has a heading and no subhead. */
body .fromag-blocks .fromag-blocks__grid {
	margin-top: 3rem;
}

/* 2. Plan Your Visit sat flush against the hours, same cause: the <dl> is
 *    the last child of .fromag-shop__hours. The wrapping div is NOT a last
 *    child, so the space goes there and holds. */
.fromag-shop .fromag-shop__hours {
	margin-bottom: 1.8rem;
}

/* 3. The press band ran 143px into the footer. Measured, it was four boxes
 *    stacked: the marquee's own 24px, a 35px WPBakery margin on the raw-HTML
 *    element, 48px of row padding, and 60px of the theme's .content-area
 *    margin. The last one is global and belongs to every page, so it stays.
 *    Clearing the two that are this band's own doing takes it to about 84px. */
body .vc_row.fromag-press {
	padding-bottom: 0;
}

.fromag-press .wpb_raw_code,
.fromag-press .wpb_raw_html {
	margin-bottom: 0;
}

/* ------------------------------------------------------------
 * Hero: the previous and next arrows.
 *
 * Asked for 2026-09-09. WPBakery ships them as a black serif chevron at
 * 50% opacity, which on a photograph is invisible, and as black-on-dark
 * it fails the 3:1 minimum for a control by a wide margin.
 *
 * They get the same treatment as the pause control so the three hero
 * controls read as one set. If one changes, change all three.
 *
 * ⚠️ THREE CLASSES, NOT TWO, AND IT IS NOT DECORATION.
 *    vc_carousel.min.css carries `.vc_images_carousel .vc_carousel-control`
 *    at (0,2,0) and loads AFTER this stylesheet, so a two-class rule here
 *    TIES and loses on source order. Colour came through and width, height,
 *    and opacity silently did not. Adding `.vc_images_carousel` makes it
 *    (0,3,0) and wins outright, with no !important anywhere.
 *
 * ⚠️ These sit OUTSIDE .fromag-hero__overlay, so they do not need the
 *    pointer-events exception the overlay's own links need. They were
 *    unreachable by mouse until the overlay stopped swallowing clicks.
 * ------------------------------------------------------------ */
.fromag-hero .vc_images_carousel .vc_carousel-control {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	z-index: 3;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 2.75rem;
	height: 2.75rem;
	margin: 0;
	/* Same 0.66 scrim as the pause control: #fffdf9 on it reads 7.9:1, so the
	 * glyph clears AA as text and the control clears the 3:1 non-text bar
	 * against any photograph underneath. */
	background: rgba(20, 17, 13, 0.66);
	color: #fffdf9;
	border: 1px solid #fffdf9;
	border-radius: 50%;
	opacity: 1;
	text-decoration: none;
	transition: background 0.2s ease, color 0.2s ease;
}

/* .vc_carousel-control is in these selectors on purpose, 2026-09-23. Without
 * it, vc_carousel.min.css's `.vc_carousel-control.vc_right { right: 0 }` tied
 * on specificity, loaded later, and won, so the right arrow sat flush with the
 * edge while the left one sat 20px in. */
.fromag-hero .vc_images_carousel .vc_carousel-control.vc_left  { left: 1.25rem; right: auto; }
.fromag-hero .vc_images_carousel .vc_carousel-control.vc_right { right: 1.25rem; left: auto; }

.fromag-hero .vc_images_carousel .vc_carousel-control:hover,
.fromag-hero .vc_images_carousel .vc_carousel-control:focus-visible {
	background: #fffdf9;
	color: #2b2620;
	opacity: 1;
}

/* ⚠️ THE CHEVRON IS DRAWN, NOT TYPED, 2026-09-09.
 * WPBakery renders it as a serif "‹" in a <span>. A glyph is positioned by
 * the font's ascent and descent, not by its ink, so flex-centring the span
 * still left the mark high and left inside the circle. Bekee caught it.
 * Nudging it in em was guessing at font metrics and would drift with any
 * font change.
 *
 * A mask has no metrics: the artwork is the box, so centre is centre. It is
 * painted in currentColor, so the hover inversion carries it for free, and
 * one shape serves both arrows by flipping the right one on the X axis.
 *
 * ⚠️ The @supports guard is load-bearing, and it is the same one the
 * external-link icon uses further up. Without mask support the
 * background-color alone would render as a solid square, so in that case
 * the span stays visible and the original glyph is used instead. */
.fromag-hero .vc_images_carousel .vc_carousel-control span {
	display: block;
	color: inherit;
	font-size: 1.75rem;
	line-height: 1;
}

@supports ((-webkit-mask-image: none) or (mask-image: none)) {
	.fromag-hero .vc_images_carousel .vc_carousel-control span { display: none; }

	.fromag-hero .vc_images_carousel .vc_carousel-control::after {
		content: "";
		display: block;
		width: 0.95rem;
		height: 0.95rem;
		background-color: currentColor;
		-webkit-mask: var(--fromag-chevron) no-repeat center / contain;
		mask: var(--fromag-chevron) no-repeat center / contain;
	}

	/* One drawing, mirrored. */
	.fromag-hero .vc_images_carousel .vc_right::after {
		transform: scaleX(-1);
	}
}

:root {
	--fromag-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10.5 2.5 4.5 8l6 5.5'/%3E%3C/svg%3E");
}

@media (max-width: 700px) {
	.fromag-hero .vc_images_carousel .vc_carousel-control { width: 2.4rem; height: 2.4rem; }
	.fromag-hero .vc_images_carousel .vc_carousel-control.vc_left  { left: 0.75rem; }
	.fromag-hero .vc_images_carousel .vc_carousel-control.vc_right { right: 0.75rem; }
	.fromag-hero .vc_images_carousel .vc_carousel-control span { font-size: 1.5rem; }
}

/* MOBILE LOGO GIVES WAY TO THE ICONS, 2026-09-23. Kyle's Pixel 4 reports about
 * 352px wide (Android's Display size turned up), and at that width the fixed
 * 203px logo ran 22px under the search icon, which is absolutely positioned
 * at the right. Overlap began below 380px and reached 54px at 320px, the
 * width WCAG 1.4.10 (Reflow) requires to work.
 *
 * The cap is the header's own arithmetic: 100vw, less the 30px gutter on each
 * side (60), the hamburger and its gap (38), the icon group (77), and 12px of
 * air before the icons = 100vw - 187px. At 400px and up the cap exceeds the
 * logo's natural width, so nothing changes there. */
@media (max-width: 400px) {
	body #masthead .site-branding img {
		max-width: calc(100vw - 187px);
		height: auto;
	}
}

/* ============================================================
 * HERO ACTIONS AS A BAND, 2026-09-23, Bekee's call: the four hero
 * actions as a band of links under the hero instead of buttons on
 * every slide. Takes the height out of the slide (Kyle's phone
 * cropped the headline) and frees each slide to carry its own link,
 * which WO section 2b promises. A slide link and buttons on the
 * same slide would nest links, so it is one or the other. The
 * pre-change page and stylesheet are in
 * backups/four-columns-mockup-2026-09-23/.
 * ============================================================ */
.fromag-paths .wpb_content_element,
.fromag-paths .wpb_text_column { margin-bottom: 0; }
.fromag-paths { background: #d3c3ab; }
.fromag-paths__list {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	margin: 0 auto;
	padding: 0;
	max-width: 1400px;
	list-style: none;
}
.fromag-paths__list li { margin: 0; border-left: 1px solid rgba(43, 38, 32, 0.25); }
.fromag-paths__list li:first-child { border-left: 0; }
body .fromag-paths__list a {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 5.5rem;
	padding: 1rem;
	color: #2b2620;
	font-size: 0.9375rem;
	letter-spacing: 0.06em;
	text-align: center;
	text-transform: uppercase;
	text-decoration: none;
	transition: background 0.2s ease, color 0.2s ease;
}
body .fromag-paths__list a:hover,
body .fromag-paths__list a:focus-visible {
	background: #2b2620;
	color: #fffdf9;
}
body .fromag-paths__list a:focus-visible { outline: 2px solid #fffdf9; outline-offset: -4px; }
@media (max-width: 700px) {
	.fromag-paths__list { grid-template-columns: repeat(2, 1fr); }
	.fromag-paths__list li:nth-child(odd) { border-left: 0; }
	.fromag-paths__list li:nth-child(n+3) { border-top: 1px solid rgba(43, 38, 32, 0.25); }
	body .fromag-paths__list a { min-height: 4.25rem; font-size: 0.8125rem; }
}

/* Product page: the size dropdown had no border and no background, so it could
 * not be seen (Bekee, 2026-09-26; production too). The dropdown and the quantity
 * box share one 1px gray edge. The quantity box's border goes on its wrapper, so
 * minus, number, and plus read as one control, replacing Mr. Tailor's 2px navy;
 * the number input itself has none. #8a7f73 on white is 3.92:1, over the 3:1 a
 * control's edge needs (WCAG 1.4.11). */
body.single-product form.cart table.variations select,
body.single-product form.cart .quantity {
	border: 1px solid #8a7f73 !important;
	border-radius: 3px;
	background-color: #fff;
}
body.single-product form.cart .quantity input.qty {
	border: 0 !important;
}
