/*
 * WordPress/WooCommerce integration fixes ONLY — source.css stays untouched.
 * Each rule here should say why it exists.
 */

/* WooCommerce's own accessibility class (quantity label, etc.) — source.css
   has no rule for it (it's a WP/Woo convention, not a Shopify one), and
   WC's default stylesheet that would normally hide it is dequeued. */
.screen-reader-text {
	clip: rect(0 0 0 0);
	border: 0;
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
}

/* Age gate: net-new (the source's gate is a third-party app whose markup never
   rendered in our harvest, since we bypass it to capture real pages — see
   inc/age-gate.php). Own namespace, not styled by source.css. */
.tbt-age-gate {
	position: fixed;
	inset: 0;
	z-index: 9999;
	display: flex;
	align-items: center;
	justify-content: center;
	background: #0f1a14;
	padding: 24px;
}
.tbt-age-gate__panel {
	max-width: 420px;
	width: 100%;
	text-align: center;
	background: #fff;
	border-radius: 8px;
	padding: 40px 32px;
}
.tbt-age-gate__wordmark {
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	margin: 0 0 16px;
}
.tbt-age-gate__title {
	margin: 0 0 12px;
	font-size: 22px;
}
.tbt-age-gate__sub {
	margin: 0 0 24px;
	color: #555;
	font-size: 14px;
}
.tbt-age-gate__btns {
	display: flex;
	gap: 12px;
	justify-content: center;
}
.tbt-age-gate__btn {
	flex: 1;
	padding: 12px 0;
	border-radius: 4px;
	font-weight: 600;
	text-decoration: none;
	letter-spacing: 0.05em;
}
.tbt-age-gate__btn--yes {
	background: #0f1a14;
	color: #fff;
}
.tbt-age-gate__btn--no {
	background: #eee;
	color: #333;
}
/* While the gate is up, stop background scroll/interaction underneath it. */
body:has(> .tbt-age-gate) {
	overflow: hidden;
}

/* Mega menu: the source's dropdown show/hide is driven by the "Globo Menu" app's
   OWN JavaScript, which we don't have (it's a Shopify app, not theme code) — only
   its CSS came across in source.css. Without it every .gm-submenu renders
   permanently open and stacks the whole menu down the page. Replace with a plain
   CSS hover/focus reveal; source.css's own gm-* rules still handle the dropdown's
   internal look once it's visible. */
/* Globo Menu's OWN CSS (added after discovering it was missing — see
   inc/assets.php) hides .gm-submenu with `display:none!important` by default,
   normally toggled by the app's JS on click/hover. Beat its !important with
   our own, scoped to :hover/:focus-within so no JS is needed for v1. */
.site-nav.site-navigation .gm-submenu {
	display: none !important;
	position: absolute;
	top: 100%;
	z-index: 100;
}
.site-nav.site-navigation .gm-item {
	position: relative;
}
.site-nav.site-navigation .gm-item:hover > .gm-submenu,
.site-nav.site-navigation .gm-item:focus-within > .gm-submenu {
	display: flex !important;
	flex-wrap: wrap;
	opacity: 1 !important;
	visibility: visible !important;
	pointer-events: auto !important;
}
.site-nav.site-navigation .gm-submenu .gm-grid {
	display: flex !important;
	flex-wrap: wrap;
	width: 100%;
}
.site-nav.site-navigation .gm-submenu .gm-grid-item {
	flex: 1 1 200px;
	min-width: 180px;
}
/* Width/left/right/background for the mega panel are the SOURCE's own rules
   now (source.css's appended Globo theming block: .gm-submenu-align-full >
   .gm-submenu gets left:0;right:0;min-width:100% off its positioning
   ancestor — #SiteHeader .header-layout--center, position:relative, below —
   and .gm-submenu.gm-mega gets the white background). This is only a
   last-resort safety clamp so a dropdown can never push past the viewport
   on a narrow-ish desktop width. Right-edge-aware flip (site.js measures
   overflow on hover/focus and adds this class) still applies on top. */
.site-nav.site-navigation .gm-submenu {
	max-width: calc(100vw - 32px);
}
.site-nav.site-navigation .gm-submenu.gm-submenu--align-right {
	left: auto !important;
	right: 0 !important;
}
.site-nav.site-navigation.tbt-menu {
	display: flex;
	justify-content: center;
	list-style: none;
	margin: 0;
	padding: 0;
}
.site-nav.site-navigation .gm-links {
	list-style: none;
	margin: 0;
	padding: 16px;
}
.site-nav.site-navigation .gm-item > a.gm-target {
	display: inline-block;
	padding: 8px 14px;
	white-space: nowrap;
}

/* Mobile nav drawer accordion — turned out to need NO hand-rolled CSS at
   all. Using the real Globo Menu classes (inc/template-helpers.php) means
   the real, already-shipped source.css drives the chevron icon (its own
   GloboMenuBaseIcon @font-face), the active-row gold highlight, and the
   submenu show/hide entirely — all keyed off one real `.gm-active` class
   that site.js toggles. An earlier pass here hand-rolled a CSS-triangle
   chevron and custom show/hide before this was found; it rendered as a
   broken double-icon on top of the real one and has been removed. */

