/* ============================================================================
   gryphon-replica — layout.css : header, nav, footer.
   Every value is from RECON-DESIGN.md §4 / §8, measured at 1440 against the
   source. Where a number is here, it was read off a probe or a tile.
   ========================================================================= */

/* ---------------------------------------------------------------- header */
/* Measured: #shopify-section-header rect h:165, position STATIC — it does not stick. */
.gr-header { position: static; background: #fff; }

/* Row 1 — announcement bar.
   ⚠ MEASURED, and it corrects a wrong reading. RECON-DESIGN §4.1b described this strip as
   "dark/brown" from looking at the tile; the source's own inline CSS says otherwise:
       .notification-bar          { background-color: #454545 }
       .notification-bar__message { color: #ffffff; font-size: 17px }
   #454545 is the FOOTER grey (--color-bg-footer), not the nav brown. The style diff caught it.
   The bar itself sets no colour — it inherits body grey, and the link supplies white. */
.gr-announce {
	background: var(--color-bg-footer);
	text-align: center;
	/* MEASURED on the live source: .notification-bar__message is 17px / 24.2857px with
	   padding 10px 22px, giving a bar of 44px at 1440, 69px at 1024 and 84px at 390.
	   Ours was `line-height:1.4; padding:8px 0`, i.e. 40 / 64 / 106 — short on desktop and
	   22px too tall on a phone, on every page of the site. */
	font-size: 1.7rem;
	line-height: 24.2857px;
	padding: 10px 22px;
}
.gr-announce a { color: #fff; font-size: 17px; }
.gr-announce a:hover { color: var(--color-header-darken-15); }
/* The bar's own box is 17px / 24.2857px at every width, but its INNER link steps down on a phone:
   measured 15px / 21.4286px at 390, filling 3 lines in a 346px span -> 64 + 20 padding = the
   source's 84px bar. (An earlier revision of this file removed the step-down after measuring the
   WRAPPER, which still reports 17px because the wrapper is not what holds the text.) */
@media (max-width: 767px) {
	.gr-header .gr-announce { line-height: 21.4286px; }
	.gr-header .gr-announce a { font-size: 15px; line-height: 21.4286px; }
}
.gr-announce strong { font-weight: var(--font-weight-bolder); }

/* Row 2 — the dark utility row (the source's `.nav-standard-top-area`).
   MEASURED on the live source, and this was wrong from the first build:
     .notification-bar         rgb(69, 69, 69)   h 44   <- ours already matched
     .nav-standard             rgb(51, 51, 51)   h 121  <- ours was #fff at h 74
     .nav-standard-nav-area    rgb(99, 88, 76)   h 54   <- ours 49
   A comment in header.php called this the "white utility row". It is near-black, and everything
   in it is light-on-dark.

   ⚠ AND THE 121 WAS READ OFF THE WRONG BOX, which is worth recording because the two sides looked
   like a 5px miss for weeks. The source's 121 is `.nav-standard`, which CONTAINS BOTH the 67px top
   area AND the 54px brown nav bar. `min-height:121px` here applied all 121 to the top area alone
   and left the 54px bar below it: a 224px header against the source's 165. One matching number is
   not a matching structure. The row is 67. */
.gr-utility { background: rgb(51, 51, 51); color: #fff; }
/* The source's header is FULL-BLEED, not inside the 1200px container: the crest sits at x=20 and
   the search box runs 696px wide from x=372 (i.e. it starts where the crest ends). Ours was
   centred in the container, which pushed the crest to x=135 and squeezed the search to 476. */
.gr-utility > .gr-container { max-width: none; padding: 0 20px; }
.gr-utility-inner {
	display: flex;
	align-items: center;
	/* measured: 352 (logo) + 696 (search) + 352 (actions) = 1400 EXACTLY. There is no gap; the
	   24px that used to be here is what pushed the search from x=372 to x=399. */
	gap: 0;
	/* HEIGHT, not min-height: the 143px crest has to overflow this row, not grow it. */
	height: 67px;
	/* the containing block for the phone search panel */
	position: relative;
}

/* ⚠ The desktop logo is a ROUND CREST BADGE, not a rectangular wordmark, and it OVERHANGS
   downward past the brown nav bar below — 76px over the bar and 22px past the whole header.
   That overhang is why .gr-navbar cannot own a stacking context that clips it, and why the nav
   list below is pushed 350px in.
   MEASURED: the anchor is 352 x 143 at x=20 and the IMAGE inside it is 293 x 143, centred.
   352 is the width of the SLOT; 293 is the width of the picture. `width:352px` on the <img>
   stretched it to 352 x 172 — that, not a missing 17px, was the "352x143 vs 352x126" delta
   (126 being the div's box once a -46px margin had eaten into it). */
.gr-logo {
	flex: 0 0 352px;
	align-self: flex-start;        /* measured y=44 = the row's top edge, NOT centred */
	text-align: center;
	position: relative;
	z-index: 3;
}
.gr-logo .logo-h1-wrapper { margin: 0; font-size: 0; line-height: 0; }
.gr-logo a { display: block; }
.gr-logo-badge { display: inline-block; width: 293px; height: 143px; margin: 0; }
.gr-logo-wordmark { display: none; }   /* phone only — see the <= 991 block */

/* MEASURED: form 696x43 at x=372 (1440) and 280x43 at x=372 (1024) — it absorbs whatever the two
   352px slots leave, capped at 696. The white FIELD inside it is at most 480 and centred (the
   source reports `margin: 0 108px` at 1440 and 0 at 1024, i.e. auto margins), radius 3px, 16px
   type, grey; and the magnifier is ABSOLUTE at the field's right edge, 35x30.
   Ours was a 696px #ddd PILL with the button inline — wrong width, wrong shape, wrong radius,
   wrong button position, and 40px tall instead of 43. */
.gr-search {
	flex: 1 1 auto;
	min-width: 0;
	max-width: 696px;
	display: block;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	background: transparent;
}
.gr-search-inner { position: relative; max-width: 480px; margin: 0 auto; }
.gr-search input[type="search"] {
	display: block;
	width: 100%;
	border: 0;
	border-radius: 3px;
	background: #fff;
	padding: 10px;
	font-family: var(--font-family);
	font-size: 16px;
	line-height: 22.8571px;        /* 22.8571 + 20 padding = the measured 42.86 */
	color: rgb(102, 101, 101);
	outline: none;
}
.gr-search button {
	position: absolute;
	top: 6px;                      /* measured margin-top 6.42 inside a 43px field */
	right: 0;
	width: 35px;
	height: 30px;
	padding: 0 7px;
	border: 0;
	background: transparent;
	color: rgb(102, 101, 101);
	font-size: 19px;
	line-height: 30px;
	cursor: pointer;
}

/* MEASURED 352 x 32, with the items LEFT-aligned 20px in from the slot edge and 20px apart
   (first li x=1088 inside a box starting at 1068), type Montserrat 400 16px/30px white.
   `min-width` rather than `flex-basis`: the slot is 352 at both 1440 and 1024, but a longer menu
   should grow it and squeeze the search rather than escape past the viewport edge. */
.gr-utility-nav {
	flex: 0 0 auto;
	min-width: 352px;
	display: flex;
	align-items: center;
	justify-content: flex-start;
	gap: 20px;
	padding-left: 20px;
	margin-left: 0;
}
.gr-utility-list {
	display: flex; align-items: center; gap: 20px;
	list-style: none; margin: 0; padding: 0;
}
.gr-utility-list a {
	color: #fff;
	font-size: 16px;
	/* measured 400, not 600. At 600 the three links are wide enough to need a smaller size to fit
	   the 352px slot, which is how the 13px override at 1024 came about. */
	font-weight: 400;
	line-height: 30px;
}
.gr-utility-list a:hover { color: var(--color-primary-lighten-20, #eda07a); }

/* measured 30 x 30, glyph 16px/30px simple-line-icons, white. Ours were 20px (the PHONE size). */
.gr-icon-link {
	position: relative;
	color: var(--color-heading);
	width: 30px;
	height: 30px;
	font-size: 16px;
	line-height: 30px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
}
.gr-icon-link:hover { color: var(--color-primary); }
.gr-cart-count {
	position: absolute;
	top: -8px; right: -10px;
	min-width: 18px; height: 18px;
	padding: 0 5px;
	border-radius: 999px;
	background: var(--color-primary);
	color: #fff;
	font-family: var(--font-family);
	font-size: 11px; font-weight: 700;
	line-height: 18px;
	text-align: center;
}

/* Both phone-only controls. Sized in the <= 991 block, hidden here. */
.gr-burger,
.gr-search-toggle { display: none; background: none; border: 0; padding: 0; cursor: pointer; }
.gr-burger span:not(.screen-reader-text) {
	display: block; width: 22px; height: 2px; margin: 4px 0;
	background: var(--color-heading);
}

/* Row 3 — brown nav bar */
.gr-navbar { background: var(--color-bg-nav); }
/* Full-bleed like the row above it: measured `.nav-standard-nav-area` 1440x54 with padding 0 20px.
   Inside the 1200px container the list started at x=285, which put the first two nav items UNDER
   the overhanging crest. */
.gr-navbar > .gr-container { max-width: none; padding: 0 20px; }
.gr-nav {
	display: flex;
	list-style: none;
	margin: 0;
	/* MEASURED, not estimated: the source's `ul.navbar-standard` carries `margin-left: 350px` and
	   its first item sits at x=370 at BOTH 1440 and 1024. The old 150px was sized for the 120px
	   crest this file used to render; with the crest at its real 293px width the first two items
	   would sit underneath it. */
	padding: 0 0 0 350px;
	gap: 28px;
}
.gr-nav-link {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 13px 0;
	color: var(--color-header);
	font-family: var(--font-family);
	font-size: var(--font-size-nav-header);
	font-weight: var(--font-weight-nav);
	text-transform: var(--text-transform-nav);
	letter-spacing: .02em;
	white-space: nowrap;
}
.gr-nav-link:hover { color: var(--color-header-darken-15); }
.gr-caret {
	width: 0; height: 0;
	border-left: 4px solid transparent;
	border-right: 4px solid transparent;
	border-top: 4px solid currentColor;
}

/* mega panel */
.gr-nav-item { position: relative; }
.gr-mega {
	display: none;
	position: absolute;
	top: 100%; left: 0;
	z-index: 50;
	min-width: 640px;
	padding: 24px 28px;
	margin: 0;
	list-style: none;
	background: var(--color-bg-nav-darken-10);
	box-shadow: 0 10px 24px rgba(0, 0, 0, .18);
	columns: 3;
	column-gap: 28px;
}
.gr-nav-item.gr-has-children:hover > .gr-mega,
.gr-nav-item.gr-has-children:focus-within > .gr-mega,
.gr-nav-item.gr-has-children.is-open > .gr-mega { display: block; }

.gr-mega-col { break-inside: avoid; margin: 0 0 18px; }
.gr-mega-head {
	display: block;
	color: #fff;
	font-weight: 700;
	font-size: 14px;
	text-transform: uppercase;
	letter-spacing: .03em;
	margin-bottom: 6px;
}
.gr-mega-col-list { list-style: none; margin: 0; padding: 0; }
.gr-mega-col-list a {
	display: block;
	padding: 3px 0;
	color: rgba(255, 255, 255, .82);
	font-size: 14px;
}
.gr-mega-col-list a:hover { color: #fff; }

/* ---------------------------------------------------------------- footer */
/* Measured: 504px tall at 1440; four 300px columns with padding 0 30px. */
.gr-footer {
	background: var(--color-bg-footer);
	color: var(--color-footer);
	font-size: 15px;              /* measured on footer.footer-main-standard, the node that
	                                 actually paints. The section WRAPPER reports 16px and
	                                 rgba(0,0,0,0) — comparing it produced four phantom diffs. */
}
/* MEASURED: the footer's columns start exactly 50px below the footer's top edge, and the column
   type is 14.5px / 20.7143px — not the 15px / 21.4286px inherited from the body. */
.gr-footer-cols { padding: 50px 0 0; }
.gr-footer .footer-col {
	padding: 0 30px;
	font-size: 14.5px;
	line-height: 20.7143px;
}
.gr-footer h4 {
	color: var(--color-footer-heading);
	font-family: var(--font-family-header);
	font-weight: var(--font-weight-header);
	font-size: 20px;              /* measured on the source, not the token */
	margin: 0 0 14px;
}
.gr-footer p { margin: 0 0 14px; line-height: 1.6; color: var(--color-footer); }
.gr-footer-list { list-style: none; margin: 0; padding: 0; }
.gr-footer-list li { margin: 0 0 7px; }
.gr-footer-list a { color: var(--color-footer-link); font-size: 15px; }
.gr-footer-list a:hover { color: var(--color-footer-link-darken-15); }

/* MEASURED on the live source (scrape/probes/measured-home.json):
     form            240 x 162,  margin 15px 0 20px
     first/last name 118 x 51 side by side        (178 x 51 at 390, 93 x 51 at 1024)
     email           240 x 51 on its own row
     JOIN            a THIRD full-width row, not inline with the email
     inputs          font-size 16px, padding 13px 26px
   Ours was an 80px two-row form with 13px type and the button inline, which left footer column 4
   at 260px against the source's 359 — and the footer short on every page. */
.gr-newsletter {
	display: flex;
	flex-direction: column;
	gap: 5px;
	margin: 15px 0 20px;
}
.gr-nl-names { display: flex; gap: 4px; }
.gr-nl-email { display: block; }
.gr-newsletter input {
	flex: 1 1 auto;
	min-width: 0;
	width: 100%;
	box-sizing: border-box;
	border: 0;
	padding: 13px 26px;
	font-family: var(--font-family);
	font-size: 16px;
	line-height: 22.8571px;
}
.gr-newsletter button {
	display: block;
	width: 100%;
	border: 0;
	padding: 13px 26px;
	background: var(--color-primary);
	color: var(--color-btn);
	font-family: var(--font-family);
	font-weight: 700;
	font-size: 14px;
	letter-spacing: .04em;
	cursor: pointer;
}
.gr-newsletter button:hover { background: var(--color-primary-darken-10); }

/* MEASURED: the row is 200x46 and each link 33x33, identically at 1440, 1024 and 390. */
.gr-social {
	display: flex;
	gap: 8px;
	list-style: none;
	margin: 0;
	padding: 0;
	width: 200px;
	height: 46px;
	align-items: center;
}
.gr-social li { line-height: 0; }
.gr-social a {
	display: block;
	width: 33px;
	height: 33px;
	color: var(--color-footer-link);
}
.gr-social a svg {
	width: 33px;
	height: 33px;
	display: block;
	fill: currentColor;
}
.gr-social a:hover { color: #fff; }

.gr-footer-bottom {
	background: var(--color-bg-footer-darken-10);
	color: var(--color-footer-link);
	font-size: 12px;
}
/* MEASURED: 504 (footer) - 50 (top padding) - 359 (tallest column) = a 95px bottom bar. */
.gr-footer-bottom { min-height: 95px; display: flex; align-items: center; }
.gr-footer-bottom .gr-row { padding: 5px 0; align-items: center; width: 100%; }
.gr-footer-bottom a { color: var(--color-footer-link); text-decoration: underline; }
.gr-credit { text-align: right; }

/* ---------------------------------------------------------------- main */
.gr-main { padding: 28px 0 56px; }

/* ============================================================================
   RESPONSIVE
   ⚠ Media queries add NO specificity. A base rule of `.gr-navbar .gr-nav` (0,2,0)
   beats `@media (…) { .gr-nav { … } }` (0,1,0) — which is exactly how a prior
   build shipped five columns at 390px with 50px cards. Repeat the full selector
   inside every breakpoint.
   ========================================================================= */
/* ============================================================================
   THE PHONE HEADER IS A DIFFERENT COMPONENT, NOT A SMALLER DESKTOP ONE.
   The source ships two separate <nav>s and swaps them; it does not reflow one. MEASURED at 390:

     .nav-container .new_mobile_header   390 x 60 at y=84, bg rgb(99,88,76) BROWN
                                         flex / align-items:center / padding 5px 0 / NO side padding
     hamburger  button 35x30 at x=6    padding 0 5px, margin 0 6px
     magnifier  a      30x30 at x=53   20px/30px simple-line-icons, white
     WORDMARK   h1    140x50 at x=128  margin 0 auto, anchor padding 10px, img 120x30
     account    a      30x30 at x=312
     cart       a      30x30 at x=354

   Two structural facts the old "shrink the desktop row" version got wrong, neither of them a
   height: the bar is BROWN, not the desktop row's rgb(51,51,51); and the round crest is not used
   on a phone AT ALL — it is replaced by the GRYPHON wordmark, centred. Ours rendered an 84px
   crest at the far left, the three utility links' icons at x=118, the hamburger at x=190 and a
   128px-wide inline search field crushed against the right edge.
   ========================================================================= */
@media (max-width: 991px) {
	.gr-header .gr-utility { background: var(--color-bg-nav); }
	.gr-header .gr-utility > .gr-container { padding: 0; }
	.gr-header .gr-utility-inner {
		height: 60px;
		min-height: 60px;
		padding: 5px 0;
		gap: 0;
		align-items: center;
	}

	/* The 6px margins on every action are what produce the measured 6 / 53 / 312 / 354. */
	.gr-header .gr-burger {
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
		gap: 4px;
		flex: 0 0 auto;
		width: 35px;
		height: 30px;
		padding: 0 5px;
		margin: 0 6px;
	}
	.gr-header .gr-burger span:not(.screen-reader-text) {
		display: block;
		width: 22px;
		height: 2px;
		margin: 0;
		background: #fff;              /* light-on-brown, like every other glyph in this bar */
	}

	.gr-header .gr-search-toggle {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		flex: 0 0 auto;
		width: 30px;
		height: 30px;
		margin: 0 6px;
		color: #fff;
		font-size: 20px;               /* the phone glyphs are 20px; the desktop ones are 16px */
		line-height: 30px;
	}
	.gr-header .gr-search-toggle:hover { color: var(--color-primary-lighten-20, #eda07a); }

	/* Centred by AUTO MARGINS, which is what the source does: its h1 reports `margin: 0 38.5px`
	   at 390, and 38.5 is not a hand-set number — it is `0 auto` resolved against the space the
	   two icons on each side leave over. */
	.gr-header .gr-logo {
		flex: 0 0 auto;
		align-self: center;
		margin: 0 auto;
		text-align: center;
	}
	.gr-header .gr-logo a { padding: 10px; }       /* gives the measured 140x50 h1 */
	.gr-header .gr-logo-badge { display: none; }
	.gr-header .gr-logo-wordmark { display: block; width: 120px; height: 30px; }

	.gr-header .gr-utility-nav {
		flex: 0 0 auto;
		min-width: 0;
		/* `margin-left:auto` HAS to go: with it the nav eats all the free space and the logo's own
		   auto margins get none, so the wordmark sits hard against the magnifier instead of in
		   the middle of the bar. */
		margin-left: 0;
		gap: 0;
		padding-left: 0;
	}
	.gr-header .gr-utility-list { display: none; }
	.gr-header .gr-utility .gr-icon-link { margin: 0 6px; font-size: 20px; }
	/* The cart glyph now ends 6px from the viewport edge, so the bubble's `right:-10px` would put
	   its right edge at 394 on a 390 viewport — a real horizontal overflow, and one
	   find-overflow.py reports. */
	.gr-header .gr-cart-count { top: -2px; right: -4px; }

	/* The search field leaves the flex flow and becomes the panel the magnifier opens, which is
	   what leaves the bar with exactly the source's five items. (The source opens a modal dialog;
	   this is the same affordance with one component fewer.)
	   `.js` gates the hiding — the same idiom as the staged checkout — so with JS off the field
	   renders inline, open, and still submits. */
	.gr-header .gr-search {
		position: absolute;
		top: 100%;
		left: 0;
		right: 0;
		z-index: 40;
		max-width: none;
		margin: 0;
		padding: 8px 12px;
		background: var(--color-bg-nav);
	}
	.gr-header .gr-search-inner { max-width: none; }
	.js .gr-header .gr-search { display: none; }
	.js .gr-header .gr-search.is-open { display: block; }

	.gr-navbar { display: none; }
	.gr-navbar.is-open { display: block; }
	.gr-navbar .gr-nav { flex-direction: column; gap: 0; padding: 8px 0; }
	.gr-navbar .gr-nav-link { padding: 11px 0; width: 100%; justify-content: space-between; }

	.gr-navbar .gr-mega {
		position: static;
		min-width: 0;
		columns: 1;
		box-shadow: none;
		padding: 4px 0 10px 14px;
		background: transparent;
	}

		.gr-footer .footer-col { padding: 0 15px 30px; }   /* measured at 390 */
	.gr-footer-bottom .gr-credit { text-align: left; }
}

@media (max-width: 767px) {
	/* The crest used to be shrunk to 84px here. It is not shown on a phone at all — the <= 991
	   block swaps it for the wordmark — so there is nothing left to resize. */
		.gr-footer .gr-footer-cols { padding: 50px 0 0; }  /* the 50px top holds at 390 too */
	.gr-footer-bottom .gr-col-6 { text-align: left; }
}

/* ============================================================================
   SHARED PRODUCT CARD — sitewide on purpose.
   This card renders on the shop grid, the homepage, the PDP related row AND in
   cart cross-sells. /cart/ loads layout.css but not a shop-only stylesheet, so
   putting these rules in shop.css would silently repaint the card as Woo's
   default on exactly the pages where it matters most.

   Measured (RECON-DESIGN §5): title Montserrat 700 14px/19.88px rgb(61,66,70);
   price Montserrat 400 14px/20px rgb(34,34,34); no border, no radius, no shadow,
   transparent background, centred.
   ========================================================================= */
.gr-pcard {
	position: relative;
	text-align: center;
	background: rgba(0, 0, 0, 0);
	border: none;
	border-radius: 0;
	box-shadow: none;
	margin: 0 0 30px;
}
.gr-pcard-image { display: block; position: relative; margin-bottom: 12px; }
/* ⚠ THE CARD IMAGE IS PORTRAIT, AND NARROWER THAN THE CARD.
 *
 * Measured on the source, from the probes: the image box is 203 x 304 inside a 300px card at 1440
 * and 129 x 194 inside a 188px card at 390. That is 67.7% of the card's width at both, with a
 * 2:3 ratio — these are instrument photographs, and they are tall.
 *
 * What was here instead was `width:100%; height:var(--height-product-image)`, and the token really
 * does say 230px — it is in the source's own :root. It is simply not the value that applies to this
 * element. Reading the variable instead of the computed box made every card 308px tall against the
 * source's 392, which is 84px x 10 rows = 840px on every archive at 1440, and 405px on the PDP's
 * related row. Exactly the error class VISUAL-FIDELITY.md exists for, and the second time this
 * build has made it with a --height/--color token.
 */
.gr-pcard-image img {
	display: block;
	width: 67.7%;
	margin: 0 auto;
	aspect-ratio: 203 / 304;
	height: auto;
	object-fit: contain;
}
/* ⚠ …AND THAT IS THE ARCHIVE CARD ONLY. The source has TWO product cards, not one, and the rule
 * above is right for exactly one of them:
 *
 *   archive (/collections/…)  `.boost-pfs-filter-product-item-image`   — Boost PFS's own card,
 *                             image 203x304 portrait inside a 300px card at 1440.
 *   homepage + PDP related    `.collection-row.use_align_height .product-thumb-img-wrap` — the
 *                             THEME's card, image the FULL card width and much shorter.
 *
 * Measured on /products/wegen-tf-picks with the lazyload images forced to load (the first probe
 * read the wrap as 262x100 and the <img> as 262x0 — both artifacts: the related row is injected by
 * AJAX from /recommendations/products AFTER the scroll pass, so lazysizes never saw the images, and
 * a height of 0 is not a measurement). The real numbers, and the source CSS that produces them:
 *
 *     .use_align_height .product-thumb-img-wrap      { height:auto; min-height:100px; max-height:230px }
 *     @media <=767 … .product-thumb-img-wrap         { min-height:70px }
 *     .use_align_height .product-thumb-img-wrap img  { max-height:230px; object-fit:contain }
 *
 *   1440  262.5 x 230 for a 153x229 or 230x230 original; 262.5 x 175 for a 262x174 one
 *    390  150   x 225 /  150 x 150 / 150 x 100, i.e. the image's own height, capped
 *
 * So it is NOT a fixed 263x230 box: it is full card width, natural height, clamped to 230. 263x230
 * is what that resolves to whenever the picture is at least as tall as 230 — which is most of them,
 * and why the row reads as a uniform band. Pinning height:230px instead would letterbox every
 * landscape accessory shot that the source renders at 175.
 *
 * The homepage "Featured Products" row is the same source component; it is overridden in home.css
 * under `.gr-featured`, which is a different context from `.related`, so the two cannot collide. */
.related.products .gr-pcard-image img {
	width: 100%;
	aspect-ratio: auto;
	height: auto;
	max-height: 230px;
	object-fit: contain;
}
.related.products .gr-pcard-image { min-height: 100px; }
@media (max-width: 767px) {
	.related.products .gr-pcard-image { min-height: 70px; }
}
/* .gr-pcard-label removed — the source's label slot is empty on every card. */
.gr-pcard-title {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	font-family: var(--font-family);
	font-size: 14px;
	font-weight: 700;
	line-height: 19.88px;
	color: rgb(61, 66, 70);
	text-align: center;
}
.gr-pcard-title:hover { color: var(--color-primary); }
.gr-pcard-price {
	margin: 6px 0 0;
	font-family: var(--font-family);
	font-size: 14px;
	font-weight: 400;
	line-height: 20px;
	color: rgb(34, 34, 34);
	text-align: center;
}
.gr-pcard-price del { opacity: .6; margin-right: 6px; }
.gr-pcard-price ins { text-decoration: none; }

/* ---- Woo chrome resets ----
   LAW (STANDARDS): treat every piece of stock WooCommerce UI as a DEFECT until proven to match
   the source. Woo's `.woocommerce:where(body:not(...)) a.button` computes at (0,2,1) — :where()
   contributes nothing — and beats a plain class override, repainting CTAs as Woo's grey/purple
   pill on every page whose body carries `woocommerce`. Match its specificity; do not reach for
   !important. */
.woocommerce ul.products::before,
.woocommerce ul.products::after { content: none; }

.woocommerce ul.products {
	display: grid;
	grid-template-columns: repeat(3, 1fr);   /* source archive is 3-up desktop, 2-up mobile */
	gap: 30px;
	margin: 0;
	padding: 0;
	list-style: none;
}
.woocommerce ul.products li.product {
	width: auto;
	margin: 0;
	float: none;
	clear: none;
}
@media (max-width: 767px) {
	.woocommerce ul.products { grid-template-columns: repeat(2, 1fr); }
}

/* ---- 992–1199: the nav bar overflows before the mobile breakpoint ----
   Measured with tools/find-overflow.py, not estimated: at 1024 the last nav item
   (THE WORKSHOP, 145px) pushed the row 39px past the viewport, because the 150px
   left padding that clears the overhanging crest badge is desktop-sized. Shrink the
   badge clearance and the gap here rather than letting the row wrap, which would
   change the nav's height and break the measured 165px header block.
   Full selectors repeated — media queries add no specificity. */
@media (max-width: 1199px) and (min-width: 992px) {
	/* Only the nav TYPE is touched now. The logo keeps its measured 352/293x143 (the source does
	   not shrink it at 1024 either) and the 350px clearance is unchanged, so the five items have
	   634px to fit in — which is exactly the span the source gives them at 1024.
	   The search needs no override any more: `flex: 1 1 auto` between two 352px slots resolves to
	   280px at 1024 on its own, which is the source's measured width. The 320px max-width that
	   used to be here was a guess at the same thing.
	   The utility links needed 13px only because they were 600 weight; at the measured 400 the
	   three of them plus two icons come to ~346 and fit the 352px slot at 16px. */
	/* ⚠ The TYPE has to carry the whole adjustment, and find-overflow.py decided the number, not
	   an estimate: at 14px/16px gap the five items needed 1090px of a 1004px row and every page
	   overflowed by 86px at 1024. The source solves the same squeeze by making this type
	   `0.85vw` — a measured 8.704px at 1024, which is unreadable and not worth copying; 12px with
	   a 10px gap fits the 634px the source's own nav list occupies there, with the crest and the
	   350px clearance both left at their measured desktop values. */
	.gr-navbar .gr-nav { gap: 10px; }
	.gr-navbar .gr-nav-link { font-size: 12px; letter-spacing: 0; }
}


/* ---------------------------------------------------------------- breadcrumb
   ⚠ SITEWIDE on purpose. The breadcrumb renders on BOTH the archive and the PDP
   (body carries show_breadcrumbs at source — it is a theme setting that is ON),
   but shop.css is only enqueued on shop/taxonomy/search. With these rules in
   shop.css the PDP's separators had no width and no margin, so the trail rendered
   as "HomeInstrumentsAcoustic GuitarsFlat Top Acoustic" — present in the DOM,
   invisible on the page. Exactly the same mistake as putting the product card in
   a shop-only stylesheet. */
.gr-breadcrumb {
	font-size: 14px;
	color: var(--color-body);
	margin: 0 0 6px;
}
.gr-breadcrumb a { color: var(--color-body); }
.gr-breadcrumb a:hover { color: var(--color-primary); }
.gr-crumb-sep {
	display: inline-block;
	width: 0; height: 0;
	margin: 0 8px;
	border-top: 3px solid transparent;
	border-bottom: 3px solid transparent;
	border-left: 4px solid currentColor;
	vertical-align: middle;
	opacity: .6;
}


/* ---------------------------------------------------------------- buttons
   ⚠ SITEWIDE. .gr-btn is the shared primary button: homepage bands, the checkout
   step actions, content pages. It lived in home.css, which is enqueued ONLY on the
   front page — so "Continue to shipping" rendered as a bare browser button on the
   one page where a broken CTA costs an order.

   This is the THIRD time this exact mistake has been made in this build: the shared
   product card (caught before shipping), the breadcrumb separator (shipped, then
   fixed), and this. Rule of thumb: if a class is used by more than one template,
   it does not belong in a page-scoped stylesheet. */
.gr-btn {
	display: inline-block;
	padding: 11px 26px;
	background: var(--color-primary);
	color: var(--color-btn);
	font-family: var(--font-family);
	font-size: 14px;
	font-weight: 700;
	letter-spacing: .03em;
	border: 0;
	border-radius: 45px;
	text-align: center;
	cursor: pointer;
}
.gr-btn:hover { background: var(--color-primary-darken-10); color: var(--color-btn); }

/* ---- footer newsletter ----
   ⚠ A SECOND set of rules for this component used to live here, 265 lines below the first, and
   the last one wins: `.gr-newsletter { display:block }` quietly undid the flex column measured
   from the source, and `.gr-nl-email { display:flex }` put JOIN back on the email row. The form
   came out 106px instead of 162. One component, one block of rules — the same mistake as scoping
   the shared product card and .gr-btn to a page stylesheet. The real rules are above. */
.gr-nl-names input { flex: 1 1 0; min-width: 0; }

/* ---- accepted payment methods ----
   A PARTIAL reproduction on purpose: the source shows nine card/wallet marks, this store takes
   manual payment only, and advertising a method the checkout cannot process is worse than showing
   fewer. See the note in footer.php. */
.gr-payments {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	padding: 10px 0 0;
	justify-content: flex-end;
}
.gr-pay-mark {
	display: inline-block;
	padding: 3px 9px;
	border: 1px solid rgba(255, 255, 255, .28);
	border-radius: 3px;
	font-family: var(--font-family);
	font-size: 10px;
	font-weight: 700;
	letter-spacing: .05em;
	text-transform: uppercase;
	color: var(--color-footer-link);
}
@media (max-width: 767px) {
	.gr-footer-bottom .gr-payments { justify-content: flex-start; }
	.gr-footer .gr-nl-names { flex-direction: column; }
}

/* =========================================================================
   MOBILE HEADER HEIGHT — measured, not estimated.
   Source at 390: .notification-bar 84px + .nav-container 60px = a 144px header.
   Ours was 106 + 74 = 180, so every mobile page started 36px lower than the
   source's. The announcement bar is fixed above (17px type, 10px/22px padding);
   this pins the utility row to the source's 60.

   ⚠ The two rules that used to be here are GONE, and deliberately: `padding-top:0;
   padding-bottom:0` on .gr-utility-inner sat LATER in the file than the phone-header block above
   and so, at equal specificity, silently undid its measured `padding: 5px 0`. The 60px row and
   its 5px padding are both set once, in the <= 991 block, where the rest of the phone bar lives.
   (Media queries add no specificity — the ordering is all there is.)
   ========================================================================= */


/* The account and cart glyphs sit in the dark utility bar, so they are light-on-dark like
   everything else in it. */
.gr-utility .gr-icon-link,
.gr-utility .gr-icon-link:visited { color: #fff; }
.gr-utility .gr-icon-link:hover { color: var(--color-primary-lighten-20, #eda07a); }

/* The brown nav bar measures 54px at source; ours was 49. */
.gr-navbar { min-height: 54px; }


/* Payment marks as official brand LOGOS rather than text labels.
   The SVG inherits `color` from its wrapper, which carries each brand's published colour, so one
   rule styles all four and a new method only needs its file and hex. */
.gr-pay-mark--logo {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 52px;
	height: 32px;
	padding: 0 8px;
	background: #fff;
	border: 1px solid rgba(0,0,0,.12);
	border-radius: 4px;
}
.gr-pay-mark--logo svg {
	width: 100%;
	height: 18px;
	display: block;
	fill: currentColor;
}


/* An empty basket shows no bubble, as the source does (it ships the element with a `hidden` class
   rather than omitting it, so its AJAX fragment still has a target to replace - ours does the same
   with .is-zero). Hiding by class, never by removing the element: the fragment key is the selector
   `span.gr-cart-count`, and a missing target makes the count stop updating after an add-to-cart. */
.gr-cart-count.is-zero { display: none; }