/* Header: the source's centered-logo layout absolutely-positions the logo over
   a thin icon row, then relies on the logo's own aspect-ratio padding to claim
   height; our simplified markup doesn't replicate that trick, so the logo
   overlaps the mega-menu row beneath it. Give the header explicit room instead. */
#SiteHeader .header-layout--center {
	position: relative;
	min-height: 64px;
	display: flex;
	align-items: center;
	justify-content: space-between;
}
#SiteHeader .header-item--logo {
	position: absolute;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%);
}
#SiteHeader > .page-width > .text-center {
	margin-top: 12px;
	padding-top: 12px;
	border-top: 1px solid #e8e8e1;
}

/* Footer grid: the source gives each column a unique generated class with its
   own inline width (e.g. .footer__item--1494301487049{width:20%}); our semantic
   column classes replace those hashes, so the percentage widths need restating
   here against the stable names instead. */
@media only screen and (min-width: 769px) {
	.site-footer .grid { display: flex; flex-wrap: wrap; }
	.site-footer .footer__item--customer-care { width: 20%; }
	.site-footer .footer__item--newsletter { width: 33%; }
	.site-footer .footer__item--logo-social { width: 15%; }
	.site-footer .footer__item--prop65 { width: 25%; }
}

/* Hero slideshow: source.css's .slideshow__slide{display:none} default is only
   ever overridden by Flickity's OWN JavaScript (a bundled carousel library, not
   theme code) adding .flickity-enabled / positioning each slide via inline
   transforms. Without that JS every slide stays hidden. Behaviour pass 2 will
   wire real Flickity (or an equivalent) for the swipe/dot interaction; for now,
   show the server-selected first slide as a plain static block so the hero
   isn't blank. */
.hero .flickity-viewport,
.hero .flickity-slider {
	position: static;
	height: 100%;
	transform: none !important;
}
.hero .slideshow__slide {
	display: none;
	opacity: 1;
	position: relative;
	height: 100%;
	transform: none !important;
}
.hero .slideshow__slide.is-selected {
	display: block;
}
.hero .hero__image-wrapper,
.hero .hero__image-wrapper .image-element {
	height: 100%;
}
.hero .hero__image {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
/* source.css gives the real .hero__image a real z-index:1 (for a different
   purpose on the real theme's own layered hero content) — on this build,
   where each hero slide is one pre-composited image with no separate real
   text/button layer, that incidentally sits above .hero__slide-link's own
   default z-index:auto, silently blocking clicks on the whole slide
   (confirmed via Playwright: the <img> intercepts the click, not the link).
   Both are already position:absolute from source.css; just needs to win. */
.hero__slide-link {
	z-index: 2;
}
/* Same real underlying cause as .hero__slide-link above, confirmed the same
   way (elementFromPoint at the button's own coordinates returns the image,
   not the button): .hero__image's real z-index:1 ends up winning over the
   "Request a Quote" button's own stacking despite .hero__text-content's
   real z-index:4, because .hero__text-wrap establishes its own stacking
   context (position:absolute + z-index:2) that traps text-content's z-index
   inside it — only text-wrap's OWN z-index:2 competes with the image at the
   outer .hero level, which .hero__image's child z-index:1 escaping its
   non-stacking-context parent still contests unpredictably in practice.
   Target the actual clickable element directly rather than relying on the
   multi-level context chain. */
.tbt-corporate-hero .hero__link .btn {
	position: relative;
	z-index: 5;
}
/* z-index alone didn't resolve it (confirmed via elementFromPoint still
   returning the image after the above) — .hero__text-wrap's own stacking
   context isn't winning against the image for a reason not worth chasing
   further given the practical fix is simple and robust either way: the
   background image has no interactive purpose, so let clicks pass straight
   through it to whatever's positioned on top instead of fighting for
   paint-order priority. */
.tbt-corporate-hero .hero__image-wrapper {
	pointer-events: none;
}
.hero .flickity-page-dots {
	position: relative;
	/* Found in a QA pass: the dots were completely unclickable (confirmed
	   via Playwright — clicks landed on .hero__slide-link instead, same
	   root cause documented above: that link's z-index:2 fix wins against
	   anything after it with no z-index of its own, dots included). */
	z-index: 3;
}
/* The aspect-ratio that gives the hero its height is a per-section hashed class
   in source.css (.hero-natural--template--<id>) we didn't replicate — our
   semantic .hero-natural class matches no rule there, so the container
   collapses to 0 height. Restate the source's own ratios directly (38.89%
   desktop / 50% mobile padding-bottom, read from its own inline <style>). */
.hero-natural {
	height: 0;
	padding-bottom: 38.888889%;
	position: relative;
}
@media screen and (max-width: 768px) {
	.hero-natural {
		padding-bottom: 50%;
	}
}
.hero-natural .hero {
	position: absolute;
	inset: 0;
}
/* Same JS-dependency class of bug, broader: source.css starts every
   data-aos="..." element (hero images, category tiles, etc.) at opacity:0 with
   a scale/translate, revealed by the "AOS" (Animate On Scroll) library on
   scroll-into-view — not present without its JS, so EVERYTHING animated this
   way would otherwise stay invisible. Force the visible end-state globally. */
[data-aos],
.hero__image,
.hero__image-wrapper,
.image-element {
	opacity: 1 !important;
	transform: none !important;
}

/* WooCommerce's star rating widget (product rating summary + review form) —
   its own CSS is dequeued along with the rest of woocommerce_enqueue_styles,
   so this native-font-based star rendering needs restating. */
.star-rating {
	overflow: hidden;
	position: relative;
	height: 1em;
	line-height: 1em;
	width: 5.4em;
	font-family: serif;
}
.star-rating::before {
	content: '\2605\2605\2605\2605\2605';
	float: left;
	top: 0;
	left: 0;
	position: absolute;
	color: #d8d8d8;
}
.star-rating span {
	overflow: hidden;
	float: left;
	top: 0;
	left: 0;
	position: absolute;
	padding-top: 1.5em;
}
.star-rating span::before {
	content: '\2605\2605\2605\2605\2605';
	top: 0;
	position: absolute;
	left: 0;
	color: #c9a227;
}
.tbt-rating-summary {
	display: flex;
	align-items: center;
	gap: 8px;
	margin: 6px 0 0;
	text-decoration: none;
	color: inherit;
}
.tbt-rating-count {
	font-size: 13px;
	color: #666;
}
#tbt-reviews .commentlist {
	list-style: none;
	margin: 16px 0;
	padding: 0;
}
#tbt-reviews .comment-text {
	border-bottom: 1px solid var(--colorBorder, #e8e8e1);
	padding: 16px 0;
}
/* Real reviews imported from the source carry their own title as a bold
   first line in the comment body (WooCommerce's review form has no native
   title field) — a bit of breathing room before the body text underneath,
   matching the source's own title-above-body layout. */
#tbt-reviews .comment-text .description > p:first-child strong:first-child {
	display: block;
	margin-bottom: 6px;
}
/* Simplified star picker: each star fills on its own hover/selection rather
   than the usual cascading 1-5 fill — a reasonable simplification, still a
   real clickable 1-5 rating control rather than raw "1 of 5 stars" text. */
#tbt-reviews p.stars a {
	display: inline-block;
	width: 1.3em;
	text-indent: -9999px;
	position: relative;
}
#tbt-reviews p.stars a::before {
	content: '\2606';
	text-indent: 0;
	position: absolute;
	left: 0;
	top: 0;
	font-size: 20px;
	color: #c9a227;
}
#tbt-reviews p.stars a:hover::before,
#tbt-reviews p.stars a.active::before {
	content: '\2605';
}
#tbt-reviews #respond input[type="text"],
#tbt-reviews #respond input[type="email"],
#tbt-reviews #respond textarea {
	width: 100%;
	max-width: 480px;
	padding: 8px 10px;
	border: 1px solid var(--colorBorder, #e8e8e1);
	margin-bottom: 10px;
	display: block;
}

/* My Account — source.css has no rules for WooCommerce's own account markup
   (a WP/Woo convention, not a Shopify one). */
.tbt-account-auth {
	display: flex;
	flex-wrap: wrap;
	gap: 48px;
	padding: 40px 0;
}
.tbt-account-auth__col {
	flex: 1 1 320px;
}
.tbt-account-auth .form-row {
	margin-bottom: 14px;
}
.tbt-account-auth label {
	display: block;
	margin-bottom: 4px;
	font-size: 14px;
}
.tbt-account-auth input[type="text"],
.tbt-account-auth input[type="email"],
.tbt-account-auth input[type="password"] {
	width: 100%;
	max-width: 360px;
	padding: 10px 12px;
	border: 1px solid var(--colorBorder, #e8e8e1);
}
.tbt-account-auth .woocommerce-form-login__rememberme {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	margin-right: 16px;
}
.woocommerce-MyAccount-navigation {
	float: left;
	width: 25%;
	padding-right: 24px;
}
.woocommerce-MyAccount-navigation ul {
	list-style: none;
	margin: 0;
	padding: 0;
}
.woocommerce-MyAccount-navigation li {
	border-bottom: 1px solid var(--colorBorder, #e8e8e1);
}
.woocommerce-MyAccount-navigation li a {
	display: block;
	padding: 10px 0;
}
.woocommerce-MyAccount-navigation li.is-active a {
	font-weight: 700;
}
.woocommerce-MyAccount-content {
	float: left;
	width: 75%;
}
.woocommerce-MyAccount-content table.shop_table {
	width: 100%;
	border-collapse: collapse;
}
.woocommerce-MyAccount-content table.shop_table th,
.woocommerce-MyAccount-content table.shop_table td {
	padding: 10px;
	border-bottom: 1px solid var(--colorBorder, #e8e8e1);
	text-align: left;
}
.woocommerce-Address {
	clear: both;
	padding-top: 20px;
}
@media screen and (max-width: 768px) {
	.woocommerce-MyAccount-navigation,
	.woocommerce-MyAccount-content {
		float: none;
		width: 100%;
	}
}

/* Checkout — LOCKED #3d rebuild (see woocommerce/checkout/form-checkout.php
   header comment for the full rationale: the source's real checkout is
   Shopify's own hosted two-column checkout, not a custom theme build). */
.tbt-checkout-header {
	border-bottom: 1px solid var(--colorBorder, #e8e8e1);
	padding: 20px 0;
	text-align: center;
}
.tbt-checkout-header__logo img {
	max-width: 110px;
	height: auto;
}
.tbt-checkout-footer {
	text-align: center;
	padding: 24px 0 40px;
	font-size: 13px;
	color: #777;
}
.tbt-checkout-footer a {
	color: inherit;
}

.tbt-checkout__grid {
	display: flex;
	flex-wrap: wrap-reverse;
	gap: 48px;
	max-width: 1100px;
	margin: 0 auto;
	padding: 32px 24px 80px;
	align-items: flex-start;
}
.tbt-checkout__main {
	flex: 1 1 520px;
	min-width: 0;
}
.tbt-checkout__sidebar {
	flex: 1 1 360px;
	max-width: 400px;
}
.tbt-checkout__sidebar-inner {
	background: #f9f9f9;
	border: 1px solid var(--colorBorder, #e8e8e1);
	border-radius: 8px;
	padding: 24px;
	position: sticky;
	top: 24px;
}
.tbt-checkout__section-title {
	font-size: 18px;
	margin: 32px 0 16px;
}
.tbt-checkout__main .tbt-checkout__section-title:first-child {
	margin-top: 0;
}
.tbt-checkout__payment-note {
	font-size: 13px;
	color: #666;
	margin-bottom: 16px;
}

.tbt-checkout .form-row {
	margin-bottom: 14px;
}
.tbt-checkout label {
	display: block;
	font-size: 13px;
	margin-bottom: 4px;
	color: #444;
}
.tbt-checkout input[type="text"],
.tbt-checkout input[type="email"],
.tbt-checkout input[type="tel"],
.tbt-checkout input[type="password"],
.tbt-checkout select,
.tbt-checkout textarea {
	width: 100%;
	padding: 11px 12px;
	border: 1px solid var(--colorBorder, #e8e8e1);
	border-radius: 4px;
	font-size: 15px;
}
.tbt-checkout .form-row-first,
.tbt-checkout .form-row-last {
	width: 48%;
	display: inline-block;
	vertical-align: top;
}
.tbt-checkout .form-row-first {
	margin-right: 4%;
}
@media screen and (max-width: 600px) {
	.tbt-checkout .form-row-first,
	.tbt-checkout .form-row-last {
		width: 100%;
		margin-right: 0;
	}
}

/* Payment method list — card-style rows instead of Woo's bare radio list. */
.tbt-checkout ul.wc_payment_methods {
	list-style: none;
	margin: 0;
	padding: 0;
}
.tbt-checkout ul.wc_payment_methods li.wc_payment_method {
	border: 1px solid var(--colorBorder, #e8e8e1);
	border-radius: 6px;
	margin-bottom: 10px;
	padding: 14px 16px;
}
.tbt-checkout ul.wc_payment_methods li.wc_payment_method label {
	display: inline;
	font-weight: 600;
	color: #111;
	margin-left: 6px;
}
.tbt-checkout ul.wc_payment_methods .payment_box {
	margin-top: 10px;
	padding: 12px;
	background: #f5f5f5;
	border-radius: 4px;
	font-size: 14px;
}
.tbt-checkout #place_order {
	width: 100%;
	padding: 16px;
	font-size: 16px;
	margin-top: 16px;
	/* WooCommerce gives this button its own "button alt" classes, not our
	   theme's real .btn — and since WooCommerce's own default button CSS is
	   dequeued site-wide (source.css has no rules for WC's own classes),
	   #place_order rendered as plain unstyled text (confirmed via computed
	   style: transparent background, no border). Restated the real .btn
	   values directly (same --colorBtnPrimary/--colorBtnPrimaryText tokens
	   the rest of the site's real buttons use), rather than a generic guess. */
	background: var(--colorBtnPrimary, #e5ce88);
	color: var(--colorBtnPrimaryText, #000000);
	border: 1px solid transparent;
	cursor: pointer;
	font-weight: 600;
}
.tbt-checkout #place_order:hover {
	background: var(--colorBtnPrimaryDim, #e0c573);
}
/* The real source checkout's own branding uses a near-black accent for
   selected radio controls (confirmed from the live checkout's own embedded
   design tokens: --x-skeleton-color-global-accent: #111111) — our radios
   were using the browser's default blue, since nothing sets accent-color. */
.tbt-checkout input[type="radio"] {
	accent-color: #111111;
}
/* Product thumbnail in the order summary — the real source's own checkout
   order summary shows a real product image per line (confirmed via the
   owner's saved checkout page); WooCommerce's default checkout review table
   has no image at all (a cart-page-only feature, not shared with checkout)
   — see woocommerce/checkout/review-order.php for the markup this styles. */
.tbt-checkout-item {
	display: flex;
	align-items: flex-start;
	gap: 10px;
}
.tbt-checkout-item img {
	width: 48px;
	height: auto;
	flex: 0 0 auto;
	border: 1px solid var(--colorBorder, #e8e8e1);
}
.tbt-checkout-item__meta {
	flex: 1 1 auto;
	min-width: 0;
}

/* Order summary sidebar — compact product rows + totals table. */
.tbt-checkout__sidebar table.shop_table {
	width: 100%;
	border-collapse: collapse;
	font-size: 14px;
}
.tbt-checkout__sidebar table.shop_table td,
.tbt-checkout__sidebar table.shop_table th {
	padding: 8px 0;
	border-bottom: 1px solid var(--colorBorder, #e8e8e1);
	text-align: left;
}
.tbt-checkout__sidebar table.shop_table td:last-child,
.tbt-checkout__sidebar table.shop_table th:last-child {
	text-align: right;
}
.tbt-checkout__sidebar .order-total td,
.tbt-checkout__sidebar .order-total th {
	font-weight: 700;
	font-size: 16px;
	border-bottom: none;
}

/* Minimum order shortfall notice (LOCKED #3b) — cart + checkout totals tables. */
.tbt-min-order-notice td {
	color: #a33;
	font-size: 13px;
	font-weight: 600;
	padding-top: 10px;
	border-bottom: none;
}

/* Shipping method — its own full-width section in the main column (matches
   the source's real checkout: Delivery / Shipping method / Payment are
   three separate sections, not folded into the order summary). The order
   summary's own copy of this row (same template, different context) is
   hidden here rather than removed server-side — the narrow sidebar column
   has no room for the real titles + "N business days" sub-copy without
   wrapping one word per line. */
.tbt-checkout__sidebar tr.shipping {
	display: none;
}
.tbt-checkout ul.woocommerce-shipping-methods {
	list-style: none;
	margin: 0;
	padding: 0;
}
.tbt-checkout ul.woocommerce-shipping-methods li {
	position: relative;
	border: 1px solid var(--colorBorder, #e8e8e1);
	border-radius: 6px;
	margin-bottom: 8px;
	padding: 12px 14px 12px 38px;
}
.tbt-checkout ul.woocommerce-shipping-methods li:has(input:checked) {
	border-color: #111;
	background: #f5f5f5;
}
.tbt-checkout ul.woocommerce-shipping-methods input.shipping_method {
	position: absolute;
	left: 14px;
	top: 14px;
}
.tbt-checkout ul.woocommerce-shipping-methods label {
	display: block;
	margin: 0;
}
.tbt-shipping-row {
	display: flex;
	justify-content: space-between;
	align-items: flex-start;
	gap: 12px;
}
.tbt-shipping-main {
	flex: 1 1 auto;
	min-width: 0;
}
.tbt-shipping-title {
	font-size: 14px;
	font-weight: 600;
	color: #111;
}
.tbt-shipping-price {
	font-size: 14px;
	font-weight: 600;
	color: #111;
	white-space: nowrap;
}
.tbt-shipping-subcopy {
	display: block;
	font-weight: 400;
	font-size: 12px;
	color: #767676;
	margin-top: 2px;
}
.tbt-shipping-subcopy span {
	display: block;
}

/* Shop/collection filter drawer. */
.tbt-filter-drawer {
	position: fixed;
	top: 0;
	left: -340px;
	width: 320px;
	height: 100%;
	background: #fff;
	box-shadow: 2px 0 12px rgba(0, 0, 0, 0.15);
	z-index: 1000;
	overflow-y: auto;
	padding: 20px;
	transition: left 0.25s ease;
}
.tbt-filter-drawer.is-open {
	left: 0;
}
.tbt-filter-drawer__header {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-bottom: 16px;
}
.tbt-filter-drawer__close {
	background: none;
	border: none;
	font-size: 28px;
	line-height: 1;
	cursor: pointer;
}
.tbt-filter-form fieldset {
	border: none;
	border-top: 1px solid var(--colorBorder, #e8e8e1);
	padding: 12px 0;
	margin: 0;
}
.tbt-filter-form legend {
	font-weight: 700;
	text-transform: uppercase;
	font-size: 12px;
	letter-spacing: 0.05em;
	padding: 0;
}
.tbt-filter-form label {
	display: block;
	padding: 4px 0;
	font-size: 14px;
}
.tbt-filter-clear {
	display: block;
	text-align: center;
	margin-top: 10px;
	font-size: 13px;
}

/* Product gallery lightbox (behaviour-pass equivalent of the source's
   PhotoSwipe zoom). */
.tbt-lightbox {
	display: none;
	position: fixed;
	inset: 0;
	z-index: 9998;
	background: rgba(0, 0, 0, 0.9);
	align-items: center;
	justify-content: center;
	padding: 40px;
}
.tbt-lightbox.is-open {
	display: flex;
}
.tbt-lightbox__img {
	max-width: 100%;
	max-height: 100%;
	object-fit: contain;
}
.tbt-lightbox__close {
	position: absolute;
	top: 20px;
	right: 30px;
	background: none;
	border: none;
	color: #fff;
	font-size: 36px;
	line-height: 1;
	cursor: pointer;
}

/* Store pickup note (PDP) — the source's .store-availability block. */
.store-availability {
	display: flex;
	gap: 8px;
	align-items: flex-start;
	margin: 12px 0;
	font-size: 14px;
}
.store-availability__small {
	margin: 2px 0 0;
	color: #666;
	font-size: 12px;
}

/* Logo fallback: the source's logo is a theme-setting image sized by inline
   style on its wrapper; our plain <img> fallback needs an explicit cap. */
.site-header__logo-link img.tbt-logo-fallback {
	max-width: 90px;
	height: auto;
	display: block;
}
.footer__logo img.tbt-logo-fallback {
	max-height: 60px;
	width: auto;
}

/* Category tiles: source sizes these via an inline aspect-ratio wrapper we
   simplified away — keep them square-ish and reasonably sized without it. */
.tbt-home-tile img {
	width: 100%;
	max-width: 420px;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	display: block;
	margin: 0 auto;
}
.tbt-home-tile__title {
	margin: 16px 0;
}

/* New Arrivals / Barrel Picks product grid — static grid, no Flickity carousel
   (behaviour pass 2). Tabs are a plain show/hide (site.js), not AJAX-swapped. */
.collection-switcher__collection-grid {
	display: flex;
	flex-wrap: wrap;
	gap: 16px;
	justify-content: center;
	margin-top: 24px;
}
/* Yet another instance of the JS-reveal pattern (RECON-FINDINGS.md / PROJECT-
   BRIEF.md integration notes): source.css has
   `.collection-switcher__collection-grid .grid__item{opacity:0}` scoped
   specifically to this carousel, revealed by Flickity/AOS JS we don't have.
   Found via document.styleSheets + Element.matches() after plain selector
   text search missed it (it's a descendant rule, not on .grid-product or
   .grid__item alone). */
.collection-switcher__collection-grid .grid__item {
	opacity: 1 !important;
	display: block !important;
}
/* Our own display:flex above beats the browser's default [hidden]{display:none}
   (equal specificity, author stylesheet wins) — restate it explicitly so the
   Barrel Picks tab actually stays hidden until site.js toggles it. */
.collection-switcher__collection[hidden] {
	display: none !important;
}
.collection-switcher__collection-grid .grid-product {
	width: 220px !important;
	flex: 0 0 220px !important;
	float: none !important;
}
.collection-switcher__collection-grid .grid-product__image-mask img {
	width: 100%;
	aspect-ratio: 1 / 1;
	object-fit: contain;
	background: #f5f5f5;
}
.collection-switcher__collection-grid .grid-product__meta {
	padding: 8px 4px;
	text-align: center;
}
.collection-switcher__collection-grid .grid-product__title {
	font-size: 14px;
	min-height: 2.6em;
}
.collection-switcher__collection-grid .grid-product__vendor {
	font-size: 12px;
	color: #888;
	text-transform: uppercase;
}
.collection-switcher__collection-grid .grid-product__price--compare {
	text-decoration: line-through;
	color: #999;
	margin-left: 6px;
}
.collection-switcher__title {
	display: inline-block;
	margin: 0 16px;
}
.collection-switcher__trigger {
	cursor: pointer;
	padding-bottom: 4px;
	opacity: 0.5;
}
.collection-switcher__trigger.is-active {
	opacity: 1;
	border-bottom: 2px solid currentColor;
}

/* Feature row (Gift Cards block): text one side, image the other. */
.feature-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 32px;
}
.feature-row__item {
	flex: 1 1 360px;
}
.feature-row__image {
	width: 100%;
	height: auto;
	display: block;
}

/* Corporate Gifts banner: dark-overlay hero, fixed height (matches source's
   hero--450px / hero--mobile--250px). */
.tbt-corporate-hero {
	position: relative;
	height: 450px;
	overflow: hidden;
}
.tbt-corporate-hero .hero__image-wrapper {
	position: absolute;
	inset: 0;
}
.tbt-corporate-hero .hero__image-wrapper::after {
	content: '';
	position: absolute;
	inset: 0;
	background: #000;
	opacity: 0.6;
}
.tbt-corporate-hero .hero__image {
	width: 100%;
	height: 100%;
	object-fit: cover;
}
.tbt-corporate-hero .hero__text-wrap {
	position: absolute;
	inset: 0;
	z-index: 2;
	display: flex;
	align-items: center;
}
.tbt-corporate-hero .hero__text-content {
	text-align: center;
	color: #fff;
	width: 100%;
}
.tbt-corporate-hero .hero__title {
	color: #fff;
	margin-bottom: 12px;
}
.tbt-corporate-hero .hero__subtitle {
	margin-bottom: 20px;
}
@media screen and (max-width: 768px) {
	.tbt-corporate-hero {
		height: 250px;
	}
}

/* Reviews (static placeholder — not the live Judge.me app). */
.tbt-reviews-summary {
	color: #c9a227;
	font-weight: 600;
	margin: 8px 0 32px;
}
.tbt-reviews-grid {
	display: flex;
	flex-wrap: wrap;
	gap: 24px;
	justify-content: center;
}
.tbt-review-card {
	width: 260px;
	text-align: left;
	border: 1px solid var(--colorBorder, #e8e8e1);
	border-radius: 6px;
	padding: 16px;
}
.tbt-review-card__title {
	font-weight: 700;
	margin-bottom: 8px;
}
.tbt-review-card__body {
	font-size: 14px;
	color: #444;
}
.tbt-review-card__name {
	margin-top: 12px;
	font-size: 12px;
	color: #888;
	text-transform: uppercase;
}

/* Brand logo row. */
.logo-bar {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	align-items: center;
	gap: 40px;
	margin-top: 24px;
}
.logo-bar__image {
	max-width: 110px;
	height: auto;
}
@media only screen and (min-width: 769px) {
	.logo-bar__image {
		max-width: 160px;
	}
}

/* Mid-page newsletter band. */
.tbt-newsletter-section {
	background: #f9f9f9;
	padding: 48px 0;
}
.tbt-newsletter-section .input-group {
	display: flex;
	max-width: 420px;
	margin: 16px auto 0;
}
.tbt-newsletter-section .newsletter__input {
	flex: 1;
	padding: 10px 12px;
	border: 1px solid var(--colorBorder, #e8e8e1);
}
.tbt-form-note {
	margin-top: 8px;
	font-size: 13px;
}

/* Blog posts row. */
.article__grid-image img {
	width: 100%;
	aspect-ratio: 3 / 2;
	object-fit: cover;
	display: block;
}
.article__grid-meta {
	padding-top: 10px;
}
.article__date {
	font-size: 12px;
	color: #888;
}
.article__title {
	display: block;
	font-weight: 600;
	margin-top: 4px;
}

/* Quick Shop modal (template-parts/product-card.php + site.js) — source.css
   already has .modal{display:none} plus all the .modal__inner/.modal--quick-shop
   layout rules (real theme classes), but the JS-driven "open" class is the
   app's own internal name, not something we can replicate without its JS. We
   use our own .is-active toggle instead (same pattern as the filter drawer),
   reusing the source's real .modal-open body class for the scroll lock. */
.modal.is-active {
	display: flex !important;
}
.modal__inner {
	position: relative;
	z-index: 1;
}

/* Variation selector (template-parts/product-form-fields.php): the real
   <select> WooCommerce's own variation-matching script needs stays in the
   DOM and functional, just visually replaced by the source's pill-button
   .variant-input-wrap UI sitting next to it (site.js bridges clicks on the
   pills to this select). */
.tbt-variant-select-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
}
.variant-input-wrap {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	border: 0;
	padding: 0;
	margin: 0 0 12px;
}
.variant-input-wrap .hide {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
}
.variant-input {
	position: relative;
}
.variant-input input[type="radio"] {
	position: absolute;
	opacity: 0;
	width: 100%;
	height: 100%;
	margin: 0;
	cursor: pointer;
}
.variant-input label {
	display: block;
	padding: 8px 16px;
	border: 1px solid var(--colorBorder, #d1d1d1);
	border-radius: 2px;
	font-size: 13px;
	cursor: pointer;
}
.variant-input input[type="radio"]:checked + label {
	border-color: #111;
	background: #111;
	color: #fff;
}
.variant__label {
	display: block;
	font-size: 12px;
	text-transform: uppercase;
	letter-spacing: 0.05em;
	margin-bottom: 6px;
}

/* Quick-shop modal's own two-column layout, scaled down from the full PDP
   grid (the modal has less width to work with than a real page). */
.tbt-quick-shop__grid {
	padding: 40px;
	max-width: 1100px;
}
.tbt-quick-shop-loading {
	padding: 60px;
	text-align: center;
	color: #767676;
}
.tbt-quick-shop__view-full {
	margin-top: 12px;
	font-size: 13px;
}
@media screen and (max-width: 749px) {
	.tbt-quick-shop__grid {
		padding: 24px 16px;
	}
}

/* Cart drawer (header.php #CartDrawer, woocommerce/cart/mini-cart.php) —
   .cart__item etc. are the source's own real classes (already styled by
   source.css), but .tbt-cart-remove is our own addition (the source's
   native drawer has no remove affordance at all — see header.php's
   #CartDrawer comment) so it needs its own positioning. */
.drawer__contents {
	display: flex;
	flex-direction: column;
	height: 100%;
}
.drawer__fixed-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 20px;
	border-bottom: 1px solid var(--colorBorder, #e8e8e1);
}
.drawer__header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	width: 100%;
}
.drawer__title {
	font-size: 18px;
}
.drawer__close-button {
	background: none;
	border: 0;
	cursor: pointer;
	padding: 4px;
}
.drawer__inner {
	flex: 1 1 auto;
	overflow-y: auto;
}
.drawer__scrollable {
	padding: 0 20px;
}
#CartDrawer .cart__item {
	position: relative;
	padding: 16px 32px 16px 0;
	border-bottom: 1px solid var(--colorBorder, #e8e8e1);
	display: grid;
	grid-template-columns: 70px 1fr;
	gap: 14px;
}
#CartDrawer .cart__item--headers {
	display: none;
}
/* source.css's own .image-wrap is a bare <a> (display:inline by default)
   relying on an inline height:0;padding-bottom:<aspect>% hack (set via JS
   per-image on the real source) to give it real box dimensions as the
   containing block for its position:absolute img — we don't replicate that
   per-image aspect-ratio JS, so left as-is the <a> collapses to a 0x0 inline
   box, which clamps the absolutely-positioned img's width (via the source's
   own unrelated bare `img{max-width:100%}` reset resolving against a 0px
   containing block) to 0 regardless of any width we declare here — confirmed
   via computed-style inspection, not guessed. Simplest correct fix: take the
   image out of absolute positioning inside the drawer entirely so it just
   sizes normally in-flow against the real 70px grid column. */
#CartDrawer .cart__item--image .image-wrap {
	display: block;
	width: 70px;
}
#CartDrawer .cart__item--image img {
	width: 70px;
	height: auto;
	display: block;
	position: static;
}
/* Same 0x0 .image-wrap collapse as the cart drawer above (found in a QA pass):
   the blog post template's featured image uses the real .image-wrap class
   with no aspect-ratio JS to give it height, so it collapsed to 0px tall —
   image loaded fine (confirmed via naturalWidth), just invisible. Same fix:
   take the img out of absolute positioning so it sizes normally in-flow. */
.article__featured-image.image-wrap {
	display: block;
}
.article__featured-image.image-wrap img {
	position: static;
	width: 100%;
	height: auto;
}
#CartDrawer .cart__item--name {
	font-weight: 600;
	font-size: 13px;
	margin-bottom: 6px;
}
#CartDrawer .cart__item--variants {
	font-weight: 400;
	color: #767676;
	font-size: 12px;
	margin-top: 2px;
}
#CartDrawer .cart__item--qty {
	margin-top: 8px;
}
#CartDrawer .cart__item--price {
	margin-top: 6px;
	font-size: 13px;
}
.tbt-cart-remove {
	position: absolute;
	top: 16px;
	right: 0;
	background: none;
	border: 0;
	cursor: pointer;
	padding: 4px;
	color: #555;
}
.tbt-cart-remove:hover {
	color: #111;
}
.tbt-cart-remove svg {
	width: 20px;
	height: 20px;
	fill: none;
	stroke: currentColor;
	stroke-width: 4;
}
.cart__footer {
	padding: 16px 20px 20px;
	border-top: 1px solid var(--colorBorder, #e8e8e1);
}
.cart__item-sub {
	display: flex;
	justify-content: space-between;
	font-weight: 600;
	margin-bottom: 8px;
}
.cart__checkout-wrapper {
	margin-top: 14px;
}
.cart__checkout-wrapper .cart__checkout {
	display: block;
	width: 100%;
	text-align: center;
	padding: 14px;
}
.tbt-cart-empty {
	padding: 40px 20px;
	text-align: center;
	color: #767676;
}

/* Header predictive search (header.php / inc/search.php) — the theme's own
   real .search__results is already styled by source.css, but source.css
   ALSO still carries Snize's own `.search__results{display:none!important}`
   suppression rule (confirmed: that app hides the native theme dropdown and
   shows its own `.snize-*` one instead) — harmless on the live source since
   Snize's JS populates its own separate dropdown, but it blocks OUR use of
   the real native one now that we're driving it ourselves. #predictive-
   search's own ID beats that bare-class !important rule on specificity
   alone, so toggling this class is enough to safely re-enable it. */
#predictive-search.is-active {
	display: block !important;
}
/* source.css's real .predictive-search-results{display:flex;flex-direction:
   row} lays the Categories/Products groups out as side-by-side columns but
   defines no gap between them — harmless on the live source since Snize's
   own dropdown replaces this one entirely, but with the real native
   dropdown actually in use here the two groups' headers butt up against
   each other with zero spacing. Supplementing, not overriding, the real
   rule. */
.predictive-search-results > div + div {
	margin-left: 40px;
}
.predictive-search-results > div {
	min-width: 180px;
}
#predictive-search-products {
	min-width: 320px;
}
.predictive__result {
	margin-bottom: 16px;
}
.predictive__result-image img {
	width: 60px;
	height: auto;
	display: block;
}

/* Track Order page (page-track-order.php) — a real, native WooCommerce
   order lookup with no source styling to reuse (the source's own page is
   just a 3rd-party AfterShip embed with no real form markup of its own). */
.tbt-track-page {
	padding-top: 40px;
	padding-bottom: 60px;
}
.tbt-track-intro {
	color: #666;
	margin: 10px 0 30px;
}
.tbt-track-form {
	max-width: 380px;
}
.tbt-track-field {
	margin-bottom: 20px;
}
.tbt-track-field label {
	display: block;
	margin-bottom: 8px;
}
.tbt-track-field input {
	width: 100%;
}
.tbt-track-form .btn {
	margin-top: 4px;
}
.tbt-track-notice {
	max-width: 380px;
	margin-top: 20px;
	padding: 14px 16px;
	background: var(--colorBodyDim, #f2f2f2);
	border-left: 3px solid #c0392b;
}
.tbt-track-result {
	max-width: 500px;
	margin-top: 40px;
	padding-top: 30px;
	border-top: 1px solid var(--colorBorder, #e8e8e1);
}
.tbt-track-result h3 {
	margin-bottom: 10px;
}
.tbt-track-result .shop_table {
	width: 100%;
	margin: 16px 0;
}
.tbt-track-result .shop_table td {
	padding: 8px 0;
	border-bottom: 1px solid var(--colorBorder, #e8e8e1);
}
.tbt-track-result .shop_table td:last-child {
	text-align: right;
}
/* Found in a QA pass: WordPress's paginate_links() already correctly marks
   the active page with a real "current" class (confirmed in the rendered
   markup — class="page-numbers current"), but nothing styled it, so it
   looked identical to every other page number. The real source dims its
   own current-page marker (.pagination .page.current{opacity:.3}) — same
   real value, applied to our actual class combination since WordPress's
   "page-numbers" convention never matches Shopify's own "page" class. */
.pagination .page-numbers.current {
	opacity: 0.3;
}
