← back to Designer Wallcoverings
Rotating new-arrivals collection hero (DTD source=A/curation=C-hybrid) + F3 specificity fix
1a27c781e829d72a02e77e623dfd8f408601b102 · 2026-06-23 15:49:54 -0700 · Steve
- snippet evolved to a crossfade rotator: curated collection.image/default = frame 1,
then newest store-wide products from collections['new-arrivals'] (self-updating via cadence)
- new asset dw-hero-rotator.js: relocates rotator into Boost header band, crossfade timer,
prefers-reduced-motion hold, preload-next, Page-Visibility pause, idempotent
- CSS: .dw-hero-slide crossfade layers; Boost inner-wrapper transparency so slides show through
- F3 mobile header gap FIXED via specificity (body.template-collection .header-branding, 0,2,0
beats theme.css 0,1,0) at the theme's own 769px breakpoint, no !important brute force
- settings: collection_hero_rotate toggle (absorbs Codex dissent: off = curated-only)
- STAGE-DEV.sh stages all 5 assets to dev 143947038771; PUSH-LIVE.sh extended for the JS+toggle
- verified on real DOM at 1440px + iPhone-13: crossfade advances, reduced-motion holds,
F3 branding 118->74px, header 160->124px
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
A shopify/collection-hero-fix/PUSH-LIVE.shA shopify/collection-hero-fix/STAGE-DEV.shA shopify/collection-hero-fix/backups/assets_custom.css.dev-143947038771.pushbakA shopify/collection-hero-fix/backups/assets_custom.css.live-142250278963.pushbakA shopify/collection-hero-fix/backups/config_settings_schema.json.dev-143947038771.pushbakA shopify/collection-hero-fix/backups/config_settings_schema.json.live-142250278963.pushbakA shopify/collection-hero-fix/backups/sections_collection.liquid.dev-143947038771.pushbakA shopify/collection-hero-fix/backups/sections_collection.liquid.live-142250278963.pushbakM shopify/collection-hero-fix/dw-collection-hero.cssA shopify/collection-hero-fix/dw-hero-rotator.jsA shopify/collection-hero-fix/patched/assets_dw-hero-rotator.jsA shopify/collection-hero-fix/patched/dw-collection-hero.cssA shopify/collection-hero-fix/patched/snippets_dw-collection-hero-bg.liquidM shopify/collection-hero-fix/snippets_dw-collection-hero-bg.liquidA verify-rotating-hero.js
Diff
commit 1a27c781e829d72a02e77e623dfd8f408601b102
Author: Steve <steve@designerwallcoverings.com>
Date: Tue Jun 23 15:49:54 2026 -0700
Rotating new-arrivals collection hero (DTD source=A/curation=C-hybrid) + F3 specificity fix
- snippet evolved to a crossfade rotator: curated collection.image/default = frame 1,
then newest store-wide products from collections['new-arrivals'] (self-updating via cadence)
- new asset dw-hero-rotator.js: relocates rotator into Boost header band, crossfade timer,
prefers-reduced-motion hold, preload-next, Page-Visibility pause, idempotent
- CSS: .dw-hero-slide crossfade layers; Boost inner-wrapper transparency so slides show through
- F3 mobile header gap FIXED via specificity (body.template-collection .header-branding, 0,2,0
beats theme.css 0,1,0) at the theme's own 769px breakpoint, no !important brute force
- settings: collection_hero_rotate toggle (absorbs Codex dissent: off = curated-only)
- STAGE-DEV.sh stages all 5 assets to dev 143947038771; PUSH-LIVE.sh extended for the JS+toggle
- verified on real DOM at 1440px + iPhone-13: crossfade advances, reduced-motion holds,
F3 branding 118->74px, header 160->124px
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
shopify/collection-hero-fix/PUSH-LIVE.sh | 64 +
shopify/collection-hero-fix/STAGE-DEV.sh | 67 +
.../assets_custom.css.dev-143947038771.pushbak | 1689 ++++++++++++++++++++
.../assets_custom.css.live-142250278963.pushbak | 1488 +++++++++++++++++
...g_settings_schema.json.dev-143947038771.pushbak | 542 +++++++
..._settings_schema.json.live-142250278963.pushbak | 527 ++++++
...ions_collection.liquid.dev-143947038771.pushbak | 262 +++
...ons_collection.liquid.live-142250278963.pushbak | 259 +++
shopify/collection-hero-fix/dw-collection-hero.css | 58 +-
shopify/collection-hero-fix/dw-hero-rotator.js | 141 ++
.../patched/assets_dw-hero-rotator.js | 141 ++
.../patched/dw-collection-hero.css | 161 ++
.../patched/snippets_dw-collection-hero-bg.liquid | 128 ++
.../snippets_dw-collection-hero-bg.liquid | 128 +-
verify-rotating-hero.js | 161 ++
15 files changed, 5781 insertions(+), 35 deletions(-)
diff --git a/shopify/collection-hero-fix/PUSH-LIVE.sh b/shopify/collection-hero-fix/PUSH-LIVE.sh
new file mode 100644
index 00000000..6531b382
--- /dev/null
+++ b/shopify/collection-hero-fix/PUSH-LIVE.sh
@@ -0,0 +1,64 @@
+#!/usr/bin/env bash
+# Steve-gated LIVE push of the 4 staged collection-hero fixes (F1 hero band, F2 dup-title
+# hide, F3 mobile header) to the PUBLISHED theme. Additive + reversible:
+# - new snippet (delete to revert)
+# - CSS inside an idempotent /* >>> ... START/END <<< */ marked block (re-run safe)
+# - settings_schema merged + existence-guarded (won't clobber concurrent customizer edits)
+# - every overwritten asset GET-backed-up to *.pushbak BEFORE the PUT
+# Live theme resolved dynamically as role==main. Re-verifies after.
+# bash PUSH-LIVE.sh
+set -euo pipefail
+cd "$(cd "$(dirname "$0")/../.." && pwd)" # -> ~/Projects/Designer-Wallcoverings
+TOK=$(grep -m1 '^SHOPIFY_THEME_TOKEN=' ~/Projects/secrets-manager/.env | cut -d= -f2- | tr -d '"' | tr -d "'")
+[ -z "$TOK" ] && { echo "No SHOPIFY_THEME_TOKEN"; exit 1; }
+STORE="designer-laboratory-sandbox.myshopify.com"
+LIVE=$(curl -sS -H "X-Shopify-Access-Token: $TOK" "https://$STORE/admin/api/2024-10/themes.json" \
+ | python3 -c 'import sys,json;print(next((str(t["id"]) for t in json.load(sys.stdin)["themes"] if t["role"]=="main"),""))')
+[ -z "$LIVE" ] && { echo "could not resolve role==main"; exit 1; }
+echo "LIVE (role=main) = $LIVE"
+mkdir -p shopify/collection-hero-fix/backups
+python3 - "$TOK" "$LIVE" "$STORE" <<'PY'
+import sys,json,urllib.request,urllib.parse,re,time
+tok,LIVE,STORE=sys.argv[1],sys.argv[2],sys.argv[3]
+def get(k):
+ q=urllib.parse.urlencode({'asset[key]':k})
+ return json.load(urllib.request.urlopen(urllib.request.Request(f"https://{STORE}/admin/api/2024-10/themes/{LIVE}/assets.json?{q}",headers={'X-Shopify-Access-Token':tok})))['asset']['value']
+def put(k,v):
+ body=json.dumps({'asset':{'key':k,'value':v}}).encode()
+ s=json.load(urllib.request.urlopen(urllib.request.Request(f"https://{STORE}/admin/api/2024-10/themes/{LIVE}/assets.json",data=body,method='PUT',headers={'X-Shopify-Access-Token':tok,'Content-Type':'application/json'})))['asset']['size']
+ print(' PUT',k,s,'bytes'); time.sleep(2)
+B='shopify/collection-hero-fix'
+for k in ['assets/custom.css','sections/collection.liquid','config/settings_schema.json']:
+ open(f"{B}/backups/{k.replace('/','_')}.live-{LIVE}.pushbak",'w').write(get(k)); print(' backup',k)
+put('snippets/dw-collection-hero-bg.liquid', open(f'{B}/snippets_dw-collection-hero-bg.liquid').read())
+put('assets/dw-hero-rotator.js', open(f'{B}/dw-hero-rotator.js').read())
+put('sections/collection.liquid', open(f'{B}/patched/sections_collection.liquid').read())
+live_ss=json.loads(get('config/settings_schema.json'))
+have_grp=any(isinstance(g,dict) and any(s.get('id')=='collection_default_hero' for s in g.get('settings',[])) for g in live_ss)
+have_tog=any(isinstance(g,dict) and any(s.get('id')=='collection_hero_rotate' for s in g.get('settings',[])) for g in live_ss)
+if not have_grp or not have_tog:
+ live_ss=[g for g in live_ss if not (isinstance(g,dict) and g.get('name')=='Collection hero')]
+ live_ss.insert(1,{"name":"Collection hero","settings":[
+ {"type":"paragraph","content":"Collection-page hero band. Per-collection Collection images always take priority (frame 1). When 'Rotate newest arrivals' is on, the newest store-wide products follow as a crossfade slideshow."},
+ {"type":"image_picker","id":"collection_default_hero","label":"Default collection hero image","info":"Used only when a collection has no image of its own. Recommended 2000x600."},
+ {"type":"checkbox","id":"collection_hero_rotate","label":"Rotate newest arrivals in the hero","default":True,"info":"Crossfades through the newest store-wide products (from the New Arrivals collection). Off = show only the curated/default image."}]})
+ put('config/settings_schema.json', json.dumps(live_ss,indent=2,ensure_ascii=False))
+else: print(' settings_schema already has hero group + rotate toggle, skipped')
+S='/* >>> dw-collection-hero-fix START >>> */'; E='/* <<< dw-collection-hero-fix END <<< */'
+base=re.sub(re.escape(S)+r'.*?'+re.escape(E),'',get('assets/custom.css'),flags=re.S).rstrip()+'\n'
+put('assets/custom.css', base+'\n'+S+'\n'+open(f'{B}/dw-collection-hero.css').read()+'\n'+E+'\n')
+# verify
+css=get('assets/custom.css'); coll=get('sections/collection.liquid'); snip=get('snippets/dw-collection-hero-bg.liquid'); js=get('assets/dw-hero-rotator.js')
+print("verify: CSS block present:", S in css)
+print("verify: render call present:", "dw-collection-hero-bg" in coll)
+print("verify: snippet (rotating) present:", "data-dw-hero-rotator" in snip, f"({len(snip)}b)")
+print("verify: rotator JS present:", "__dwHeroRotatorInit" in js, f"({len(js)}b)")
+print('LIVE push complete')
+PY
+echo "=== verify LIVE collection pages return no Liquid error ==="
+sleep 3
+for c in all new-arrivals grasscloth; do
+ err=$(curl -sS -A "Mozilla/5.0" "https://www.designerwallcoverings.com/collections/$c?_cb=$(date +%s)" | grep -oE "Liquid error[^<]*" | head -1)
+ printf " %-16s %s\n" "$c" "${err:-OK}"
+done
+echo "Rollback: re-PUT shopify/collection-hero-fix/backups/*.live-${LIVE}.pushbak, delete snippet + assets/dw-hero-rotator.js, strip the marked CSS block."
\ No newline at end of file
diff --git a/shopify/collection-hero-fix/STAGE-DEV.sh b/shopify/collection-hero-fix/STAGE-DEV.sh
new file mode 100644
index 00000000..c17e1db2
--- /dev/null
+++ b/shopify/collection-hero-fix/STAGE-DEV.sh
@@ -0,0 +1,67 @@
+#!/usr/bin/env bash
+# Stage the ROTATING new-arrivals hero + F3 fix onto the DEV theme (143947038771,
+# UNPUBLISHED — safe). Idempotent + backup-first. NOT the live theme.
+# Pushes 5 assets:
+# 1. snippets/dw-collection-hero-bg.liquid (rotating slides + inline style)
+# 2. assets/dw-hero-rotator.js (crossfade rotator, reduced-motion)
+# 3. sections/collection.liquid (the {% render %} line — unchanged from prior)
+# 4. config/settings_schema.json (+ collection_hero_rotate toggle, + default-hero picker)
+# 5. assets/custom.css (marked idempotent hero/F2/F3 block)
+# bash STAGE-DEV.sh
+set -euo pipefail
+cd "$(cd "$(dirname "$0")/../.." && pwd)" # -> ~/Projects/Designer-Wallcoverings
+TOK=$(grep -m1 '^SHOPIFY_THEME_TOKEN=' ~/Projects/secrets-manager/.env | cut -d= -f2- | tr -d '"' | tr -d "'")
+[ -z "$TOK" ] && { echo "No SHOPIFY_THEME_TOKEN"; exit 1; }
+STORE="designer-laboratory-sandbox.myshopify.com"
+DEV="${DEV_THEME_ID:-143947038771}"
+echo "DEV theme = $DEV (unpublished)"
+mkdir -p shopify/collection-hero-fix/backups
+python3 - "$TOK" "$DEV" "$STORE" <<'PY'
+import sys,json,urllib.request,urllib.parse,re,time
+tok,DEV,STORE=sys.argv[1],sys.argv[2],sys.argv[3]
+def get(k):
+ q=urllib.parse.urlencode({'asset[key]':k})
+ return json.load(urllib.request.urlopen(urllib.request.Request(f"https://{STORE}/admin/api/2024-10/themes/{DEV}/assets.json?{q}",headers={'X-Shopify-Access-Token':tok})))['asset']['value']
+def put(k,v):
+ body=json.dumps({'asset':{'key':k,'value':v}}).encode()
+ s=json.load(urllib.request.urlopen(urllib.request.Request(f"https://{STORE}/admin/api/2024-10/themes/{DEV}/assets.json",data=body,method='PUT',headers={'X-Shopify-Access-Token':tok,'Content-Type':'application/json'})))['asset']['size']
+ print(' PUT',k,s,'bytes'); time.sleep(2)
+B='shopify/collection-hero-fix'
+for k in ['assets/custom.css','sections/collection.liquid','config/settings_schema.json']:
+ try: open(f"{B}/backups/{k.replace('/','_')}.dev-{DEV}.pushbak",'w').write(get(k)); print(' backup',k)
+ except Exception as e: print(' (no existing',k,'-',e,')')
+# 1 snippet 2 rotator js
+put('snippets/dw-collection-hero-bg.liquid', open(f'{B}/snippets_dw-collection-hero-bg.liquid').read())
+put('assets/dw-hero-rotator.js', open(f'{B}/dw-hero-rotator.js').read())
+# 3 collection.liquid render line
+put('sections/collection.liquid', open(f'{B}/patched/sections_collection.liquid').read())
+# 4 settings_schema: add Collection hero group (default-hero picker + rotate toggle)
+live_ss=json.loads(get('config/settings_schema.json'))
+have_grp=any(isinstance(g,dict) and any(s.get('id')=='collection_default_hero' for s in g.get('settings',[])) for g in live_ss)
+have_tog=any(isinstance(g,dict) and any(s.get('id')=='collection_hero_rotate' for s in g.get('settings',[])) for g in live_ss)
+if not have_grp or not have_tog:
+ grp={"name":"Collection hero","settings":[
+ {"type":"paragraph","content":"Collection-page hero band. Per-collection Collection images always take priority (frame 1). When 'Rotate newest arrivals' is on, the newest store-wide products follow as a crossfade slideshow."},
+ {"type":"image_picker","id":"collection_default_hero","label":"Default collection hero image","info":"Used only when a collection has no image of its own. Recommended 2000x600."},
+ {"type":"checkbox","id":"collection_hero_rotate","label":"Rotate newest arrivals in the hero","default":True,"info":"Crossfades through the newest store-wide products (from the New Arrivals collection). Off = show only the curated/default image."}]}
+ # remove any partial prior group then insert fresh
+ live_ss=[g for g in live_ss if not (isinstance(g,dict) and g.get('name')=='Collection hero')]
+ live_ss.insert(1,grp)
+ put('config/settings_schema.json', json.dumps(live_ss,indent=2,ensure_ascii=False))
+else: print(' settings_schema already has hero group + rotate toggle, skipped')
+# 5 custom.css marked block (idempotent)
+S='/* >>> dw-collection-hero-fix START >>> */'; E='/* <<< dw-collection-hero-fix END <<< */'
+try: cur=get('assets/custom.css')
+except Exception: cur=''
+base=re.sub(re.escape(S)+r'.*?'+re.escape(E),'',cur,flags=re.S).rstrip()+'\n'
+put('assets/custom.css', base+'\n'+S+'\n'+open(f'{B}/dw-collection-hero.css').read()+'\n'+E+'\n')
+# verify
+css=get('assets/custom.css'); coll=get('sections/collection.liquid'); snip=get('snippets/dw-collection-hero-bg.liquid'); js=get('assets/dw-hero-rotator.js')
+print("verify: CSS block present:", S in css)
+print("verify: rotator slide markup present:", "data-dw-hero-rotator" in snip)
+print("verify: rotator JS present:", "__dwHeroRotatorInit" in js, f"({len(js)}b)")
+print("verify: render call present:", "dw-collection-hero-bg" in coll)
+print('DEV stage complete -> Preview theme', DEV)
+PY
+echo ""
+echo "PREVIEW: Shopify admin -> Online Store -> Themes -> '★ 5.0 Grid+Infinite FIX (approve)' ($DEV) -> Preview -> open /collections/all and any real collection."
diff --git a/shopify/collection-hero-fix/backups/assets_custom.css.dev-143947038771.pushbak b/shopify/collection-hero-fix/backups/assets_custom.css.dev-143947038771.pushbak
new file mode 100644
index 00000000..9e4e030f
--- /dev/null
+++ b/shopify/collection-hero-fix/backups/assets_custom.css.dev-143947038771.pushbak
@@ -0,0 +1,1689 @@
+/* Global font override — system sans-serif site-wide (matches product title/SKU) */
+body,html,h1,h2,h3,h4,h5,h6,p,a,span,div,li,td,th,label,input,select,textarea,button,.breadcrumbs,.breadcrumbs a,.breadcrumbs span,.main-content,.page-content,.page-title,.collection-title,.product-title,.product-vendor,.product-price,.product-description,.rte,.rte p,.rte li,.rte a,.rte span,.footer,.site-header,.navigation,.nav-link,.menu-link,.announcement-bar,.toolbar,.search-form,.search-results,.collection-grid,.product-grid,.product-list,.sidebar,.widget,.cart,.mini-cart,.shopify-section,.upper-footer,.upper-footer-item,.footer-blurb,.footer-blurb p,.footer-blurb a,.footer-linklist,.footer-linklist a,.footer-linklist li,.sub-footer-right,.sub-footer__row,.subfooter__payment-types,[class*=footer],[class*=footer] a,[class*=footer] p,[class*=footer] li,[class*=footer] span,[class*=footer] h1,[class*=footer] h2,[class*=footer] h3,[class*=footer] h4{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif!important}
+
+/* Override theme heading font (Lora serif → system sans-serif) */
+.quick-shop-modal-trigger,.product-list-item-inventory,.mega-nav-list .mega-nav-list-title .mega-nav-list-title-link,.navigation.navigation-desktop .mega-nav-list .mega-nav-list-title-link,.product-title,.home-masonry-feature-title,th,.section-title,.page-title,.shopify-policy__title h1,.shopify-policy__title .age-gate__heading,h1,.age-gate__heading,h2,h3,h4,h5,h6,.home-slideshow-slide-heading,.home-promotion-title,.collection-title,.mega-nav-list-title-link,.home-promo-grid-item-heading,.promo-grid__text,.toolbar__title,.sidebar__title{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif!important}
+.header-search-inline {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ flex-wrap: nowrap;
+}
+.header-search-inline .search-form {
+ margin: 0;
+}
+.header-search-inline__visual {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 30px;
+ height: 30px;
+ color: inherit;
+}
+.header-search-inline__visual svg {
+ width: 20px;
+ height: 20px;
+ display: block;
+}
+@media (max-width: 1079px) {
+ .header-content-right--inline-search {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ width: auto;
+ }
+}
+.product-list-item-thumbnail {
+ height: 0;
+ padding-bottom: 100%;
+ overflow: hidden;
+}
+.product-list-item-thumbnail > a {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ display: block;
+}
+.product-list-item-thumbnail img,
+.product-list-item-thumbnail svg {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+.product-info .vertical-center {
+ position: absolute;
+ top: 50%;
+ width: 100%;
+ transform: translateY(-50%);
+}
+.product-list-item > figure:hover .product-info,
+.product-grid-masonry-sizer > figure:hover .product-info {
+ opacity: 0.578159;
+}
+.product-info {
+ width: 100%;
+ height: 100%;
+ background-color: #fff;
+ opacity: 0;
+ transition: all 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94);
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ padding: 12px;
+ font-size: 1.07143rem;
+ text-align: center;
+ z-index: 1;
+ transform: translate(-50%) translateY(-50%);
+ color: #000;
+}
+.product-price-discount {
+ font-size: 0.9em;
+ line-height: 1.2;
+}
+
+/* ==========================================================================
+ Original custom css here
+ ========================================================================== */
+
+/* ===============================================
+// Hover Effect CSS
+// =============================================== */
+
+.hover-effect .hidden { display: block !important; visibility: visible !important;}
+.product:hover .hover-effect img { opacity: 1; }
+.hover-effect .hidden {
+position: absolute;
+z-index: -1;
+top: 0;
+width: 100%;
+height: 100%;
+opacity: 0;
+-webkit-transition: opacity 0.3s ease-in-out;
+-moz-transition: opacity 0.3s ease-in-out;
+-o-transition: opacity 0.3s ease-in-out;
+transition: opacity 0.3s ease-in-out;
+}
+.hover-effect:hover .hidden {
+z-index: 100000;
+opacity: 1;
+}
+.hover-effect .caption {
+position: absolute;
+top: 0;
+display: table;
+width: 100%;
+height: 100%;
+background-color: white; /* fallback for IE8 */
+background-color: rgba(255, 255, 255, 0.7);
+text-align: center;
+text-rendering: optimizeLegibility;
+}
+.hover-effect .hidden .caption .centered {
+display: table-cell;
+vertical-align: middle;
+}
+/* ===============================================
+// Reveal module
+// =============================================== */
+
+.reveal .hidden { display: block !important; visibility: visible !important;}
+.product:hover .reveal img { opacity: 1; }
+.reveal { position: relative; }
+.reveal .hidden {
+ position: absolute;
+ z-index: -1;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ opacity: 0;
+ -webkit-transition: opacity 0.3s ease-in-out;
+ -moz-transition: opacity 0.3s ease-in-out;
+ -o-transition: opacity 0.3s ease-in-out;
+ transition: opacity 0.3s ease-in-out;
+}
+.reveal:hover .hidden {
+ z-index: 100000;
+ opacity: 1;
+}
+.reveal .caption {
+ position: absolute;
+ top: 0;
+ display: table;
+ width: 100%;
+ height: 100%;
+ background-color: white; /* fallback for IE8 */
+ background-color: rgba(255, 255, 255, 0.7);
+ font: 13px/1.6 sans-serif;
+ text-transform: uppercase;
+ color: #333;
+ letter-spacing: 1px;
+ text-align: center;
+ text-rendering: optimizeLegibility;
+}
+.reveal .hidden .caption .centered {
+ display: table-cell;
+ vertical-align: middle;
+}
+@media (min-width: 480px) and (max-width: 979px) {
+ .reveal .caption {
+ font-size: 11px;
+ }
+}
+div#content {
+ width: 100%;
+ max-width: 1050px;
+ margin-left: auto;
+ margin-right: auto;
+}
+/*==================== 020 css for prod Quantity ============================*/
+
+.mm_quantity {
+ display: inline-block; }
+
+.mm_quantity .input-text.qty {
+ width: 40px;
+ height: 42px;
+ padding: 0 5px;
+ text-align: center;
+ background-color: transparent;
+ border: 1px solid #efefef;
+}
+.mm_quantity.mm_buttons_added {
+ text-align: left;
+ position: relative;
+ white-space: nowrap;
+ vertical-align: top;
+}
+.mm_quantity.mm_buttons_added input {
+ display: inline-block;
+ margin: 0;
+ vertical-align: top;
+ box-shadow: none;
+}
+.mm_quantity.mm_buttons_added .minus,
+.mm_quantity.mm_buttons_added .plus {
+ padding: 7px 10px 8px;
+ height: 42px;
+ background-color: #ffffff;
+ border: 1px solid #efefef;
+ cursor:pointer;
+ color:#000000;
+}
+.mm_quantity.mm_buttons_added .minus {
+ border-right: 0;
+}
+.mm_quantity.mm_buttons_added .plus {
+ border-left: 0;
+ margin-left: 1px;
+}
+.mm_quantity.mm_buttons_added .minus:hover,
+.mm_quantity.mm_buttons_added .plus:hover {
+ background: #eeeeee;
+}
+.mm_quantity input::-webkit-outer-spin-button,
+.mm_quantity input::-webkit-inner-spin-button {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ margin: 0;
+}
+.mm_quantity.mm_buttons_added .minus:focus,
+.mm_quantity.mm_buttons_added .plus:focus {
+ outline: none;
+}
+/*--------*/
+.shopify-product-form .product-options label {
+ text-transform: uppercase;
+ font-weight: bold;
+ font-size: 14px;
+ font-family: "Times New Roman", Times, serif;
+}
+/* Product option labels: vertically center with selects */
+.shopify-product-form .product-options label.product-option-column-1 {
+ display: flex;
+ align-items: center;
+ align-self: center;
+}
+.shopify-product-form .product-options label.product-option-column-1 strong {
+ line-height: 1.1;
+}
+/* Ensure the control column centers within the grid row too */
+.shopify-product-form .product-options .product-option-column-1 + * {
+ align-self: center;
+}
+/* Product options layout: center items + add row spacing (desktop grid) */
+body.template-product .shopify-product-form .product-options {
+ align-items: center;
+ row-gap: 3px;
+ column-gap: 14px;
+}
+body.template-product .shopify-product-form .product-options .product-option-column-1,
+body.template-product .shopify-product-form .product-options .product-option-column-1 + *,
+body.template-product .shopify-product-form .product-options .select-wrapper,
+body.template-product .shopify-product-form .product-options .last_variant {
+ margin: 0 !important;
+ align-self: center;
+}
+body.template-product .shopify-product-form .product-options label.product-option-column-1 {
+ min-height: 44px;
+}
+.mm_quantity {
+ margin-top: 10px !important;
+}
+
+@media only screen and (max-width: 769px) {
+ body.template-product .shopify-product-form .product-options {
+ display: grid;
+ grid-template-columns: max-content 1fr;
+ column-gap: 12px;
+ align-items: center;
+ width: 100%;
+ max-width: 100%;
+ }
+
+ body.template-product .shopify-product-form .product-options label.product-option-column-1 {
+ min-height: auto;
+ justify-content: flex-start;
+ grid-column: 1;
+ }
+
+ body.template-product .shopify-product-form .product-options select.single-option-selector,
+ body.template-product .shopify-product-form .product-options .last_variant,
+ body.template-product .shopify-product-form .product-options .mm_quantity {
+ grid-column: 2;
+ width: 100%;
+ }
+
+ body.template-product .shopify-product-form .product-options select.single-option-selector {
+ min-width: 0;
+ box-sizing: border-box;
+ height: 44px;
+ line-height: 44px;
+ padding-right: 28px;
+ }
+
+ body.template-product .shopify-product-form .product-options .product-option-row-1 { grid-row: 1; }
+ body.template-product .shopify-product-form .product-options .product-option-row-2 { grid-row: 2; }
+ body.template-product .shopify-product-form .product-options .product-option-row-3 { grid-row: 3; }
+ body.template-product .shopify-product-form .product-options .product-option-row-4 { grid-row: 4; }
+ body.template-product .shopify-product-form .product-options .product-option-row-5 { grid-row: 5; }
+ body.template-product .shopify-product-form .product-options .product-option-row-6 { grid-row: 6; }
+ body.template-product .shopify-product-form .product-options .product-option-row-7 { grid-row: 7; }
+ body.template-product .shopify-product-form .product-options .product-option-row-8 { grid-row: 8; }
+}
+#studioengine{
+ display: inline-block;
+ margin: 0;
+ padding: 0;
+ width: 100vw;
+ height: 100%;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ margin: 0 auto;
+ max-width: 100%;
+}
+#studioeditor {
+ display: inline-block;
+ margin: 0;
+ padding: 0;
+ width: 100vw;
+ height: 100%;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ margin: 0 auto;
+ max-width: 100%;
+}
+
+
+
+/*020*/
+
+
+.shopify-product-form .product-add-to-cart{
+ display: block;
+}
+
+/*============*/
+
+/*hide variant ddl from dropdown*/
+
+.last_variant{
+ font-family: "Open Sans",sans-serif!important;
+ font-style: normal!important;
+ font-weight: 400!important;
+ color: #333!important;
+ font-size: 14px!important;
+ line-height: 1.625!important;
+ font-weight: normal!important;
+ text-transform: capitalize!important;
+
+ position: relative;
+ top: -1px;
+}
+@media only screen and (max-width: 769px) {
+ .last_variant{
+ width: 100%;
+ display: inline-block;
+
+ }
+}
+
+/* SC start 009 */
+#custom-popup-overlay{
+ position: fixed;
+ display: none;
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0,0,0,0.5);
+ z-index: 99999;
+}
+#custom-popup-overlay .custom-popup-main{
+ margin: 80px auto;
+ padding: 20px;
+ background: #fff;
+ border-radius: 5px;
+ width: 30%;
+ position: relative;
+ transition: all 5s ease-in-out;
+ z-index: 9999;
+}
+#custom-popup-overlay .custom-popup-main .custom-close {
+ position: absolute;
+ top: 10px;
+ right: 20px;
+ transition: all 200ms;
+ font-size: 30px;
+ font-weight: bold;
+ text-decoration: none;
+ color: #333;
+ cursor:pointer;
+}
+#custom-popup-overlay .custom-popup-main .custom-close:hover {
+ color: #06D85F;
+}
+#custom-popup-overlay .custom-popup-main .content-main {
+ max-height: 30%;
+ overflow: auto;
+}
+#custom-popup-overlay .site-logo-in-popup{
+ text-align:center;
+ margin-top:25px;
+}
+#custom-popup-overlay .popup-content{
+ padding-top:30px;
+ text-align:center;
+}
+#custom-popup-overlay .site-logo-in-popup img{ width: 130px; }
+
+#custom-popup-overlay #contact_form{
+ padding:0px 5px;
+}
+/* Popup contact form: match intended full-width field styling */
+#custom-popup-overlay .custom-popup-main{
+ width: min(640px, calc(100% - 32px));
+ max-width: 640px;
+ padding: 40px 40px 30px;
+}
+#custom-popup-overlay .popup-content{
+ text-align: left;
+ padding-top: 20px;
+}
+#custom-popup-overlay .popup-content h2{
+ text-align: center;
+ margin: 0 0 22px;
+}
+#custom-popup-overlay .popup-content form{
+ width: 100%;
+}
+#custom-popup-overlay .field-wrap{
+ width: 100%;
+ margin: 0 0 14px;
+}
+#custom-popup-overlay .field-wrap input,
+#custom-popup-overlay .field-wrap textarea{
+ width: 100%;
+ display: block;
+ box-sizing: border-box;
+ padding: 12px 14px;
+ border: 1px solid #d9d9d9;
+ border-radius: 2px;
+ font-family: inherit;
+ font-size: 16px;
+}
+#custom-popup-overlay .field-wrap textarea{
+ min-height: 150px;
+ resize: vertical;
+}
+#custom-popup-overlay input[type="submit"]{
+ display: block;
+ width: fit-content;
+ min-width: 140px;
+ margin: 18px auto 0;
+ padding: 12px 22px;
+}
+
+@media screen and (max-width: 1100px) {
+ #custom-popup-overlay .custom-popup-main{
+ width: min(640px, calc(100% - 32px));
+ }
+}
+@media screen and (max-width: 1024px) {
+ .product-add-to-cart .add-to-cart{
+ width: 100% !important;
+ max-width:inherit !important;
+ }
+}
+@media screen and (max-width: 600px) {
+ .custom-popup-main .popup-content h2{
+ font-size:1.2rem;
+ }
+
+ #custom-popup-overlay .custom-popup-main{
+ margin: 20px auto;
+ padding: 26px 18px 20px;
+ }
+
+ #custom-popup-overlay .custom-popup-main textarea{
+ min-height:100px;
+ }
+}
+/* SC end 009 */
+
+.block-buttonpdf {
+ margin-top: 25px;
+}
+@media (min-width: 1024px) {
+ .template-search .main-content {
+ max-width: 1600px;
+ }
+
+ .template-search .section-search > .search-results-wrapper {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-around;
+ }
+
+ .template-search .section-search > .search-results-wrapper .search-results-count {
+ flex-basis: 100%;
+ }
+
+ #bc-sf-filter-wrapper {
+ flex-basis: 75%;
+ }
+
+ .template-search .section-search > .search-results-wrapper .search-results-wrapper {
+ flex-basis: 20%;
+ border-left: 1px solid #ccc;
+ }
+
+ #bc-sf-filter-right {
+ width: calc(100% - 237px);
+ }
+}
+.product-options #calculator .element,
+.product-options #calculator .price-marker {
+ padding-left: 0;
+ display: flex;
+ align-items: center;
+}
+.product-options #calculator .element label,
+.product-options #calculator .price-marker > label {
+ font-weight: bold;
+ font-size: 14px !important;
+ font-family: "Times New Roman", Times, serif;
+ /* margin-bottom: 10px !important; */
+ text-transform: uppercase;
+ min-width: 110px;
+ text-align: left;
+}
+.product-options #calculator .element input[type="number"],
+.product-options #calculator .element .formula-block label {
+ font-family: "Open Sans", sans-serif;
+ font-style: normal;
+ color: #333333;
+ font-size: 14px !important;
+ padding-left: 10px;
+}
+.product-options #calculator .price-marker span label {
+ color: #444;
+ font-family: Lora, serif;
+ font-size: 1.28571rem !important;
+ font-weight: 400 !important;
+}
+.product-options #calculator .price-marker span {
+ font-family: Lora, serif;
+ font-size: 1.28571rem !important;
+ font-weight: 400 !important;
+}
+.product-options #calculator .element .formula-block {
+ margin: 0;
+}
+.collection-header {
+ text-align: center;
+}
+.dl-customize-btn, .dl-contact-btn, .dl-sample-btn, .dl-second-sample-btn, .button, .submit, input[type=submit], input[type=button], .pxs-newsletter-form-button, .pxs-image-with-text-button {
+ font-family: Lora,serif;
+ font-style: normal;
+ font-weight: 700;
+ background: black;
+ color: #fff;
+ display: inline-block;
+ text-align: center;
+ line-height: normal;
+ padding: 15px 20px;
+ border-radius: 2px;
+ text-transform: uppercase;
+ font-size: .92857rem;
+}
+/* Hide Contact Us button on product pages */
+body.template-product .dl-contact-btn {
+ display: none !important;
+}
+.home-slideshow-slide-heading {
+ text-shadow: 0px 0px 2px #000, 2px 1px 1px #000, 3px 2px 1px #000, 4px 3px 1px #000, 5px 4px 1px #000;
+ font-size: 3.5em;
+}
+.home-slideshow-slide-subheading {
+ text-shadow: 0px 0px 1px #000, 1px 1px 1px #000, 2px 2px 1px #000;
+ font-weight: 500;
+ font-size: 2em;
+}
+@media (max-width: 769px) {
+ .home-slideshow-slide-heading {
+ color: #000!important;
+ font-size: clamp(1.75rem, 6vw, 2.4rem);
+ line-height: 1.1;
+ text-shadow: 0px 0px 0px #ffffff;
+ }
+ .home-slideshow-slide-subheading {
+ color: #8a8a8a!important;
+ font-size: clamp(1rem, 4.2vw, 1.4rem);
+ line-height: 1.2;
+ text-shadow: 0px 0px 0px #ffffff;
+ font-weight: 400;
+ }
+}
+/* New header */
+.header-layout-compact-left .header-branding-desktop img {
+ max-width: 100px;
+}
+.header-main-content {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+@media (min-width: 1080px) {
+ .header-layout-compact-left .header-branding-desktop {
+ width: 150px;
+ text-align: center;
+ }
+ .sticky-header .header-content-right {
+ display: table-cell;
+ vertical-align: middle;
+ }
+}
+@media (max-width: 1672px) {
+ .navigation.navigation-desktop .navigation-menu > li > a, .navigation.navigation-desktop .navigation-menu summary {
+ padding: 17px 25px;
+ font-size: 14px;
+ }
+ .navigation.navigation-desktop .has-dropdown>a:after, .navigation.navigation-desktop .has-dropdown summary:after, .navigation.navigation-desktop .has-mega-nav>a:after, .navigation.navigation-desktop .has-mega-nav summary:after {
+ right: 5px;
+ }
+}
+@media (max-width: 1525px) {
+ .header-layout-compact-left .header-branding-desktop {
+ width: 100px;
+ }
+ .navigation.navigation-desktop .navigation-menu > li >a, .navigation.navigation-desktop .navigation-menu summary {
+ padding: 17px 20px;
+ }
+ .header-layout-compact-left .navigation-wrapper,
+ .sticky-header .header-layout-compact-left .navigation-wrapper {
+ width: calc(100% - 100px);
+ }
+ .header-layout-compact-left .header-content-right {
+ width: 150px;
+ }
+}
+@media (max-width: 1345px) {
+ .header-layout-compact-left .header-branding-desktop {
+ width: 80px;
+ }
+ .header-layout-compact-left .header-branding-desktop img {
+ max-width: 80px;
+ }
+ .header-main-content {
+ padding: 0 20px;
+ }
+ .header-tools .checkout-link, .header-tools .customer-links, .header-tools .cart-count {
+ font-size: 12px;
+ }
+ .header-layout-compact-left .header-content-right {
+ width: 110px;
+ }
+}
+@media (max-width: 1260px) {
+ .navigation.navigation-desktop .navigation-menu>li>a, .navigation.navigation-desktop .navigation-menu summary {
+ padding: 17px 15px;
+ }
+}
+@media (max-width: 1260px) {
+ .navigation.navigation-desktop .navigation-menu>li>a, .navigation.navigation-desktop .navigation-menu summary {
+ padding: 17px 10px;
+ }
+ .navigation.navigation-desktop .has-dropdown>a:after, .navigation.navigation-desktop .has-dropdown summary:after, .navigation.navigation-desktop .has-mega-nav>a:after, .navigation.navigation-desktop .has-mega-nav summary:after {
+ right: 0;
+ }
+}
+@media (max-width: 1079px) {
+ .header-layout-compact-left .header-content-right {
+ width: auto;
+ margin-right: 35px;
+ }
+}
+/* Product description mobile */
+.product-content__mobile {
+ display: none;
+}
+@media (max-width: 769px) {
+ .product-content__mobile {
+ display: block;
+ }
+ .product-content__desktop {
+ display: none;
+ }
+ .dl-sample-btn {
+ margin-bottom: 10px;
+ }
+ .product-title {
+ font-size: 28px;
+ }
+ .block-buttonpdf .btn-pdf {
+ padding: 10px 15px !important;
+ }
+ .product-options {
+ margin-top: 10px;
+ }
+ .product-description {
+ margin-top: 0;
+ }
+ .cp-vendor-thumb {
+ justify-content: center;
+ align-items: center;
+ }
+ .cp-vendor-thumb-img {
+ max-width: 200px;
+ }
+ .block-buttonpdf .btn-pdf {
+ margin: auto !important;
+ }
+}
+/* End - New header */
+
+#bc-sf-filter-products .product-list-item-thumbnail {
+ display: block;
+ height: 0;
+ overflow: hidden;
+ position: relative;
+ z-index: 1;
+ background-size: cover;
+}
+.product-list-item-thumbnail {
+ display: block;
+ height: 0;
+ overflow: hidden;
+ position: relative;
+ z-index: 1;
+}
+#bc-sf-filter-products .product-list-item-thumbnail img {
+ bottom: 0;
+ display: block;
+ left: 0;
+ margin: auto;
+ position: absolute;
+ right: 0;
+ top: 0;
+}
+.product-list-item-thumbnail img {
+ bottom: 0;
+ display: block;
+ left: 0;
+ margin: auto;
+ position: absolute;
+ right: 0;
+ top: 0;
+}
+.addon-item {
+ padding: 30px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+@media screen and (max-width:767px) {
+ .addon-item {
+ flex-direction: column;
+ padding: 0px;
+ }
+}
+.addon-item .item-first {
+ display: flex;
+ align-items: center;
+}
+.addon-items .product-item-details {
+ padding: 0 30px 0 20px;
+ display: flex;
+ flex-direction: column;
+}
+.sticky-header a.visual-search-clickable {
+ display: none;
+}
+/* Hide this block temperally*/
+.pdfproductprint .block-buttonpdf button {
+ display: none !important;
+}
+.mini-cart-item-wrapper {
+ max-height: 360px;
+ overflow-y: auto;
+}
+.mini-cart-item-wrapper .mini-cart-item {
+ display: flex;
+ align-items: center;
+}
+.mini-cart-item.cart-subtotal {
+ flex-direction: column;
+}
+.subtotal-row {
+ width: 100%;
+}
+.product-add-to-cart .add-to-cart, .product-add-to-cart .shopify-payment-button__button, .dl-sample-btn, .dl-second-sample-btn, .dl-customize-btn, .dl-contact-btn {
+ width: 206px;
+ font-size: 12px !important;
+ border-radius: 99px;
+}
+.dl-sample-btn.dl-click-locked,
+.dl-second-sample-btn.dl-click-locked {
+ pointer-events: none;
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+@media screen and (max-width: 1024px) {
+ .product-add-to-cart .add-to-cart, .product-add-to-cart .shopify-payment-button__button, .dl-sample-btn, .dl-second-sample-btn, .dl-customize-btn, .dl-contact-btn {
+ width: 206px !important;
+ margin-left: auto;
+ margin-right: auto;
+ }
+}
+.mini-cart-item-price, .mini-cart-item .original-price, .mini-cart-item .cart-item-discounts {
+ display: none;
+}
+.mini-cart {
+ right: 0px;
+}
+.mini-cart-wrapper.is-open .mini-cart {
+ display: block;
+}
+.product-message.error-message {
+ width: 206px;
+ height: 45px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border: 1px solid;
+ border-radius: 99px;
+ margin-top: 10px;
+}
+.product-add-to-cart a {
+ margin-bottom: 10px;
+}
+.product-add-to-cart .add-to-cart,
+.product-add-to-cart a {
+ height: 45px;
+}
+.mini-cart-item .remove-item {
+ position: absolute;
+ top: 18px;
+ left: -25px;
+}
+.remove-item svg {
+ fill: #444;
+ width: 20px;
+}
+.product__form .hidden {
+ display: none !important;
+}
+.product-details-wrapper p {
+ margin-top: 0.5rem !important;
+ margin-bottom: 0.5rem !important;;
+}
+.add-to-cart.unavailable {
+ display: none !important;
+}
+.dl-second-sample-btn.unavailable {
+ display: none;
+}
+.showonly {
+ display: none;
+}
+/* ===============================================
+// Register Form Design
+// =============================================== */
+
+.register-form-card,
+.login-form-card {
+ max-width: 500px;
+ margin: 40px auto;
+ padding: 40px;
+ background: #ffffff;
+ border-radius: 8px;
+}
+.register-header,
+.login-header {
+ text-align: center;
+ margin-bottom: 30px;
+}
+.welcome-title,
+.login-title {
+ font-size: 24px;
+ font-weight: bold;
+ color: #333;
+ margin: 0 0 8px 0;
+ line-height: 1.2;
+}
+.welcome-subtitle {
+ font-size: 16px;
+ color: #666;
+ margin: 0;
+ line-height: 1.4;
+}
+.name-fields-row {
+ display: flex;
+ gap: 15px;
+ margin-bottom: 10px;
+}
+.name-field {
+ flex: 1;
+}
+.input-wrapper {
+ margin-bottom: 0;
+}
+.input-wrapper label {
+ display: block;
+ font-weight: bold;
+ color: #333;
+ margin-bottom: 8px;
+ font-size: 14px;
+}
+.input-wrapper input[type="text"],
+.input-wrapper input[type="email"],
+.input-wrapper input[type="password"],
+.input-wrapper select {
+ width: 100%;
+ padding: 12px;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ font-size: 14px;
+ background: #fff;
+ color: #666;
+ box-sizing: border-box;
+}
+.input-wrapper input[type="text"]:focus,
+.input-wrapper input[type="email"]:focus,
+.input-wrapper input[type="password"]:focus,
+.input-wrapper select:focus {
+ outline: none;
+ border-color: black;
+ color: white;
+}
+
+.input-wrapper input[type="submit"] {
+ width: 100%;
+ padding: 15px;
+ background: #4185f4;
+ color: #fff;
+ border: none;
+ border-radius: 4px;
+ font-size: 16px;
+ font-weight: bold;
+ text-transform: uppercase;
+ cursor: pointer;
+ transition: background-color 0.3s ease;
+}
+.input-wrapper input[type="submit"]:hover {
+ background: #3367d6;
+}
+/* OR separator between register form and social login */
+.or-separator {
+ position: relative;
+ text-align: center;
+ margin: 20px 0;
+}
+.or-separator::before {
+ content: "";
+ position: absolute;
+ top: 50%;
+ left: 0;
+ right: 0;
+ height: 1px;
+ background: #ddd;
+}
+.or-text {
+ background: white;
+ padding: 0 15px;
+ font-weight: bold;
+ color: #333;
+ position: relative;
+ z-index: 1;
+}
+/* Hide social login widget on register and login pages */
+/* .register-form-card .os_social_widget,
+.login-form-card .os_social_widget {
+ display: none !important;
+} */
+
+/* Mobile responsiveness */
+@media (max-width: 768px) {
+ .register-form-card,
+ .login-form-card {
+ margin: 20px;
+ padding: 30px 20px;
+ }
+
+ .name-fields-row {
+ flex-direction: column;
+ gap: 0;
+ }
+
+ .name-field {
+ margin-bottom: 20px;
+ }
+
+ .welcome-title,
+ .login-title {
+ font-size: 20px;
+ }
+
+ .welcome-subtitle {
+ font-size: 14px;
+ }
+
+ .keywords-desktop {
+ display: none !important;
+ }
+}
+/** More css custom cod **/
+.product-price-minimum.original {
+ text-decoration: line-through;
+ opacity: .8;
+ font-size: 1.1rem;
+}
+/* Base form control styles (missing from theme.css on some pages) */
+input[type="text"],
+input[type="email"],
+input[type="password"],
+input[type="search"],
+input[type="telephone"],
+input[type="tel"],
+input[type="number"],
+textarea,
+select {
+ font-family: Helvetica, Arial, sans-serif;
+ font-style: normal;
+ font-weight: 400;
+ display: block;
+ width: 100%;
+ max-width: 100%;
+ padding: 10px 12px;
+ font-size: 1rem;
+ box-sizing: border-box;
+ border-radius: 2px;
+ border: 1px solid rgba(0, 0, 0, 0.25);
+ color: inherit;
+ background: #fff;
+ -webkit-appearance: none;
+ appearance: none;
+}
+.boost-sd__in-collection-search {
+ display: none !important;
+}
+/* === Hide prices in You May Also Like / Product Recommendations === */
+.product-recommendations .product-list-item-price {
+ display: none !important;
+}
+
+/* DW Collections Page — full-width override (loads after theme.css) */
+.template-page .page-content > .dw-ex-header,
+.template-page .page-content > .dw-ex-section,
+.template-page .page-content > .dw-ex-grid,
+.template-page .page-content > .dw-ex-gc,
+.template-page .page-content > .dw-ex-section-title,
+.template-page .page-content > .dw-coll-wrap,
+.template-page .page-content > div[class*="dw-ex-"] {
+ max-width: 1500px !important;
+ margin-left: auto !important;
+ margin-right: auto !important;
+}
+.template-page .page-content > .dw-ex-grid {
+ max-width: 1500px !important;
+ padding-left: 24px !important;
+ padding-right: 24px !important;
+}
+
+/* ============================================
+ DW Compact Product Form — Size/Price/Qty
+ Added 2026-03-23 by ClawCoder session
+ ============================================ */
+.product-option-column-1 {
+ width: auto !important;
+ height: auto !important;
+ min-height: 0 !important;
+ margin-right: 4px !important;
+}
+.product-options {
+ display: flex !important;
+ flex-wrap: wrap !important;
+ align-items: center !important;
+ gap: 2px 0 !important;
+ margin: 4px 0 !important;
+}
+.product-options > label,
+.product-options > div.last_variant {
+ display: inline-flex !important;
+ align-items: center !important;
+ height: auto !important;
+ margin: 0 !important;
+}
+.last_variant .selected-text {
+ display: inline !important;
+ font-size: 14px !important;
+}
+.product__price {
+ margin: 2px 0 !important;
+}
+.product-sku-label,
+.product-sku-value {
+ margin-bottom: 2px !important;
+}
+.product-add-to-cart {
+ margin-top: 15px !important;
+}
+.block-buttonpdf {
+ margin-top: 10px !important;
+}
+label.product-option-row-4 {
+ height: auto !important;
+ width: auto !important;
+ margin-right: 4px !important;
+}
+.mm_quantity {
+ margin: 4px 0 !important;
+}
+/* Fix transparent PNG images showing black boxes in collection grids */
+.product-grid-image img,
+.product-image img,
+.product-card img,
+.collection-product-image img,
+.grid__image img,
+.product-grid-item img,
+.product_image img {
+ background-color: #fff !important;
+}
+.product-grid-image,
+.product-image,
+.product-card__image,
+.collection-product-image,
+.grid__image,
+.product-grid-item {
+ background-color: #fff !important;
+}
+
+/* Remove share buttons from product pages */
+.share-buttons,
+.product-share,
+.social-sharing,
+.product__social-sharing,
+.share-icons,
+[class*="share"],
+.product-social-sharing,
+.sharing {
+ display: none !important;
+}
+/* input.add-to-cart,
+input[type="submit"].add-to-cart,
+.product-add-to-cart input[type="submit"],
+.product-add-to-cart .add-to-cart {
+ background-color: #000 !important;
+ color: #fff !important;
+ border: none !important;
+ border-radius: 999px !important;
+ text-align: center !important;
+ font-weight: 500 !important;
+ font-size: 11px !important;
+ letter-spacing: 0.5px !important;
+ text-transform: uppercase !important;
+ padding: 10px 20px !important;
+ cursor: pointer !important;
+ display: inline-block !important;
+ vertical-align: middle !important;
+ line-height: 1 !important;
+ -webkit-appearance: none !important;
+ appearance: none !important;
+} */
+.block-buttonpdf button.btn-pdf {
+ background-color: #000 !important;
+ color: #fff !important;
+ border: none !important;
+ border-radius: 999px !important;
+ padding: 10px 20px !important;
+ font-size: 11px !important;
+ font-weight: 500 !important;
+ letter-spacing: 0.5px !important;
+ text-transform: uppercase !important;
+ font-family: inherit !important;
+ cursor: pointer !important;
+}
+.spec-sheet-btn:hover,
+.dl-sample-btn:hover,
+input.add-to-cart:hover,
+.block-buttonpdf button.btn-pdf:hover {
+ background-color: #333 !important;
+ color: white !important;
+}
+/* Match all product action buttons to the Add to Cart button */
+.product-add-to-cart .add-to-cart,
+.product-add-to-cart .shopify-payment-button__button,
+.product-form--atc .action_button,
+.dl-sample-btn,
+.dl-second-sample-btn,
+.spec-sheet-btn {
+ display: inline-flex !important;
+ align-items: center !important;
+ justify-content: center !important;
+ width: 206px !important;
+ min-height: 45px !important;
+ padding: 10px 20px !important;
+ border-radius: 999px !important;
+ box-sizing: border-box !important;
+ font-size: 12px !important;
+ font-weight: 500 !important;
+ letter-spacing: 0.5px !important;
+ line-height: 1 !important;
+ text-align: center !important;
+ text-transform: uppercase !important;
+ text-decoration: none !important;
+}
+
+/* Force prices visible on product pages — overrides Boost transparent color */
+.product-price .money,
+.product-price-minimum.money,
+.product-price-discount.money,
+.product__price .money,
+.product__price span,
+#shopify-section-template--18587140849715__main .money,
+[id*="__main"] .product-price span,
+[id*="__main"] .money {
+ color: inherit !important;
+ opacity: 1 !important;
+ visibility: visible !important;
+}
+/* === Product grid card descriptions === */
+.product-list-item-description {
+ font-size: 12px;
+ line-height: 1.45;
+ color: #666;
+ margin: 3px 0 6px;
+ overflow: hidden;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+}
+/* === Grid Density Slider Control === */
+.collection-grid-controls {
+ display: flex;
+ align-items: center;
+ gap: 16px;
+ margin: 20px 0;
+ padding: 12px 16px;
+ background: #f9f9f9;
+ border-radius: 4px;
+ flex-wrap: wrap;
+}
+.collection-grid-controls label {
+ font-size: 13px;
+ font-weight: 500;
+ color: #666;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ white-space: nowrap;
+}
+.collection-grid-controls-slider {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ flex: 1;
+ min-width: 200px;
+}
+.collection-grid-controls-slider input[type="range"] {
+ flex: 1;
+ min-width: 120px;
+ height: 6px;
+ border-radius: 3px;
+ background: #ddd;
+ outline: none;
+ -webkit-appearance: none;
+ appearance: none;
+}
+.collection-grid-controls-slider input[type="range"]::-webkit-slider-thumb {
+ -webkit-appearance: none;
+ appearance: none;
+ width: 18px;
+ height: 18px;
+ border-radius: 50%;
+ background: #111;
+ cursor: pointer;
+ box-shadow: 0 1px 3px rgba(0,0,0,0.2);
+}
+.collection-grid-controls-slider input[type="range"]::-moz-range-thumb {
+ width: 18px;
+ height: 18px;
+ border-radius: 50%;
+ background: #111;
+ cursor: pointer;
+ border: none;
+ box-shadow: 0 1px 3px rgba(0,0,0,0.2);
+}
+.collection-grid-density-value {
+ min-width: 45px;
+ text-align: center;
+ font-weight: 600;
+ color: #111;
+ font-size: 14px;
+}
+/* DW-RESPONSIVE-GRID (desktop 4 / tablet 3 / mobile 2); JS slider overrides */
+.collection-products{--grid-columns:2;display:grid !important;grid-template-columns:repeat(var(--grid-columns),1fr) !important;gap:16px !important;}
+@media (min-width:481px){.collection-products{--grid-columns:3;}}
+@media (min-width:769px){.collection-products{--grid-columns:4;}}
+
+
+/* Responsive: reduce max columns on mobile */
+@media (max-width: 768px) {
+ .collection-grid-controls {
+ flex-direction: column;
+ align-items: flex-start;
+ }
+
+ .collection-grid-controls-slider {
+ width: 100%;
+ }
+
+ .collection-products {
+ --grid-columns: 2 !important;
+ }
+}
+}
+
+/* === Collection Cards: Image only, no text === */
+.product-list-item {
+ cursor: pointer;
+}
+
+.product-list-item-details {
+ display: none !important;
+}
+
+.product-list-item-overlay {
+ display: none !important;
+}
+
+.product-list-item-thumbnail {
+ transition: opacity 0.2s ease, transform 0.2s ease;
+}
+
+.product-list-item:hover .product-list-item-thumbnail {
+ opacity: 0.9;
+ transform: scale(1.02);
+}
+
+/* Hide Boost Commerce hover overlays on collection cards */
+.dw-hover-label {
+ display: none !important;
+}
+
+.boost-sd__product-item-image-overlay {
+ display: none !important;
+}
+
+/* === Collection Card Hover Overlay: Vendor + Pattern Name === */
+.product-list-item-hover-overlay {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: rgba(0, 0, 0, 0);
+ transition: background 0.25s ease;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 10;
+}
+
+.product-list-item:hover .product-list-item-hover-overlay {
+ background: rgba(0, 0, 0, 0.75);
+}
+
+.product-list-item-hover-content {
+ opacity: 0;
+ transition: opacity 0.25s ease;
+ text-align: center;
+ color: white;
+ padding: 20px;
+ pointer-events: none;
+}
+
+.product-list-item:hover .product-list-item-hover-content {
+ opacity: 1;
+}
+
+.product-list-item-hover-vendor {
+ font-size: 11px;
+ font-weight: 500;
+ text-transform: uppercase;
+ letter-spacing: 0.12em;
+ color: #aaa;
+ margin: 0 0 8px;
+ line-height: 1.2;
+}
+
+.product-list-item-hover-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #fff;
+ margin: 0;
+ line-height: 1.4;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
+}
+
+.product-list-item-hover-title a {
+ color: inherit;
+ text-decoration: none;
+}
+
+/* Ensure no text below images */
+.product-list-item-details {
+ display: none !important;
+}
+
+/* Hide any secondary labels */
+.dw-hover-label {
+ display: none !important;
+}
+
+/* Compact spacing: reduce gaps between rows */
+.collection-products {
+ gap: 8px !important;
+ row-gap: 4px !important;
+}
+
+/* Reduce item margins/padding */
+.product-list-item {
+ margin: 0 !important;
+ padding: 0 !important;
+}
+
+.product-list-item-thumbnail {
+ margin: 0 !important;
+}
+
+/* Product card = image ONLY, zero space below */
+.product-list-item {
+ display: flex;
+ flex-direction: column;
+}
+
+.product-list-item-thumbnail {
+ flex: 1;
+ width: 100%;
+}
+
+.product-list-item-details {
+ display: none !important;
+ height: 0 !important;
+ margin: 0 !important;
+ padding: 0 !important;
+ overflow: hidden !important;
+}
+
+/* Article takes only image space */
+.product-list-item article {
+ display: contents;
+}
+
+.product-list-item {
+ overflow: hidden;
+}
+
+/* Ultra-tight grid spacing */
+.collection-products {
+ gap: 2px !important;
+ row-gap: 2px !important;
+}
+
+/* >>> dw-collection-grid-fix START >>> */
+/* =====================================================================
+ DW collection + homepage "huge images" fix (dw-collection-grid-fix.css)
+ Owner: vp-dw-commerce · 2026-06-23
+ Corrected root cause (measured in-browser at 1440 + 390):
+ - COLLECTION: stale Boost server-rendered theme fallback markup
+ (.boost-sd__product-filter-fallback > section.collection + loose
+ article.product-list-item) stays visible AFTER Boost hydrates, stacking
+ full-width theme cards below the real grid. The GOOD hydrated grid lives
+ under .boost-sd-container (NOT in .product-list-item), so we can hide the
+ stale theme branch without touching the live Boost grid.
+ - HOMEPAGE: featured-collection .product-list-item cards that grid.js failed
+ to lay into .home-products-content are orphaned onto .main-content/<body>
+ and render at full 1440px. We CONSTRAIN them into a responsive grid (never
+ hide — they are real products) so they degrade gracefully even if grid.js
+ init still partially fails. The grid.js init-abort fix remains the primary
+ mechanism; this is the defensive net (DTD verdict A, 3/3, 2026-06-23).
+ Scoped to body.boost-sd__search-widget-init-enabled for the collection rules
+ so the pre-hydration server fallback still shows (no flash of empty grid).
+ ===================================================================== */
+
+/* ---- (A) COLLECTION: suppress stale Boost theme fallback after hydration ---- */
+body.boost-sd__search-widget-init-enabled .boost-sd__product-filter-fallback > section.collection,
+body.boost-sd__search-widget-init-enabled .boost-sd__product-filter-fallback > article.product-list-item,
+body.boost-sd__search-widget-init-enabled .boost-sd__product-filter-fallback > .shopify-section:not(:has(.boost-sd-container)) {
+ display: none !important;
+}
+
+/* Safety net for the collection page: a theme-native .product-list-item that is
+ NOT part of the live Boost app grid and NOT inside a real CSS-grid wrapper is
+ stale fallback — hide it (collection context only). */
+body.template-collection.boost-sd__search-widget-init-enabled
+ .boost-sd__product-filter-fallback
+ article.product-list-item {
+ display: none !important;
+}
+/* but keep the live Boost grid's own items visible */
+body.template-collection.boost-sd__search-widget-init-enabled
+ .boost-sd-container article.product-list-item {
+ display: revert !important;
+}
+/* Also catch the loose stale cards that sit directly under .main-content /
+ <body> on the collection template (orphaned by the same fallback dump) — the
+ live Boost products are inside .boost-sd-container, never here. */
+body.template-collection.boost-sd__search-widget-init-enabled > article.product-list-item,
+body.template-collection.boost-sd__search-widget-init-enabled .main-content > article.product-list-item,
+body.template-collection.boost-sd__search-widget-init-enabled section.collection article.product-list-item {
+ display: none !important;
+}
+
+/* ---- (B) HOMEPAGE: constrain featured-collection cards into a grid ---- */
+/* Force the featured-collection section to a responsive grid so even orphaned
+ cards (attached at section/.main-content/body level) get a column width. */
+body.template-index section.home-products {
+ display: grid !important;
+ grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
+ gap: 1.5rem;
+ align-items: start;
+}
+body.template-index section.home-products .home-products-content {
+ display: contents; /* let inner cards participate in the section grid */
+}
+/* Hard clamp: ANY featured-collection product card can never exceed its column,
+ and a stray orphaned card (e.g. one that escaped onto .main-content/body) is
+ width-capped so it can never render full-bleed. */
+body.template-index .product-list-item {
+ max-width: 360px !important;
+ width: 100% !important;
+}
+/* The card image follows the card width and lazy-loads. */
+body.template-index .product-list-item img {
+ width: 100% !important;
+ height: auto !important;
+ max-width: 100% !important;
+}
+
+/* ---- (C) Global belt: orphaned cards attached directly to body/.main-content
+ on ANY template can never be full-bleed (defensive, harmless to real grids
+ because real grid cards are already < this cap). ---- */
+body > .product-list-item,
+.main-content > .product-list-item {
+ max-width: 360px !important;
+}
+
+/* <<< dw-collection-grid-fix END <<< */
+
+/* >>> dw-collection-hero-fix START >>> */
+/* ====================================================================
+ DW COLLECTION HERO + DUP-TITLE + MOBILE-HEADER FIX
+ Owner: vp-dw-commerce · 2026-06-23 · DTD verdict F1=B / F2=A / F3=A
+ Appended (marked + idempotent) to a theme-controlled CSS asset.
+ Pairs with snippet 'dw-collection-hero-bg' (emits the per-collection
+ background-image inline) for the F1=B always-on hero.
+ Removable: delete everything between the START/END markers.
+ ==================================================================== */
+
+/* --- F2: kill the duplicate theme leftover title on collection pages.
+ Boost's h1.boost-sd__header-title is the live header (carries image +
+ description); the OOTS theme h1.page-title is a pre-Boost leftover that
+ stacks the same text. Hide the theme one ONLY on collection templates. --- */
+body.template-collection .collection > div > .page-title,
+body.template-collection section.collection .collection-header-content > .page-title,
+body.template-collection .boost-sd__product-filter-fallback .page-title {
+ display: none !important;
+}
+
+/* --- F1: the collection hero band.
+ .dw-collection-hero is a wrapper the snippet emits around the Boost header
+ (or, pre-hydration, the theme header). It always shows a background:
+ collection.image when set, else settings.collection_default_hero, else a
+ soft branded gradient. The title pill stays white-on-image ONLY when a real
+ image is behind it; with no image the title is clean centered dark type on
+ the soft band (no naked dark pill, no flat grey dead-block). --- */
+
+.dw-collection-hero {
+ position: relative;
+ width: 100%;
+ min-height: 220px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ text-align: center;
+ /* default soft branded band when no image var is set */
+ background:
+ linear-gradient(180deg, rgba(0,0,0,0.04), rgba(0,0,0,0.02)),
+ #f4f2ee;
+ background-size: cover;
+ background-position: center;
+ overflow: hidden;
+ margin-bottom: 8px;
+}
+
+/* When the snippet sets --dw-hero-img, paint it as a real cover background
+ with a legibility scrim so the white pill reads. */
+.dw-collection-hero[style*="--dw-hero-img"] {
+ background-image:
+ linear-gradient(180deg, rgba(0,0,0,0.18), rgba(0,0,0,0.34)),
+ var(--dw-hero-img);
+ background-size: cover;
+ background-position: center;
+}
+
+/* The Boost (and theme) header title, hoisted into the hero band.
+ IMAGE PRESENT: keep white text + dark pill (legible over photo). */
+.dw-collection-hero.dw-has-image .boost-sd__header-title,
+.dw-collection-hero.dw-has-image .page-title {
+ color: #fff !important;
+ background: rgba(0,0,0,0.42) !important;
+ border-radius: 4px !important;
+ padding: 12px 28px !important;
+ display: inline-block !important;
+ text-shadow: 0 1px 18px rgba(0,0,0,0.45);
+}
+
+/* NO IMAGE: clean centered dark type, NO pill, NO grey block. */
+.dw-collection-hero:not(.dw-has-image) .boost-sd__header-title,
+.dw-collection-hero:not(.dw-has-image) .page-title {
+ color: #1a1a1a !important;
+ background: transparent !important;
+ border-radius: 0 !important;
+ padding: 0 !important;
+ text-shadow: none !important;
+ letter-spacing: .14em;
+ text-transform: uppercase;
+ font-weight: 300;
+}
+
+/* Belt-and-suspenders: neutralize Boost's default dark pill whenever the
+ collection has NO hero. "No hero" = the snippet did NOT add .dw-has-hero
+ (set only when collection.image OR settings.collection_default_hero exists)
+ AND Boost rendered no native image-inner. Excludes .dw-has-hero so the
+ image case (painted by the snippet's inline <style>) is never stripped. */
+body:not(.dw-collection-has-hero) .boost-sd__collection-header:not(:has(.boost-sd__header-image-inner)) .boost-sd__header-title {
+ background: transparent !important;
+ color: #1a1a1a !important;
+ border-radius: 0 !important;
+ padding: 14px 0 !important;
+ text-shadow: none !important;
+ letter-spacing: .14em;
+ text-transform: uppercase;
+ font-weight: 300;
+}
+body:not(.dw-collection-has-hero) .boost-sd__collection-header:not(:has(.boost-sd__header-image-inner)) {
+ background: #f4f2ee;
+ min-height: 200px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ text-align: center;
+}
+
+/* keep the description readable inside the band */
+.dw-collection-hero .boost-sd__header-description,
+.dw-collection-hero .collection-description { margin-top: 10px; }
+.dw-collection-hero.dw-has-image .boost-sd__header-description,
+.dw-collection-hero.dw-has-image .boost-sd__header-description * { color: rgba(255,255,255,.92) !important; }
+
+/* --- F3: mobile header gap.
+ theme.css mobile media query gives .header-branding{padding:36px 0}, making a
+ 118px logo block with a big empty gap, while the CART(0) tools bar floats
+ 42px above. Tighten both so the logo sits up near the cart. Surgical +
+ reversible — only at mobile widths. --- */
+@media (max-width: 768px) {
+ .header-branding { padding: 14px 0 !important; }
+ /* trim the standalone tools bar so cart isn't marooned at the top */
+ .header-tools-wrapper { padding-top: 4px !important; padding-bottom: 0 !important; }
+ .header-tools { padding-top: 0 !important; padding-bottom: 0 !important; }
+ /* pull the logo+icons row up closer to the cart row */
+ .header-main-content { padding-top: 4px !important; }
+}
+
+/* <<< dw-collection-hero-fix END <<< */
diff --git a/shopify/collection-hero-fix/backups/assets_custom.css.live-142250278963.pushbak b/shopify/collection-hero-fix/backups/assets_custom.css.live-142250278963.pushbak
new file mode 100644
index 00000000..ca390dd2
--- /dev/null
+++ b/shopify/collection-hero-fix/backups/assets_custom.css.live-142250278963.pushbak
@@ -0,0 +1,1488 @@
+/* Global font override — system sans-serif site-wide (matches product title/SKU) */
+body,html,h1,h2,h3,h4,h5,h6,p,a,span,div,li,td,th,label,input,select,textarea,button,.breadcrumbs,.breadcrumbs a,.breadcrumbs span,.main-content,.page-content,.page-title,.collection-title,.product-title,.product-vendor,.product-price,.product-description,.rte,.rte p,.rte li,.rte a,.rte span,.footer,.site-header,.navigation,.nav-link,.menu-link,.announcement-bar,.toolbar,.search-form,.search-results,.collection-grid,.product-grid,.product-list,.sidebar,.widget,.cart,.mini-cart,.shopify-section,.upper-footer,.upper-footer-item,.footer-blurb,.footer-blurb p,.footer-blurb a,.footer-linklist,.footer-linklist a,.footer-linklist li,.sub-footer-right,.sub-footer__row,.subfooter__payment-types,[class*=footer],[class*=footer] a,[class*=footer] p,[class*=footer] li,[class*=footer] span,[class*=footer] h1,[class*=footer] h2,[class*=footer] h3,[class*=footer] h4{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif!important}
+
+/* Override theme heading font (Lora serif → system sans-serif) */
+.quick-shop-modal-trigger,.product-list-item-inventory,.mega-nav-list .mega-nav-list-title .mega-nav-list-title-link,.navigation.navigation-desktop .mega-nav-list .mega-nav-list-title-link,.product-title,.home-masonry-feature-title,th,.section-title,.page-title,.shopify-policy__title h1,.shopify-policy__title .age-gate__heading,h1,.age-gate__heading,h2,h3,h4,h5,h6,.home-slideshow-slide-heading,.home-promotion-title,.collection-title,.mega-nav-list-title-link,.home-promo-grid-item-heading,.promo-grid__text,.toolbar__title,.sidebar__title{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif!important}
+.header-search-inline {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ flex-wrap: nowrap;
+}
+.header-search-inline .search-form {
+ margin: 0;
+}
+.header-search-inline__visual {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 30px;
+ height: 30px;
+ color: inherit;
+}
+.header-search-inline__visual svg {
+ width: 20px;
+ height: 20px;
+ display: block;
+}
+@media (max-width: 1079px) {
+ .header-content-right--inline-search {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ width: auto;
+ }
+}
+.product-list-item-thumbnail {
+ height: 0;
+ padding-bottom: 100%;
+ overflow: hidden;
+}
+.product-list-item-thumbnail > a {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ display: block;
+}
+.product-list-item-thumbnail img,
+.product-list-item-thumbnail svg {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+.product-info .vertical-center {
+ position: absolute;
+ top: 50%;
+ width: 100%;
+ transform: translateY(-50%);
+}
+.product-list-item > figure:hover .product-info,
+.product-grid-masonry-sizer > figure:hover .product-info {
+ opacity: 0.578159;
+}
+.product-info {
+ width: 100%;
+ height: 100%;
+ background-color: #fff;
+ opacity: 0;
+ transition: all 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94);
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ padding: 12px;
+ font-size: 1.07143rem;
+ text-align: center;
+ z-index: 1;
+ transform: translate(-50%) translateY(-50%);
+ color: #000;
+}
+.product-price-discount {
+ font-size: 0.9em;
+ line-height: 1.2;
+}
+
+/* ==========================================================================
+ Original custom css here
+ ========================================================================== */
+
+/* ===============================================
+// Hover Effect CSS
+// =============================================== */
+
+.hover-effect .hidden { display: block !important; visibility: visible !important;}
+.product:hover .hover-effect img { opacity: 1; }
+.hover-effect .hidden {
+position: absolute;
+z-index: -1;
+top: 0;
+width: 100%;
+height: 100%;
+opacity: 0;
+-webkit-transition: opacity 0.3s ease-in-out;
+-moz-transition: opacity 0.3s ease-in-out;
+-o-transition: opacity 0.3s ease-in-out;
+transition: opacity 0.3s ease-in-out;
+}
+.hover-effect:hover .hidden {
+z-index: 100000;
+opacity: 1;
+}
+.hover-effect .caption {
+position: absolute;
+top: 0;
+display: table;
+width: 100%;
+height: 100%;
+background-color: white; /* fallback for IE8 */
+background-color: rgba(255, 255, 255, 0.7);
+text-align: center;
+text-rendering: optimizeLegibility;
+}
+.hover-effect .hidden .caption .centered {
+display: table-cell;
+vertical-align: middle;
+}
+/* ===============================================
+// Reveal module
+// =============================================== */
+
+.reveal .hidden { display: block !important; visibility: visible !important;}
+.product:hover .reveal img { opacity: 1; }
+.reveal { position: relative; }
+.reveal .hidden {
+ position: absolute;
+ z-index: -1;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ opacity: 0;
+ -webkit-transition: opacity 0.3s ease-in-out;
+ -moz-transition: opacity 0.3s ease-in-out;
+ -o-transition: opacity 0.3s ease-in-out;
+ transition: opacity 0.3s ease-in-out;
+}
+.reveal:hover .hidden {
+ z-index: 100000;
+ opacity: 1;
+}
+.reveal .caption {
+ position: absolute;
+ top: 0;
+ display: table;
+ width: 100%;
+ height: 100%;
+ background-color: white; /* fallback for IE8 */
+ background-color: rgba(255, 255, 255, 0.7);
+ font: 13px/1.6 sans-serif;
+ text-transform: uppercase;
+ color: #333;
+ letter-spacing: 1px;
+ text-align: center;
+ text-rendering: optimizeLegibility;
+}
+.reveal .hidden .caption .centered {
+ display: table-cell;
+ vertical-align: middle;
+}
+@media (min-width: 480px) and (max-width: 979px) {
+ .reveal .caption {
+ font-size: 11px;
+ }
+}
+div#content {
+ width: 100%;
+ max-width: 1050px;
+ margin-left: auto;
+ margin-right: auto;
+}
+/*==================== 020 css for prod Quantity ============================*/
+
+.mm_quantity {
+ display: inline-block; }
+
+.mm_quantity .input-text.qty {
+ width: 40px;
+ height: 42px;
+ padding: 0 5px;
+ text-align: center;
+ background-color: transparent;
+ border: 1px solid #efefef;
+}
+.mm_quantity.mm_buttons_added {
+ text-align: left;
+ position: relative;
+ white-space: nowrap;
+ vertical-align: top;
+}
+.mm_quantity.mm_buttons_added input {
+ display: inline-block;
+ margin: 0;
+ vertical-align: top;
+ box-shadow: none;
+}
+.mm_quantity.mm_buttons_added .minus,
+.mm_quantity.mm_buttons_added .plus {
+ padding: 7px 10px 8px;
+ height: 42px;
+ background-color: #ffffff;
+ border: 1px solid #efefef;
+ cursor:pointer;
+ color:#000000;
+}
+.mm_quantity.mm_buttons_added .minus {
+ border-right: 0;
+}
+.mm_quantity.mm_buttons_added .plus {
+ border-left: 0;
+ margin-left: 1px;
+}
+.mm_quantity.mm_buttons_added .minus:hover,
+.mm_quantity.mm_buttons_added .plus:hover {
+ background: #eeeeee;
+}
+.mm_quantity input::-webkit-outer-spin-button,
+.mm_quantity input::-webkit-inner-spin-button {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ margin: 0;
+}
+.mm_quantity.mm_buttons_added .minus:focus,
+.mm_quantity.mm_buttons_added .plus:focus {
+ outline: none;
+}
+/*--------*/
+.shopify-product-form .product-options label {
+ text-transform: uppercase;
+ font-weight: bold;
+ font-size: 14px;
+ font-family: "Times New Roman", Times, serif;
+}
+/* Product option labels: vertically center with selects */
+.shopify-product-form .product-options label.product-option-column-1 {
+ display: flex;
+ align-items: center;
+ align-self: center;
+}
+.shopify-product-form .product-options label.product-option-column-1 strong {
+ line-height: 1.1;
+}
+/* Ensure the control column centers within the grid row too */
+.shopify-product-form .product-options .product-option-column-1 + * {
+ align-self: center;
+}
+/* Product options layout: center items + add row spacing (desktop grid) */
+body.template-product .shopify-product-form .product-options {
+ align-items: center;
+ row-gap: 3px;
+ column-gap: 14px;
+}
+body.template-product .shopify-product-form .product-options .product-option-column-1,
+body.template-product .shopify-product-form .product-options .product-option-column-1 + *,
+body.template-product .shopify-product-form .product-options .select-wrapper,
+body.template-product .shopify-product-form .product-options .last_variant {
+ margin: 0 !important;
+ align-self: center;
+}
+body.template-product .shopify-product-form .product-options label.product-option-column-1 {
+ min-height: 44px;
+}
+.mm_quantity {
+ margin-top: 10px !important;
+}
+
+@media only screen and (max-width: 769px) {
+ body.template-product .shopify-product-form .product-options {
+ display: grid;
+ grid-template-columns: max-content 1fr;
+ column-gap: 12px;
+ align-items: center;
+ width: 100%;
+ max-width: 100%;
+ }
+
+ body.template-product .shopify-product-form .product-options label.product-option-column-1 {
+ min-height: auto;
+ justify-content: flex-start;
+ grid-column: 1;
+ }
+
+ body.template-product .shopify-product-form .product-options select.single-option-selector,
+ body.template-product .shopify-product-form .product-options .last_variant,
+ body.template-product .shopify-product-form .product-options .mm_quantity {
+ grid-column: 2;
+ width: 100%;
+ }
+
+ body.template-product .shopify-product-form .product-options select.single-option-selector {
+ min-width: 0;
+ box-sizing: border-box;
+ height: 44px;
+ line-height: 44px;
+ padding-right: 28px;
+ }
+
+ body.template-product .shopify-product-form .product-options .product-option-row-1 { grid-row: 1; }
+ body.template-product .shopify-product-form .product-options .product-option-row-2 { grid-row: 2; }
+ body.template-product .shopify-product-form .product-options .product-option-row-3 { grid-row: 3; }
+ body.template-product .shopify-product-form .product-options .product-option-row-4 { grid-row: 4; }
+ body.template-product .shopify-product-form .product-options .product-option-row-5 { grid-row: 5; }
+ body.template-product .shopify-product-form .product-options .product-option-row-6 { grid-row: 6; }
+ body.template-product .shopify-product-form .product-options .product-option-row-7 { grid-row: 7; }
+ body.template-product .shopify-product-form .product-options .product-option-row-8 { grid-row: 8; }
+}
+#studioengine{
+ display: inline-block;
+ margin: 0;
+ padding: 0;
+ width: 100vw;
+ height: 100%;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ margin: 0 auto;
+ max-width: 100%;
+}
+#studioeditor {
+ display: inline-block;
+ margin: 0;
+ padding: 0;
+ width: 100vw;
+ height: 100%;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ margin: 0 auto;
+ max-width: 100%;
+}
+
+
+
+/*020*/
+
+
+.shopify-product-form .product-add-to-cart{
+ display: block;
+}
+
+/*============*/
+
+/*hide variant ddl from dropdown*/
+
+.last_variant{
+ font-family: "Open Sans",sans-serif!important;
+ font-style: normal!important;
+ font-weight: 400!important;
+ color: #333!important;
+ font-size: 14px!important;
+ line-height: 1.625!important;
+ font-weight: normal!important;
+ text-transform: capitalize!important;
+
+ position: relative;
+ top: -1px;
+}
+@media only screen and (max-width: 769px) {
+ .last_variant{
+ width: 100%;
+ display: inline-block;
+
+ }
+}
+
+/* SC start 009 */
+#custom-popup-overlay{
+ position: fixed;
+ display: none;
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0,0,0,0.5);
+ z-index: 99999;
+}
+#custom-popup-overlay .custom-popup-main{
+ margin: 80px auto;
+ padding: 20px;
+ background: #fff;
+ border-radius: 5px;
+ width: 30%;
+ position: relative;
+ transition: all 5s ease-in-out;
+ z-index: 9999;
+}
+#custom-popup-overlay .custom-popup-main .custom-close {
+ position: absolute;
+ top: 10px;
+ right: 20px;
+ transition: all 200ms;
+ font-size: 30px;
+ font-weight: bold;
+ text-decoration: none;
+ color: #333;
+ cursor:pointer;
+}
+#custom-popup-overlay .custom-popup-main .custom-close:hover {
+ color: #06D85F;
+}
+#custom-popup-overlay .custom-popup-main .content-main {
+ max-height: 30%;
+ overflow: auto;
+}
+#custom-popup-overlay .site-logo-in-popup{
+ text-align:center;
+ margin-top:25px;
+}
+#custom-popup-overlay .popup-content{
+ padding-top:30px;
+ text-align:center;
+}
+#custom-popup-overlay .site-logo-in-popup img{ width: 130px; }
+
+#custom-popup-overlay #contact_form{
+ padding:0px 5px;
+}
+/* Popup contact form: match intended full-width field styling */
+#custom-popup-overlay .custom-popup-main{
+ width: min(640px, calc(100% - 32px));
+ max-width: 640px;
+ padding: 40px 40px 30px;
+}
+#custom-popup-overlay .popup-content{
+ text-align: left;
+ padding-top: 20px;
+}
+#custom-popup-overlay .popup-content h2{
+ text-align: center;
+ margin: 0 0 22px;
+}
+#custom-popup-overlay .popup-content form{
+ width: 100%;
+}
+#custom-popup-overlay .field-wrap{
+ width: 100%;
+ margin: 0 0 14px;
+}
+#custom-popup-overlay .field-wrap input,
+#custom-popup-overlay .field-wrap textarea{
+ width: 100%;
+ display: block;
+ box-sizing: border-box;
+ padding: 12px 14px;
+ border: 1px solid #d9d9d9;
+ border-radius: 2px;
+ font-family: inherit;
+ font-size: 16px;
+}
+#custom-popup-overlay .field-wrap textarea{
+ min-height: 150px;
+ resize: vertical;
+}
+#custom-popup-overlay input[type="submit"]{
+ display: block;
+ width: fit-content;
+ min-width: 140px;
+ margin: 18px auto 0;
+ padding: 12px 22px;
+}
+
+@media screen and (max-width: 1100px) {
+ #custom-popup-overlay .custom-popup-main{
+ width: min(640px, calc(100% - 32px));
+ }
+}
+@media screen and (max-width: 1024px) {
+ .product-add-to-cart .add-to-cart{
+ width: 100% !important;
+ max-width:inherit !important;
+ }
+}
+@media screen and (max-width: 600px) {
+ .custom-popup-main .popup-content h2{
+ font-size:1.2rem;
+ }
+
+ #custom-popup-overlay .custom-popup-main{
+ margin: 20px auto;
+ padding: 26px 18px 20px;
+ }
+
+ #custom-popup-overlay .custom-popup-main textarea{
+ min-height:100px;
+ }
+}
+/* SC end 009 */
+
+.block-buttonpdf {
+ margin-top: 25px;
+}
+@media (min-width: 1024px) {
+ .template-search .main-content {
+ max-width: 1600px;
+ }
+
+ .template-search .section-search > .search-results-wrapper {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-around;
+ }
+
+ .template-search .section-search > .search-results-wrapper .search-results-count {
+ flex-basis: 100%;
+ }
+
+ #bc-sf-filter-wrapper {
+ flex-basis: 75%;
+ }
+
+ .template-search .section-search > .search-results-wrapper .search-results-wrapper {
+ flex-basis: 20%;
+ border-left: 1px solid #ccc;
+ }
+
+ #bc-sf-filter-right {
+ width: calc(100% - 237px);
+ }
+}
+.product-options #calculator .element,
+.product-options #calculator .price-marker {
+ padding-left: 0;
+ display: flex;
+ align-items: center;
+}
+.product-options #calculator .element label,
+.product-options #calculator .price-marker > label {
+ font-weight: bold;
+ font-size: 14px !important;
+ font-family: "Times New Roman", Times, serif;
+ /* margin-bottom: 10px !important; */
+ text-transform: uppercase;
+ min-width: 110px;
+ text-align: left;
+}
+.product-options #calculator .element input[type="number"],
+.product-options #calculator .element .formula-block label {
+ font-family: "Open Sans", sans-serif;
+ font-style: normal;
+ color: #333333;
+ font-size: 14px !important;
+ padding-left: 10px;
+}
+.product-options #calculator .price-marker span label {
+ color: #444;
+ font-family: Lora, serif;
+ font-size: 1.28571rem !important;
+ font-weight: 400 !important;
+}
+.product-options #calculator .price-marker span {
+ font-family: Lora, serif;
+ font-size: 1.28571rem !important;
+ font-weight: 400 !important;
+}
+.product-options #calculator .element .formula-block {
+ margin: 0;
+}
+.collection-header {
+ text-align: center;
+}
+.dl-customize-btn, .dl-contact-btn, .dl-sample-btn, .dl-second-sample-btn, .button, .submit, input[type=submit], input[type=button], .pxs-newsletter-form-button, .pxs-image-with-text-button {
+ font-family: Lora,serif;
+ font-style: normal;
+ font-weight: 700;
+ background: black;
+ color: #fff;
+ display: inline-block;
+ text-align: center;
+ line-height: normal;
+ padding: 15px 20px;
+ border-radius: 2px;
+ text-transform: uppercase;
+ font-size: .92857rem;
+}
+/* Hide Contact Us button on product pages */
+body.template-product .dl-contact-btn {
+ display: none !important;
+}
+.home-slideshow-slide-heading {
+ text-shadow: 0px 0px 2px #000, 2px 1px 1px #000, 3px 2px 1px #000, 4px 3px 1px #000, 5px 4px 1px #000;
+ font-size: 3.5em;
+}
+.home-slideshow-slide-subheading {
+ text-shadow: 0px 0px 1px #000, 1px 1px 1px #000, 2px 2px 1px #000;
+ font-weight: 500;
+ font-size: 2em;
+}
+@media (max-width: 769px) {
+ .home-slideshow-slide-heading {
+ color: #000!important;
+ font-size: clamp(1.75rem, 6vw, 2.4rem);
+ line-height: 1.1;
+ text-shadow: 0px 0px 0px #ffffff;
+ }
+ .home-slideshow-slide-subheading {
+ color: #8a8a8a!important;
+ font-size: clamp(1rem, 4.2vw, 1.4rem);
+ line-height: 1.2;
+ text-shadow: 0px 0px 0px #ffffff;
+ font-weight: 400;
+ }
+}
+/* New header */
+.header-layout-compact-left .header-branding-desktop img {
+ max-width: 100px;
+}
+.header-main-content {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+@media (min-width: 1080px) {
+ .header-layout-compact-left .header-branding-desktop {
+ width: 150px;
+ text-align: center;
+ }
+ .sticky-header .header-content-right {
+ display: table-cell;
+ vertical-align: middle;
+ }
+}
+@media (max-width: 1672px) {
+ .navigation.navigation-desktop .navigation-menu > li > a, .navigation.navigation-desktop .navigation-menu summary {
+ padding: 17px 25px;
+ font-size: 14px;
+ }
+ .navigation.navigation-desktop .has-dropdown>a:after, .navigation.navigation-desktop .has-dropdown summary:after, .navigation.navigation-desktop .has-mega-nav>a:after, .navigation.navigation-desktop .has-mega-nav summary:after {
+ right: 5px;
+ }
+}
+@media (max-width: 1525px) {
+ .header-layout-compact-left .header-branding-desktop {
+ width: 100px;
+ }
+ .navigation.navigation-desktop .navigation-menu > li >a, .navigation.navigation-desktop .navigation-menu summary {
+ padding: 17px 20px;
+ }
+ .header-layout-compact-left .navigation-wrapper,
+ .sticky-header .header-layout-compact-left .navigation-wrapper {
+ width: calc(100% - 100px);
+ }
+ .header-layout-compact-left .header-content-right {
+ width: 150px;
+ }
+}
+@media (max-width: 1345px) {
+ .header-layout-compact-left .header-branding-desktop {
+ width: 80px;
+ }
+ .header-layout-compact-left .header-branding-desktop img {
+ max-width: 80px;
+ }
+ .header-main-content {
+ padding: 0 20px;
+ }
+ .header-tools .checkout-link, .header-tools .customer-links, .header-tools .cart-count {
+ font-size: 12px;
+ }
+ .header-layout-compact-left .header-content-right {
+ width: 110px;
+ }
+}
+@media (max-width: 1260px) {
+ .navigation.navigation-desktop .navigation-menu>li>a, .navigation.navigation-desktop .navigation-menu summary {
+ padding: 17px 15px;
+ }
+}
+@media (max-width: 1260px) {
+ .navigation.navigation-desktop .navigation-menu>li>a, .navigation.navigation-desktop .navigation-menu summary {
+ padding: 17px 10px;
+ }
+ .navigation.navigation-desktop .has-dropdown>a:after, .navigation.navigation-desktop .has-dropdown summary:after, .navigation.navigation-desktop .has-mega-nav>a:after, .navigation.navigation-desktop .has-mega-nav summary:after {
+ right: 0;
+ }
+}
+@media (max-width: 1079px) {
+ .header-layout-compact-left .header-content-right {
+ width: auto;
+ margin-right: 35px;
+ }
+}
+/* Product description mobile */
+.product-content__mobile {
+ display: none;
+}
+@media (max-width: 769px) {
+ .product-content__mobile {
+ display: block;
+ }
+ .product-content__desktop {
+ display: none;
+ }
+ .dl-sample-btn {
+ margin-bottom: 10px;
+ }
+ .product-title {
+ font-size: 28px;
+ }
+ .block-buttonpdf .btn-pdf {
+ padding: 10px 15px !important;
+ }
+ .product-options {
+ margin-top: 10px;
+ }
+ .product-description {
+ margin-top: 0;
+ }
+ .cp-vendor-thumb {
+ justify-content: center;
+ align-items: center;
+ }
+ .cp-vendor-thumb-img {
+ max-width: 200px;
+ }
+ .block-buttonpdf .btn-pdf {
+ margin: auto !important;
+ }
+}
+/* End - New header */
+
+#bc-sf-filter-products .product-list-item-thumbnail {
+ display: block;
+ height: 0;
+ overflow: hidden;
+ position: relative;
+ z-index: 1;
+ background-size: cover;
+}
+.product-list-item-thumbnail {
+ display: block;
+ height: 0;
+ overflow: hidden;
+ position: relative;
+ z-index: 1;
+}
+#bc-sf-filter-products .product-list-item-thumbnail img {
+ bottom: 0;
+ display: block;
+ left: 0;
+ margin: auto;
+ position: absolute;
+ right: 0;
+ top: 0;
+}
+.product-list-item-thumbnail img {
+ bottom: 0;
+ display: block;
+ left: 0;
+ margin: auto;
+ position: absolute;
+ right: 0;
+ top: 0;
+}
+.addon-item {
+ padding: 30px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+@media screen and (max-width:767px) {
+ .addon-item {
+ flex-direction: column;
+ padding: 0px;
+ }
+}
+.addon-item .item-first {
+ display: flex;
+ align-items: center;
+}
+.addon-items .product-item-details {
+ padding: 0 30px 0 20px;
+ display: flex;
+ flex-direction: column;
+}
+.sticky-header a.visual-search-clickable {
+ display: none;
+}
+/* Hide this block temperally*/
+.pdfproductprint .block-buttonpdf button {
+ display: none !important;
+}
+.mini-cart-item-wrapper {
+ max-height: 360px;
+ overflow-y: auto;
+}
+.mini-cart-item-wrapper .mini-cart-item {
+ display: flex;
+ align-items: center;
+}
+.mini-cart-item.cart-subtotal {
+ flex-direction: column;
+}
+.subtotal-row {
+ width: 100%;
+}
+.product-add-to-cart .add-to-cart, .product-add-to-cart .shopify-payment-button__button, .dl-sample-btn, .dl-second-sample-btn, .dl-customize-btn, .dl-contact-btn {
+ width: 206px;
+ font-size: 12px !important;
+ border-radius: 99px;
+}
+.dl-sample-btn.dl-click-locked,
+.dl-second-sample-btn.dl-click-locked {
+ pointer-events: none;
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+@media screen and (max-width: 1024px) {
+ .product-add-to-cart .add-to-cart, .product-add-to-cart .shopify-payment-button__button, .dl-sample-btn, .dl-second-sample-btn, .dl-customize-btn, .dl-contact-btn {
+ width: 206px !important;
+ margin-left: auto;
+ margin-right: auto;
+ }
+}
+.mini-cart-item-price, .mini-cart-item .original-price, .mini-cart-item .cart-item-discounts {
+ display: none;
+}
+.mini-cart {
+ right: 0px;
+}
+.mini-cart-wrapper.is-open .mini-cart {
+ display: block;
+}
+.product-message.error-message {
+ width: 206px;
+ height: 45px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border: 1px solid;
+ border-radius: 99px;
+ margin-top: 10px;
+}
+.product-add-to-cart a {
+ margin-bottom: 10px;
+}
+.product-add-to-cart .add-to-cart,
+.product-add-to-cart a {
+ height: 45px;
+}
+.mini-cart-item .remove-item {
+ position: absolute;
+ top: 18px;
+ left: -25px;
+}
+.remove-item svg {
+ fill: #444;
+ width: 20px;
+}
+.product__form .hidden {
+ display: none !important;
+}
+.product-details-wrapper p {
+ margin-top: 0.5rem !important;
+ margin-bottom: 0.5rem !important;;
+}
+.add-to-cart.unavailable {
+ display: none !important;
+}
+.dl-second-sample-btn.unavailable {
+ display: none;
+}
+.showonly {
+ display: none;
+}
+/* ===============================================
+// Register Form Design
+// =============================================== */
+
+.register-form-card,
+.login-form-card {
+ max-width: 500px;
+ margin: 40px auto;
+ padding: 40px;
+ background: #ffffff;
+ border-radius: 8px;
+}
+.register-header,
+.login-header {
+ text-align: center;
+ margin-bottom: 30px;
+}
+.welcome-title,
+.login-title {
+ font-size: 24px;
+ font-weight: bold;
+ color: #333;
+ margin: 0 0 8px 0;
+ line-height: 1.2;
+}
+.welcome-subtitle {
+ font-size: 16px;
+ color: #666;
+ margin: 0;
+ line-height: 1.4;
+}
+.name-fields-row {
+ display: flex;
+ gap: 15px;
+ margin-bottom: 10px;
+}
+.name-field {
+ flex: 1;
+}
+.input-wrapper {
+ margin-bottom: 0;
+}
+.input-wrapper label {
+ display: block;
+ font-weight: bold;
+ color: #333;
+ margin-bottom: 8px;
+ font-size: 14px;
+}
+.input-wrapper input[type="text"],
+.input-wrapper input[type="email"],
+.input-wrapper input[type="password"],
+.input-wrapper select {
+ width: 100%;
+ padding: 12px;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ font-size: 14px;
+ background: #fff;
+ color: #666;
+ box-sizing: border-box;
+}
+.input-wrapper input[type="text"]:focus,
+.input-wrapper input[type="email"]:focus,
+.input-wrapper input[type="password"]:focus,
+.input-wrapper select:focus {
+ outline: none;
+ border-color: black;
+ color: white;
+}
+
+.input-wrapper input[type="submit"] {
+ width: 100%;
+ padding: 15px;
+ background: #4185f4;
+ color: #fff;
+ border: none;
+ border-radius: 4px;
+ font-size: 16px;
+ font-weight: bold;
+ text-transform: uppercase;
+ cursor: pointer;
+ transition: background-color 0.3s ease;
+}
+.input-wrapper input[type="submit"]:hover {
+ background: #3367d6;
+}
+/* OR separator between register form and social login */
+.or-separator {
+ position: relative;
+ text-align: center;
+ margin: 20px 0;
+}
+.or-separator::before {
+ content: "";
+ position: absolute;
+ top: 50%;
+ left: 0;
+ right: 0;
+ height: 1px;
+ background: #ddd;
+}
+.or-text {
+ background: white;
+ padding: 0 15px;
+ font-weight: bold;
+ color: #333;
+ position: relative;
+ z-index: 1;
+}
+/* Hide social login widget on register and login pages */
+/* .register-form-card .os_social_widget,
+.login-form-card .os_social_widget {
+ display: none !important;
+} */
+
+/* Mobile responsiveness */
+@media (max-width: 768px) {
+ .register-form-card,
+ .login-form-card {
+ margin: 20px;
+ padding: 30px 20px;
+ }
+
+ .name-fields-row {
+ flex-direction: column;
+ gap: 0;
+ }
+
+ .name-field {
+ margin-bottom: 20px;
+ }
+
+ .welcome-title,
+ .login-title {
+ font-size: 20px;
+ }
+
+ .welcome-subtitle {
+ font-size: 14px;
+ }
+
+ .keywords-desktop {
+ display: none !important;
+ }
+}
+/** More css custom cod **/
+.product-price-minimum.original {
+ text-decoration: line-through;
+ opacity: .8;
+ font-size: 1.1rem;
+}
+/* Base form control styles (missing from theme.css on some pages) */
+input[type="text"],
+input[type="email"],
+input[type="password"],
+input[type="search"],
+input[type="telephone"],
+input[type="tel"],
+input[type="number"],
+textarea,
+select {
+ font-family: Helvetica, Arial, sans-serif;
+ font-style: normal;
+ font-weight: 400;
+ display: block;
+ width: 100%;
+ max-width: 100%;
+ padding: 10px 12px;
+ font-size: 1rem;
+ box-sizing: border-box;
+ border-radius: 2px;
+ border: 1px solid rgba(0, 0, 0, 0.25);
+ color: inherit;
+ background: #fff;
+ -webkit-appearance: none;
+ appearance: none;
+}
+.boost-sd__in-collection-search {
+ display: none !important;
+}
+/* === Hide prices in You May Also Like / Product Recommendations === */
+.product-recommendations .product-list-item-price {
+ display: none !important;
+}
+
+/* DW Collections Page — full-width override (loads after theme.css) */
+.template-page .page-content > .dw-ex-header,
+.template-page .page-content > .dw-ex-section,
+.template-page .page-content > .dw-ex-grid,
+.template-page .page-content > .dw-ex-gc,
+.template-page .page-content > .dw-ex-section-title,
+.template-page .page-content > .dw-coll-wrap,
+.template-page .page-content > div[class*="dw-ex-"] {
+ max-width: 1500px !important;
+ margin-left: auto !important;
+ margin-right: auto !important;
+}
+.template-page .page-content > .dw-ex-grid {
+ max-width: 1500px !important;
+ padding-left: 24px !important;
+ padding-right: 24px !important;
+}
+
+/* ============================================
+ DW Compact Product Form — Size/Price/Qty
+ Added 2026-03-23 by ClawCoder session
+ ============================================ */
+.product-option-column-1 {
+ width: auto !important;
+ height: auto !important;
+ min-height: 0 !important;
+ margin-right: 4px !important;
+}
+.product-options {
+ display: flex !important;
+ flex-wrap: wrap !important;
+ align-items: center !important;
+ gap: 2px 0 !important;
+ margin: 4px 0 !important;
+}
+.product-options > label,
+.product-options > div.last_variant {
+ display: inline-flex !important;
+ align-items: center !important;
+ height: auto !important;
+ margin: 0 !important;
+}
+.last_variant .selected-text {
+ display: inline !important;
+ font-size: 14px !important;
+}
+.product__price {
+ margin: 2px 0 !important;
+}
+.product-sku-label,
+.product-sku-value {
+ margin-bottom: 2px !important;
+}
+.product-add-to-cart {
+ margin-top: 15px !important;
+}
+.block-buttonpdf {
+ margin-top: 10px !important;
+}
+label.product-option-row-4 {
+ height: auto !important;
+ width: auto !important;
+ margin-right: 4px !important;
+}
+.mm_quantity {
+ margin: 4px 0 !important;
+}
+/* Fix transparent PNG images showing black boxes in collection grids */
+.product-grid-image img,
+.product-image img,
+.product-card img,
+.collection-product-image img,
+.grid__image img,
+.product-grid-item img,
+.product_image img {
+ background-color: #fff !important;
+}
+.product-grid-image,
+.product-image,
+.product-card__image,
+.collection-product-image,
+.grid__image,
+.product-grid-item {
+ background-color: #fff !important;
+}
+
+/* Remove share buttons from product pages */
+.share-buttons,
+.product-share,
+.social-sharing,
+.product__social-sharing,
+.share-icons,
+[class*="share"],
+.product-social-sharing,
+.sharing {
+ display: none !important;
+}
+/* input.add-to-cart,
+input[type="submit"].add-to-cart,
+.product-add-to-cart input[type="submit"],
+.product-add-to-cart .add-to-cart {
+ background-color: #000 !important;
+ color: #fff !important;
+ border: none !important;
+ border-radius: 999px !important;
+ text-align: center !important;
+ font-weight: 500 !important;
+ font-size: 11px !important;
+ letter-spacing: 0.5px !important;
+ text-transform: uppercase !important;
+ padding: 10px 20px !important;
+ cursor: pointer !important;
+ display: inline-block !important;
+ vertical-align: middle !important;
+ line-height: 1 !important;
+ -webkit-appearance: none !important;
+ appearance: none !important;
+} */
+.block-buttonpdf button.btn-pdf {
+ background-color: #000 !important;
+ color: #fff !important;
+ border: none !important;
+ border-radius: 999px !important;
+ padding: 10px 20px !important;
+ font-size: 11px !important;
+ font-weight: 500 !important;
+ letter-spacing: 0.5px !important;
+ text-transform: uppercase !important;
+ font-family: inherit !important;
+ cursor: pointer !important;
+}
+.spec-sheet-btn:hover,
+.dl-sample-btn:hover,
+input.add-to-cart:hover,
+.block-buttonpdf button.btn-pdf:hover {
+ background-color: #333 !important;
+ color: white !important;
+}
+/* Match all product action buttons to the Add to Cart button */
+.product-add-to-cart .add-to-cart,
+.product-add-to-cart .shopify-payment-button__button,
+.product-form--atc .action_button,
+.dl-sample-btn,
+.dl-second-sample-btn,
+.spec-sheet-btn {
+ display: inline-flex !important;
+ align-items: center !important;
+ justify-content: center !important;
+ width: 206px !important;
+ min-height: 45px !important;
+ padding: 10px 20px !important;
+ border-radius: 999px !important;
+ box-sizing: border-box !important;
+ font-size: 12px !important;
+ font-weight: 500 !important;
+ letter-spacing: 0.5px !important;
+ line-height: 1 !important;
+ text-align: center !important;
+ text-transform: uppercase !important;
+ text-decoration: none !important;
+}
+
+/* Force prices visible on product pages — overrides Boost transparent color */
+.product-price .money,
+.product-price-minimum.money,
+.product-price-discount.money,
+.product__price .money,
+.product__price span,
+#shopify-section-template--18587140849715__main .money,
+[id*="__main"] .product-price span,
+[id*="__main"] .money {
+ color: inherit !important;
+ opacity: 1 !important;
+ visibility: visible !important;
+}
+/* === Product grid card descriptions === */
+.product-list-item-description {
+ font-size: 12px;
+ line-height: 1.45;
+ color: #666;
+ margin: 3px 0 6px;
+ overflow: hidden;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+}
+/* === Grid Density Slider Control === */
+.collection-grid-controls {
+ display: flex;
+ align-items: center;
+ gap: 16px;
+ margin: 20px 0;
+ padding: 12px 16px;
+ background: #f9f9f9;
+ border-radius: 4px;
+ flex-wrap: wrap;
+}
+.collection-grid-controls label {
+ font-size: 13px;
+ font-weight: 500;
+ color: #666;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ white-space: nowrap;
+}
+.collection-grid-controls-slider {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ flex: 1;
+ min-width: 200px;
+}
+.collection-grid-controls-slider input[type="range"] {
+ flex: 1;
+ min-width: 120px;
+ height: 6px;
+ border-radius: 3px;
+ background: #ddd;
+ outline: none;
+ -webkit-appearance: none;
+ appearance: none;
+}
+.collection-grid-controls-slider input[type="range"]::-webkit-slider-thumb {
+ -webkit-appearance: none;
+ appearance: none;
+ width: 18px;
+ height: 18px;
+ border-radius: 50%;
+ background: #111;
+ cursor: pointer;
+ box-shadow: 0 1px 3px rgba(0,0,0,0.2);
+}
+.collection-grid-controls-slider input[type="range"]::-moz-range-thumb {
+ width: 18px;
+ height: 18px;
+ border-radius: 50%;
+ background: #111;
+ cursor: pointer;
+ border: none;
+ box-shadow: 0 1px 3px rgba(0,0,0,0.2);
+}
+.collection-grid-density-value {
+ min-width: 45px;
+ text-align: center;
+ font-weight: 600;
+ color: #111;
+ font-size: 14px;
+}
+/* Dynamic grid columns (3-12) */
+.collection-products {
+ --grid-columns: 3;
+ display: grid !important;
+ grid-template-columns: repeat(var(--grid-columns), 1fr) !important;
+ gap: 16px !important;
+}
+.collection-products.grid-cols-3 { --grid-columns: 3; }
+.collection-products.grid-cols-4 { --grid-columns: 4; }
+.collection-products.grid-cols-5 { --grid-columns: 5; }
+.collection-products.grid-cols-6 { --grid-columns: 6; }
+.collection-products.grid-cols-7 { --grid-columns: 7; }
+.collection-products.grid-cols-8 { --grid-columns: 8; }
+.collection-products.grid-cols-9 { --grid-columns: 9; }
+.collection-products.grid-cols-10 { --grid-columns: 10; }
+.collection-products.grid-cols-11 { --grid-columns: 11; }
+.collection-products.grid-cols-12 { --grid-columns: 12; }
+
+/* Responsive: reduce max columns on mobile */
+@media (max-width: 768px) {
+ .collection-grid-controls {
+ flex-direction: column;
+ align-items: flex-start;
+ }
+
+ .collection-grid-controls-slider {
+ width: 100%;
+ }
+
+ .collection-products {
+ --grid-columns: 2 !important;
+ }
+}
+}
+
+/* === Collection Cards: Image only, no text === */
+.product-list-item {
+ cursor: pointer;
+}
+
+.product-list-item-details {
+ display: none !important;
+}
+
+.product-list-item-overlay {
+ display: none !important;
+}
+
+.product-list-item-thumbnail {
+ transition: opacity 0.2s ease, transform 0.2s ease;
+}
+
+.product-list-item:hover .product-list-item-thumbnail {
+ opacity: 0.9;
+ transform: scale(1.02);
+}
+
+/* Hide Boost Commerce hover overlays on collection cards */
+.dw-hover-label {
+ display: none !important;
+}
+
+.boost-sd__product-item-image-overlay {
+ display: none !important;
+}
+
+/* === Collection Card Hover Overlay: Vendor + Pattern Name === */
+.product-list-item-hover-overlay {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: rgba(0, 0, 0, 0);
+ transition: background 0.25s ease;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 10;
+}
+
+.product-list-item:hover .product-list-item-hover-overlay {
+ background: rgba(0, 0, 0, 0.75);
+}
+
+.product-list-item-hover-content {
+ opacity: 0;
+ transition: opacity 0.25s ease;
+ text-align: center;
+ color: white;
+ padding: 20px;
+ pointer-events: none;
+}
+
+.product-list-item:hover .product-list-item-hover-content {
+ opacity: 1;
+}
+
+.product-list-item-hover-vendor {
+ font-size: 11px;
+ font-weight: 500;
+ text-transform: uppercase;
+ letter-spacing: 0.12em;
+ color: #aaa;
+ margin: 0 0 8px;
+ line-height: 1.2;
+}
+
+.product-list-item-hover-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #fff;
+ margin: 0;
+ line-height: 1.4;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
+}
+
+.product-list-item-hover-title a {
+ color: inherit;
+ text-decoration: none;
+}
+
+/* Ensure no text below images */
+.product-list-item-details {
+ display: none !important;
+}
+
+/* Hide any secondary labels */
+.dw-hover-label {
+ display: none !important;
+}
+
+/* Compact spacing: reduce gaps between rows */
+.collection-products {
+ gap: 8px !important;
+ row-gap: 4px !important;
+}
+
+/* Reduce item margins/padding */
+.product-list-item {
+ margin: 0 !important;
+ padding: 0 !important;
+}
+
+.product-list-item-thumbnail {
+ margin: 0 !important;
+}
+
+/* Product card = image ONLY, zero space below */
+.product-list-item {
+ display: flex;
+ flex-direction: column;
+}
+
+.product-list-item-thumbnail {
+ flex: 1;
+ width: 100%;
+}
+
+.product-list-item-details {
+ display: none !important;
+ height: 0 !important;
+ margin: 0 !important;
+ padding: 0 !important;
+ overflow: hidden !important;
+}
+
+/* Article takes only image space */
+.product-list-item article {
+ display: contents;
+}
+
+.product-list-item {
+ overflow: hidden;
+}
+
+/* Ultra-tight grid spacing */
+.collection-products {
+ gap: 2px !important;
+ row-gap: 2px !important;
+}
diff --git a/shopify/collection-hero-fix/backups/config_settings_schema.json.dev-143947038771.pushbak b/shopify/collection-hero-fix/backups/config_settings_schema.json.dev-143947038771.pushbak
new file mode 100644
index 00000000..d37ca312
--- /dev/null
+++ b/shopify/collection-hero-fix/backups/config_settings_schema.json.dev-143947038771.pushbak
@@ -0,0 +1,542 @@
+[
+ {
+ "name": "theme_info",
+ "theme_name": "Grid",
+ "theme_author": "Pixel Union",
+ "theme_version": "7.1.0",
+ "theme_documentation_url": "https:\/\/support.pixelunion.net\/hc\/en-us\/sections\/360003950473-Grid",
+ "theme_support_url": "https:\/\/support.pixelunion.net\/hc\/en-us\/requests\/new"
+ },
+ {
+ "name": "Collection hero",
+ "settings": [
+ {
+ "type": "paragraph",
+ "content": "Fallback hero image shown on collection pages that do not have their own Collection image set. Per-collection images (Collections > [collection] > Image) always take priority."
+ },
+ {
+ "type": "image_picker",
+ "id": "collection_default_hero",
+ "label": "Default collection hero image",
+ "info": "Used only when a collection has no image of its own. Recommended 2000x600."
+ }
+ ]
+ },
+ {
+ "name": "Favicon",
+ "settings": [
+ {
+ "type": "image_picker",
+ "id": "favicon",
+ "label": "Favicon"
+ }
+ ]
+ },
+ {
+ "name": "t:settings_schema.age_gate.name",
+ "settings": [
+ {
+ "type": "checkbox",
+ "id": "enable_age_gate_site_wide",
+ "label": "t:settings_schema.age_gate.enable_site_wide.label",
+ "default": false
+ },
+ {
+ "type": "number",
+ "id": "age_gate_site_wide_min_age",
+ "label": "t:settings_schema.age_gate.minimum_age.label",
+ "default": 18
+ },
+ {
+ "type": "text",
+ "id": "age_gate_heading",
+ "label": "t:settings_schema.age_gate.heading.label",
+ "default": "Age Verification"
+ },
+ {
+ "type": "text",
+ "id": "age_gate_description",
+ "label": "t:settings_schema.age_gate.description.label",
+ "default": "Please enter your date of birth for full access."
+ },
+ {
+ "type": "checkbox",
+ "id": "show_age_gate_logo",
+ "label": "t:settings_schema.age_gate.show_logo.label",
+ "default": true,
+ "info": "t:settings_schema.age_gate.show_logo.info"
+ }
+ ]
+ },
+ {
+ "name": "Color",
+ "settings": [
+ {
+ "type": "header",
+ "content": "Background"
+ },
+ {
+ "type": "color",
+ "id": "background-color",
+ "label": "Background"
+ },
+ {
+ "type": "image_picker",
+ "id": "body-background-image",
+ "label": "Background image",
+ "info": "200 x 200px recommended"
+ },
+ {
+ "type": "header",
+ "content": "General"
+ },
+ {
+ "type": "color",
+ "id": "body-text-color",
+ "label": "Text"
+ },
+ {
+ "type": "color",
+ "id": "accent-color",
+ "label": "Accent"
+ },
+ {
+ "type": "color",
+ "id": "heading-color",
+ "label": "Heading"
+ },
+ {
+ "type": "color",
+ "id": "meta-color",
+ "label": "Meta text"
+ },
+ {
+ "type": "color",
+ "id": "border-color",
+ "label": "Border"
+ },
+ {
+ "type": "color",
+ "id": "product-badge-background-color",
+ "label": "Sale\/sold out badges and discounts"
+ },
+ {
+ "type": "header",
+ "content": "Buttons"
+ },
+ {
+ "type": "color",
+ "id": "button-color",
+ "label": "Primary button text"
+ },
+ {
+ "type": "color",
+ "id": "secondary-button-background",
+ "label": "Secondary button background"
+ },
+ {
+ "type": "color",
+ "id": "secondary-button-color",
+ "label": "Secondary button text"
+ },
+ {
+ "type": "header",
+ "content": "Header"
+ },
+ {
+ "type": "color",
+ "id": "header-tools-color",
+ "label": "Header tools"
+ },
+ {
+ "type": "color",
+ "id": "header-tools-background-color",
+ "label": "Header tools background"
+ },
+ {
+ "type": "color",
+ "id": "navigation-color",
+ "label": "Navigation"
+ },
+ {
+ "type": "header",
+ "content": "Dropdowns\/table headers"
+ },
+ {
+ "type": "color",
+ "id": "form-select-background",
+ "label": "Background"
+ },
+ {
+ "type": "color",
+ "id": "form-select-color",
+ "label": "Text"
+ },
+ {
+ "type": "color",
+ "id": "form-select-border-color",
+ "label": "Border",
+ "info": "This option only applies to dropdown menus."
+ }
+ ]
+ },
+ {
+ "name": "Typography",
+ "settings": [
+ {
+ "type": "select",
+ "id": "font-base-size",
+ "label": "Base size",
+ "default": "14px",
+ "options": [
+ {
+ "value": "14px",
+ "label": "Small"
+ },
+ {
+ "value": "16px",
+ "label": "Medium"
+ },
+ {
+ "value": "18px",
+ "label": "Large"
+ }
+ ]
+ },
+ {
+ "type": "font_picker",
+ "label": "Body font",
+ "id": "font_body",
+ "default": "helvetica_n4"
+ },
+ {
+ "type": "header",
+ "content": "Headings"
+ },
+ {
+ "type": "font_picker",
+ "label": "Heading font",
+ "id": "font_heading",
+ "default": "helvetica_n4"
+ },
+ {
+ "type": "checkbox",
+ "id": "heading-font-small-caps",
+ "label": "Capitalize"
+ },
+ {
+ "type": "header",
+ "content": "Navigation"
+ },
+ {
+ "type": "font_picker",
+ "label": "Navigation font",
+ "id": "font_navigation",
+ "default": "helvetica_n4"
+ },
+ {
+ "type": "checkbox",
+ "id": "navigation-font-small-caps",
+ "label": "Capitalize"
+ },
+ {
+ "type": "header",
+ "content": "Captions"
+ },
+ {
+ "type": "font_picker",
+ "label": "Caption font",
+ "id": "font_meta",
+ "default": "helvetica_n4"
+ },
+ {
+ "type": "checkbox",
+ "id": "meta-font-small-caps",
+ "label": "Capitalize"
+ },
+ {
+ "type": "header",
+ "content": "Buttons"
+ },
+ {
+ "type": "font_picker",
+ "label": "Button font",
+ "id": "font_button",
+ "default": "helvetica_n4"
+ },
+ {
+ "type": "checkbox",
+ "id": "button-font-small-caps",
+ "label": "Capitalize"
+ }
+ ]
+ },
+ {
+ "name": "Social media",
+ "settings": [
+ {
+ "type": "header",
+ "content": "Accounts"
+ },
+ {
+ "type": "text",
+ "id": "social-behance-link",
+ "label": "Behance",
+ "info": "https:\/\/behance.net\/"
+ },
+ {
+ "type": "text",
+ "id": "social-clubhouse-link",
+ "label": "Clubhouse",
+ "info": "https:\/\/www.clubhouse.com\/"
+ },
+ {
+ "type": "text",
+ "id": "social-discord-link",
+ "label": "Discord",
+ "info": "https:\/\/discord.com\/"
+ },
+ {
+ "type": "text",
+ "id": "social-dribbble-link",
+ "label": "Dribbble",
+ "info": "https:\/\/dribbble.com\/shopify"
+ },
+ {
+ "type": "text",
+ "id": "social-email-link",
+ "label": "Email address"
+ },
+ {
+ "type": "text",
+ "id": "social-facebook-link",
+ "label": "Facebook",
+ "info": "https:\/\/www.facebook.com\/shopify"
+ },
+ {
+ "type": "text",
+ "id": "social-flickr-link",
+ "label": "Flickr",
+ "info": "https:\/\/flickr.com\/"
+ },
+ {
+ "type": "text",
+ "id": "social-houzz-link",
+ "label": "Houzz",
+ "info": "https:\/\/www.houzz.com\/"
+ },
+ {
+ "type": "text",
+ "id": "social-instagram-link",
+ "label": "Instagram",
+ "info": "https:\/\/instagram.com\/shopify"
+ },
+ {
+ "type": "text",
+ "id": "social-kickstarter-link",
+ "label": "Kickstarter",
+ "info": "https:\/\/www.kickstarter.com\/"
+ },
+ {
+ "type": "text",
+ "id": "social-linkedin-link",
+ "label": "LinkedIn",
+ "info": "https:\/\/www.linkedin.com\/company\/shopify"
+ },
+ {
+ "type": "text",
+ "id": "social-medium-link",
+ "label": "Medium",
+ "info": "https:\/\/medium.com\/"
+ },
+ {
+ "type": "text",
+ "id": "social-messenger-link",
+ "label": "Messenger",
+ "info": "https:\/\/www.messenger.com\/"
+ },
+ {
+ "type": "text",
+ "id": "social-opensea-link",
+ "label": "OpenSea",
+ "info": "https:\/\/opensea.io\/"
+ },
+ {
+ "type": "text",
+ "id": "social-pinterest-link",
+ "label": "Pinterest",
+ "info": "https:\/\/www.pinterest.com\/shopify"
+ },
+ {
+ "type": "text",
+ "id": "social-reddit-link",
+ "label": "Reddit",
+ "info": "https:\/\/www.reddit.com\/r\/shopify\/"
+ },
+ {
+ "type": "text",
+ "id": "social-rss-link",
+ "label": "RSS",
+ "info": "https:\/\/www.shopify.com\/content-services\/feeds\/ecommerce.atom"
+ },
+ {
+ "type": "text",
+ "id": "social-snapchat-link",
+ "label": "Snapchat",
+ "info": "https:\/\/www.snapchat.com\/"
+ },
+ {
+ "type": "text",
+ "id": "social-spotify-link",
+ "label": "Spotify",
+ "info": "https:\/\/www.spotify.com\/"
+ },
+ {
+ "type": "text",
+ "id": "social-tiktok-link",
+ "label": "TikTok",
+ "info": "https:\/\/tiktok.com\/@shopify"
+ },
+ {
+ "type": "text",
+ "id": "social-tumblr-link",
+ "label": "Tumblr",
+ "info": "https:\/\/shopify.tumblr.com"
+ },
+ {
+ "type": "text",
+ "id": "social-twitch-link",
+ "label": "Twitch",
+ "info": "https:\/\/www.twitch.tv\/"
+ },
+ {
+ "type": "text",
+ "id": "social-x-link",
+ "label": "X",
+ "info": "https:\/\/x.com\/shopify"
+ },
+ {
+ "type": "text",
+ "id": "social-vimeo-link",
+ "label": "Vimeo",
+ "info": "https:\/\/vimeo.com\/"
+ },
+ {
+ "type": "text",
+ "id": "social-whatsapp-link",
+ "label": "WhatsApp",
+ "info": "https:\/\/www.whatsapp.com\/"
+ },
+ {
+ "type": "text",
+ "id": "social-youtube-link",
+ "label": "YouTube",
+ "info": "https:\/\/www.youtube.com\/user\/shopify"
+ },
+ {
+ "type": "header",
+ "content": "Sharing"
+ },
+ {
+ "type": "checkbox",
+ "id": "share-widget-facebook",
+ "label": "Share on Facebook"
+ },
+ {
+ "type": "checkbox",
+ "id": "share-widget-x",
+ "label": "Share on X"
+ },
+ {
+ "type": "checkbox",
+ "id": "share-widget-pinterest",
+ "label": "Pin on Pinterest"
+ },
+ {
+ "type": "checkbox",
+ "id": "share-widget-fancy",
+ "label": "Add to Fancy"
+ },
+ {
+ "type": "checkbox",
+ "id": "share-widget-email",
+ "label": "Enable email"
+ }
+ ]
+ },
+ {
+ "name": "Product cards",
+ "settings": [
+ {
+ "type": "select",
+ "id": "product_hover",
+ "label": "Overlay \/ hover interaction",
+ "options": [
+ {
+ "value": "quick-shop",
+ "label": "Quick shop"
+ },
+ {
+ "value": "image-flip",
+ "label": "Secondary image"
+ },
+ {
+ "value": "stock-level",
+ "label": "Stock level indicator"
+ },
+ {
+ "value": "none",
+ "label": "None"
+ }
+ ],
+ "default": "quick-shop"
+ },
+ {
+ "type": "range",
+ "id": "product_stock_level_threshold",
+ "label": "Show warning when stock is equal to or less than:",
+ "min": 1,
+ "max": 10,
+ "step": 1,
+ "default": 1
+ },
+ {
+ "type": "checkbox",
+ "id": "show_vendor",
+ "label": "Show vendor name",
+ "default": false
+ },
+ {
+ "type": "checkbox",
+ "id": "product_badges",
+ "label": "Show 'on sale' \/ 'sold out' badges",
+ "default": false
+ },
+ {
+ "type": "checkbox",
+ "id": "product_badges_icons",
+ "label": "Use icons for 'on sale' \/ 'sold out' badges",
+ "default": false
+ }
+ ]
+ },
+ {
+ "name": "DW Controls",
+ "settings": [
+ {
+ "type": "checkbox",
+ "id": "dw_enable_recently_viewed",
+ "label": "Enable Recently Viewed products section",
+ "info": "Shows a carousel of recently viewed products at the top of static pages. Toggle OFF to instantly hide.",
+ "default": true
+ },
+ {
+ "type": "checkbox",
+ "id": "dw_enable_new_metafields",
+ "label": "Enable new product metafields UI",
+ "info": "Toggle this OFF to instantly revert to the old metafields layout",
+ "default": false
+ }
+ ]
+ }
+]
diff --git a/shopify/collection-hero-fix/backups/config_settings_schema.json.live-142250278963.pushbak b/shopify/collection-hero-fix/backups/config_settings_schema.json.live-142250278963.pushbak
new file mode 100644
index 00000000..cbc1db1f
--- /dev/null
+++ b/shopify/collection-hero-fix/backups/config_settings_schema.json.live-142250278963.pushbak
@@ -0,0 +1,527 @@
+[
+ {
+ "name": "theme_info",
+ "theme_name": "Grid",
+ "theme_author": "Pixel Union",
+ "theme_version": "7.1.0",
+ "theme_documentation_url": "https:\/\/support.pixelunion.net\/hc\/en-us\/sections\/360003950473-Grid",
+ "theme_support_url": "https:\/\/support.pixelunion.net\/hc\/en-us\/requests\/new"
+ },
+ {
+ "name": "Favicon",
+ "settings": [
+ {
+ "type": "image_picker",
+ "id": "favicon",
+ "label": "Favicon"
+ }
+ ]
+ },
+ {
+ "name": "t:settings_schema.age_gate.name",
+ "settings": [
+ {
+ "type": "checkbox",
+ "id": "enable_age_gate_site_wide",
+ "label": "t:settings_schema.age_gate.enable_site_wide.label",
+ "default": false
+ },
+ {
+ "type": "number",
+ "id": "age_gate_site_wide_min_age",
+ "label": "t:settings_schema.age_gate.minimum_age.label",
+ "default": 18
+ },
+ {
+ "type": "text",
+ "id": "age_gate_heading",
+ "label": "t:settings_schema.age_gate.heading.label",
+ "default": "Age Verification"
+ },
+ {
+ "type": "text",
+ "id": "age_gate_description",
+ "label": "t:settings_schema.age_gate.description.label",
+ "default": "Please enter your date of birth for full access."
+ },
+ {
+ "type": "checkbox",
+ "id": "show_age_gate_logo",
+ "label": "t:settings_schema.age_gate.show_logo.label",
+ "default": true,
+ "info": "t:settings_schema.age_gate.show_logo.info"
+ }
+ ]
+ },
+ {
+ "name": "Color",
+ "settings": [
+ {
+ "type": "header",
+ "content": "Background"
+ },
+ {
+ "type": "color",
+ "id": "background-color",
+ "label": "Background"
+ },
+ {
+ "type": "image_picker",
+ "id": "body-background-image",
+ "label": "Background image",
+ "info": "200 x 200px recommended"
+ },
+ {
+ "type": "header",
+ "content": "General"
+ },
+ {
+ "type": "color",
+ "id": "body-text-color",
+ "label": "Text"
+ },
+ {
+ "type": "color",
+ "id": "accent-color",
+ "label": "Accent"
+ },
+ {
+ "type": "color",
+ "id": "heading-color",
+ "label": "Heading"
+ },
+ {
+ "type": "color",
+ "id": "meta-color",
+ "label": "Meta text"
+ },
+ {
+ "type": "color",
+ "id": "border-color",
+ "label": "Border"
+ },
+ {
+ "type": "color",
+ "id": "product-badge-background-color",
+ "label": "Sale\/sold out badges and discounts"
+ },
+ {
+ "type": "header",
+ "content": "Buttons"
+ },
+ {
+ "type": "color",
+ "id": "button-color",
+ "label": "Primary button text"
+ },
+ {
+ "type": "color",
+ "id": "secondary-button-background",
+ "label": "Secondary button background"
+ },
+ {
+ "type": "color",
+ "id": "secondary-button-color",
+ "label": "Secondary button text"
+ },
+ {
+ "type": "header",
+ "content": "Header"
+ },
+ {
+ "type": "color",
+ "id": "header-tools-color",
+ "label": "Header tools"
+ },
+ {
+ "type": "color",
+ "id": "header-tools-background-color",
+ "label": "Header tools background"
+ },
+ {
+ "type": "color",
+ "id": "navigation-color",
+ "label": "Navigation"
+ },
+ {
+ "type": "header",
+ "content": "Dropdowns\/table headers"
+ },
+ {
+ "type": "color",
+ "id": "form-select-background",
+ "label": "Background"
+ },
+ {
+ "type": "color",
+ "id": "form-select-color",
+ "label": "Text"
+ },
+ {
+ "type": "color",
+ "id": "form-select-border-color",
+ "label": "Border",
+ "info": "This option only applies to dropdown menus."
+ }
+ ]
+ },
+ {
+ "name": "Typography",
+ "settings": [
+ {
+ "type": "select",
+ "id": "font-base-size",
+ "label": "Base size",
+ "default": "14px",
+ "options": [
+ {
+ "value": "14px",
+ "label": "Small"
+ },
+ {
+ "value": "16px",
+ "label": "Medium"
+ },
+ {
+ "value": "18px",
+ "label": "Large"
+ }
+ ]
+ },
+ {
+ "type": "font_picker",
+ "label": "Body font",
+ "id": "font_body",
+ "default": "helvetica_n4"
+ },
+ {
+ "type": "header",
+ "content": "Headings"
+ },
+ {
+ "type": "font_picker",
+ "label": "Heading font",
+ "id": "font_heading",
+ "default": "helvetica_n4"
+ },
+ {
+ "type": "checkbox",
+ "id": "heading-font-small-caps",
+ "label": "Capitalize"
+ },
+ {
+ "type": "header",
+ "content": "Navigation"
+ },
+ {
+ "type": "font_picker",
+ "label": "Navigation font",
+ "id": "font_navigation",
+ "default": "helvetica_n4"
+ },
+ {
+ "type": "checkbox",
+ "id": "navigation-font-small-caps",
+ "label": "Capitalize"
+ },
+ {
+ "type": "header",
+ "content": "Captions"
+ },
+ {
+ "type": "font_picker",
+ "label": "Caption font",
+ "id": "font_meta",
+ "default": "helvetica_n4"
+ },
+ {
+ "type": "checkbox",
+ "id": "meta-font-small-caps",
+ "label": "Capitalize"
+ },
+ {
+ "type": "header",
+ "content": "Buttons"
+ },
+ {
+ "type": "font_picker",
+ "label": "Button font",
+ "id": "font_button",
+ "default": "helvetica_n4"
+ },
+ {
+ "type": "checkbox",
+ "id": "button-font-small-caps",
+ "label": "Capitalize"
+ }
+ ]
+ },
+ {
+ "name": "Social media",
+ "settings": [
+ {
+ "type": "header",
+ "content": "Accounts"
+ },
+ {
+ "type": "text",
+ "id": "social-behance-link",
+ "label": "Behance",
+ "info": "https:\/\/behance.net\/"
+ },
+ {
+ "type": "text",
+ "id": "social-clubhouse-link",
+ "label": "Clubhouse",
+ "info": "https:\/\/www.clubhouse.com\/"
+ },
+ {
+ "type": "text",
+ "id": "social-discord-link",
+ "label": "Discord",
+ "info": "https:\/\/discord.com\/"
+ },
+ {
+ "type": "text",
+ "id": "social-dribbble-link",
+ "label": "Dribbble",
+ "info": "https:\/\/dribbble.com\/shopify"
+ },
+ {
+ "type": "text",
+ "id": "social-email-link",
+ "label": "Email address"
+ },
+ {
+ "type": "text",
+ "id": "social-facebook-link",
+ "label": "Facebook",
+ "info": "https:\/\/www.facebook.com\/shopify"
+ },
+ {
+ "type": "text",
+ "id": "social-flickr-link",
+ "label": "Flickr",
+ "info": "https:\/\/flickr.com\/"
+ },
+ {
+ "type": "text",
+ "id": "social-houzz-link",
+ "label": "Houzz",
+ "info": "https:\/\/www.houzz.com\/"
+ },
+ {
+ "type": "text",
+ "id": "social-instagram-link",
+ "label": "Instagram",
+ "info": "https:\/\/instagram.com\/shopify"
+ },
+ {
+ "type": "text",
+ "id": "social-kickstarter-link",
+ "label": "Kickstarter",
+ "info": "https:\/\/www.kickstarter.com\/"
+ },
+ {
+ "type": "text",
+ "id": "social-linkedin-link",
+ "label": "LinkedIn",
+ "info": "https:\/\/www.linkedin.com\/company\/shopify"
+ },
+ {
+ "type": "text",
+ "id": "social-medium-link",
+ "label": "Medium",
+ "info": "https:\/\/medium.com\/"
+ },
+ {
+ "type": "text",
+ "id": "social-messenger-link",
+ "label": "Messenger",
+ "info": "https:\/\/www.messenger.com\/"
+ },
+ {
+ "type": "text",
+ "id": "social-opensea-link",
+ "label": "OpenSea",
+ "info": "https:\/\/opensea.io\/"
+ },
+ {
+ "type": "text",
+ "id": "social-pinterest-link",
+ "label": "Pinterest",
+ "info": "https:\/\/www.pinterest.com\/shopify"
+ },
+ {
+ "type": "text",
+ "id": "social-reddit-link",
+ "label": "Reddit",
+ "info": "https:\/\/www.reddit.com\/r\/shopify\/"
+ },
+ {
+ "type": "text",
+ "id": "social-rss-link",
+ "label": "RSS",
+ "info": "https:\/\/www.shopify.com\/content-services\/feeds\/ecommerce.atom"
+ },
+ {
+ "type": "text",
+ "id": "social-snapchat-link",
+ "label": "Snapchat",
+ "info": "https:\/\/www.snapchat.com\/"
+ },
+ {
+ "type": "text",
+ "id": "social-spotify-link",
+ "label": "Spotify",
+ "info": "https:\/\/www.spotify.com\/"
+ },
+ {
+ "type": "text",
+ "id": "social-tiktok-link",
+ "label": "TikTok",
+ "info": "https:\/\/tiktok.com\/@shopify"
+ },
+ {
+ "type": "text",
+ "id": "social-tumblr-link",
+ "label": "Tumblr",
+ "info": "https:\/\/shopify.tumblr.com"
+ },
+ {
+ "type": "text",
+ "id": "social-twitch-link",
+ "label": "Twitch",
+ "info": "https:\/\/www.twitch.tv\/"
+ },
+ {
+ "type": "text",
+ "id": "social-x-link",
+ "label": "X",
+ "info": "https:\/\/x.com\/shopify"
+ },
+ {
+ "type": "text",
+ "id": "social-vimeo-link",
+ "label": "Vimeo",
+ "info": "https:\/\/vimeo.com\/"
+ },
+ {
+ "type": "text",
+ "id": "social-whatsapp-link",
+ "label": "WhatsApp",
+ "info": "https:\/\/www.whatsapp.com\/"
+ },
+ {
+ "type": "text",
+ "id": "social-youtube-link",
+ "label": "YouTube",
+ "info": "https:\/\/www.youtube.com\/user\/shopify"
+ },
+ {
+ "type": "header",
+ "content": "Sharing"
+ },
+ {
+ "type": "checkbox",
+ "id": "share-widget-facebook",
+ "label": "Share on Facebook"
+ },
+ {
+ "type": "checkbox",
+ "id": "share-widget-x",
+ "label": "Share on X"
+ },
+ {
+ "type": "checkbox",
+ "id": "share-widget-pinterest",
+ "label": "Pin on Pinterest"
+ },
+ {
+ "type": "checkbox",
+ "id": "share-widget-fancy",
+ "label": "Add to Fancy"
+ },
+ {
+ "type": "checkbox",
+ "id": "share-widget-email",
+ "label": "Enable email"
+ }
+ ]
+ },
+ {
+ "name": "Product cards",
+ "settings": [
+ {
+ "type": "select",
+ "id": "product_hover",
+ "label": "Overlay \/ hover interaction",
+ "options": [
+ {
+ "value": "quick-shop",
+ "label": "Quick shop"
+ },
+ {
+ "value": "image-flip",
+ "label": "Secondary image"
+ },
+ {
+ "value": "stock-level",
+ "label": "Stock level indicator"
+ },
+ {
+ "value": "none",
+ "label": "None"
+ }
+ ],
+ "default": "quick-shop"
+ },
+ {
+ "type": "range",
+ "id": "product_stock_level_threshold",
+ "label": "Show warning when stock is equal to or less than:",
+ "min": 1,
+ "max": 10,
+ "step": 1,
+ "default": 1
+ },
+ {
+ "type": "checkbox",
+ "id": "show_vendor",
+ "label": "Show vendor name",
+ "default": false
+ },
+ {
+ "type": "checkbox",
+ "id": "product_badges",
+ "label": "Show 'on sale' \/ 'sold out' badges",
+ "default": false
+ },
+ {
+ "type": "checkbox",
+ "id": "product_badges_icons",
+ "label": "Use icons for 'on sale' \/ 'sold out' badges",
+ "default": false
+ }
+ ]
+ },
+ {
+ "name": "DW Controls",
+ "settings": [
+ {
+ "type": "checkbox",
+ "id": "dw_enable_recently_viewed",
+ "label": "Enable Recently Viewed products section",
+ "info": "Shows a carousel of recently viewed products at the top of static pages. Toggle OFF to instantly hide.",
+ "default": true
+ },
+ {
+ "type": "checkbox",
+ "id": "dw_enable_new_metafields",
+ "label": "Enable new product metafields UI",
+ "info": "Toggle this OFF to instantly revert to the old metafields layout",
+ "default": false
+ }
+ ]
+ }
+]
diff --git a/shopify/collection-hero-fix/backups/sections_collection.liquid.dev-143947038771.pushbak b/shopify/collection-hero-fix/backups/sections_collection.liquid.dev-143947038771.pushbak
new file mode 100644
index 00000000..609a8785
--- /dev/null
+++ b/shopify/collection-hero-fix/backups/sections_collection.liquid.dev-143947038771.pushbak
@@ -0,0 +1,262 @@
+<script
+ type="application/json"
+ data-section-id="{{ section.id }}"
+ data-section-type="static-collection"
+>
+</script>
+
+{% liquid
+ assign products_per_page = section.settings.products_per_row | times: section.settings.number_of_rows
+ assign use_masonry = false
+
+ if section.settings.layout == 'masonry'
+ assign use_masonry = true
+ endif
+
+ assign show_filters = false
+ if section.settings.show_filters
+ assign show_filters = true
+ endif
+
+ assign show_sorting = false
+ if section.settings.sorting
+ assign show_sorting = true
+ endif
+
+ assign show_collection_image = false
+ if collection.image and section.settings.show_collection_image
+ assign show_collection_image = true
+ endif
+%}
+
+{%- comment -%} DW collection hero (F1=B) {%- endcomment -%}
+{% render 'dw-collection-hero-bg' %}
+
+<div>
+ {% unless use_masonry %}
+ <h1 class="page-title">{{ collection.title }}</h1>
+ {% render 'breadcrumbs' %}
+ {% endunless %}
+
+ {% paginate collection.products by products_per_page %}
+ <section
+ class="collection collection-image--{{ show_collection_image }}"
+ data-product-hover="{{ settings.product_hover }}"
+ {% if use_masonry %}data-collection-masonry{% endif %}
+ data-section-id="{{ section.id }}"
+ data-section-type="collection">
+
+ {% if use_masonry or show_collection_image or collection.description != blank or show_sorting or show_filters %}
+ <div
+ class="
+ collection-header
+ {% if use_masonry %}
+ collection-header-alternate
+ {% endif %}
+ {% if show_filters and show_sorting %}
+ collection-header--filters-sort-enabled
+ {% endif %}
+ "
+ >
+ {% if show_collection_image %}
+ <div class="collection-featured-image">
+ {%
+ render 'rimg',
+ img: collection.image,
+ size: '1024x1024',
+ lazy: true,
+ %}
+ </div>
+ {% endif %}
+
+ <div class="collection-header-content">
+ {% if use_masonry %}
+ {% render 'breadcrumbs' %}
+ <h1 class="page-title">{{ collection.title }}</h1>
+ {% endif %}
+
+ {% if collection.description != blank and section.settings.show_description %}
+ <div class="collection-description rte">
+ {{ collection.description }}
+ </div>
+ {% endif %}
+
+ {% if show_filters or show_sorting %}
+ <div class="collection-filters">
+ {% if show_filters and collection.filters.size > 0 %}
+ <!-- Approach B: Horizontal filter bar (proxies to Boost's hidden controls) -->
+ {% render 'collection-filters-horizontal' %}
+
+ <!-- Boost native filters (hidden by Approach B CSS, powers the filtering) -->
+ <div class="faceted-filters" data-faceted-filter>
+ {%
+ render "faceted-filters",
+ filters: collection.filters,
+ class_prefix: 'collection',
+ %}
+ </div>
+ {% endif %}
+ {% if show_sorting %}
+ <div class="collection-sorting__wrapper">
+ <label class="collection-filters__title label" for="sort-by">
+ {{- 'collections.collection.sort_title' | t -}}:
+ </label>
+
+ <div
+ class="
+ collection-dropdown
+ collection-dropdown--sort
+ select-wrapper
+ {% if collection.current_vendor %}
+ vendor-collection
+ {% endif %}
+ "
+ >
+ {% assign current_sort = collection.sort_by | default: collection.default_sort_by %}
+
+ <span class="selected-text"></span>
+
+ <select id="sort-by" class="select" data-collection-sorting>
+ {%- for option in collection.sort_options -%}
+ {% if current_sort == option.value %}
+ <option value="{{ option.value }}" selected="selected">{{ option.name }}</option>
+ {% else %}
+ <option value="{{ option.value }}">{{ option.name }}</option>
+ {% endif %}
+ {% endfor %}
+ </select>
+ </div>
+ </div>
+ {% endif %}
+ </div>
+ {% endif %}
+ </div>
+
+ {% if show_filters and collection.filters.size > 0 %}
+ {% for filter in collection.filters %}
+ {% if filter.active_values.size > 0 or filter.min_value.value or filter.max_value.value %}
+ {%-
+ render 'faceted-filters-active',
+ show_sorting: show_sorting,
+ filter: filter,
+ filters: collection.filters,
+ class_prefix: 'collection',
+ clear_url: collection.url,
+ %}
+ {% break %}
+ {% endif %}
+ {% endfor %}
+ {% endif %}
+ </div>
+ {% endif %}
+
+ <!-- Full Collection Toolbar: Sort + Grid Density Slider -->
+ {% include 'collection-toolbar' %}
+
+ <div
+ class="collection-products rows-of-{{ section.settings.products_per_row }} grid-cols-3"
+ data-collection-grid
+ {% if use_masonry %}data-masonry-grid{% endif %}
+ >
+ {%- if use_masonry -%}
+ <div class="product-grid-masonry-sizer" data-masonry-sizer></div>
+ {%- endif -%}
+
+ {%- if collection.handle == 'all' and collection.all_vendors.size == 0 and collection.all_types.size == 0 -%}
+ {%- for i in (1..section.settings.products_per_row) -%}
+ {%- capture productImage -%}
+ {%- cycle 'product-1', 'product-2', 'product-3' -%}
+ {%- endcapture -%}
+ {%- assign image = productImage | placeholder_svg_tag: 'placeholder-svg' -%}
+
+ {%- render 'home-onboard-product', image: image -%}
+ {%- endfor -%}
+ {%- else -%}
+ {% for product in collection.products %}
+ {%
+ render 'product-list-item',
+ product: product,
+ %}
+ {% else %}
+ {% capture continueLink %}
+ <a href="{{ routes.all_products_collection_url }}">{{ 'collections.collection.continue_link' | t }}</a>
+ {% endcapture %}
+ <p class="empty">{{ 'collections.collection.empty_html' | t: continue_link: continueLink }}</p>
+ {% endfor %}
+ {%- endif -%}
+ </div>
+ </section>
+
+ {%
+ render 'pagination',
+ paginate: paginate,
+ %}
+ {% endpaginate %}
+</div>
+
+<script src="{{ 'collection-grid-density.js' | asset_url }}" defer></script>
+
+{% schema %}
+{
+ "name": "Collection pages",
+ "settings": [
+ {
+ "type": "checkbox",
+ "id": "show_collection_image",
+ "label": "Show collection image"
+ },
+ {
+ "type": "checkbox",
+ "id": "show_description",
+ "label": "Show description"
+ },
+ {
+ "type": "checkbox",
+ "id": "sorting",
+ "label": "Enable sorting",
+ "info": "Parameters include: best selling, A-Z, newest to oldest, etc."
+ },
+ {
+ "type": "checkbox",
+ "id": "show_filters",
+ "label": "Enable filtering",
+ "default": true
+ },
+ {
+ "type": "select",
+ "id": "layout",
+ "label": "Layout",
+ "options": [
+ {
+ "value": "default",
+ "label": "Default"
+ },
+ {
+ "value": "masonry",
+ "label": "Masonry"
+ }
+ ],
+ "default": "default"
+ },
+ {
+ "type": "range",
+ "id": "products_per_row",
+ "label": "Products per row",
+ "min": 2,
+ "max": 4,
+ "step": 1,
+ "default": 3
+ },
+ {
+ "type": "range",
+ "id": "number_of_rows",
+ "label": "Rows",
+ "min": 1,
+ "max": 12,
+ "step": 1,
+ "default": 3
+ }
+ ]
+}
+
+{% endschema %}
diff --git a/shopify/collection-hero-fix/backups/sections_collection.liquid.live-142250278963.pushbak b/shopify/collection-hero-fix/backups/sections_collection.liquid.live-142250278963.pushbak
new file mode 100644
index 00000000..c404beb9
--- /dev/null
+++ b/shopify/collection-hero-fix/backups/sections_collection.liquid.live-142250278963.pushbak
@@ -0,0 +1,259 @@
+<script
+ type="application/json"
+ data-section-id="{{ section.id }}"
+ data-section-type="static-collection"
+>
+</script>
+
+{% liquid
+ assign products_per_page = section.settings.products_per_row | times: section.settings.number_of_rows
+ assign use_masonry = false
+
+ if section.settings.layout == 'masonry'
+ assign use_masonry = true
+ endif
+
+ assign show_filters = false
+ if section.settings.show_filters
+ assign show_filters = true
+ endif
+
+ assign show_sorting = false
+ if section.settings.sorting
+ assign show_sorting = true
+ endif
+
+ assign show_collection_image = false
+ if collection.image and section.settings.show_collection_image
+ assign show_collection_image = true
+ endif
+%}
+
+<div>
+ {% unless use_masonry %}
+ <h1 class="page-title">{{ collection.title }}</h1>
+ {% render 'breadcrumbs' %}
+ {% endunless %}
+
+ {% paginate collection.products by products_per_page %}
+ <section
+ class="collection collection-image--{{ show_collection_image }}"
+ data-product-hover="{{ settings.product_hover }}"
+ {% if use_masonry %}data-collection-masonry{% endif %}
+ data-section-id="{{ section.id }}"
+ data-section-type="collection">
+
+ {% if use_masonry or show_collection_image or collection.description != blank or show_sorting or show_filters %}
+ <div
+ class="
+ collection-header
+ {% if use_masonry %}
+ collection-header-alternate
+ {% endif %}
+ {% if show_filters and show_sorting %}
+ collection-header--filters-sort-enabled
+ {% endif %}
+ "
+ >
+ {% if show_collection_image %}
+ <div class="collection-featured-image">
+ {%
+ render 'rimg',
+ img: collection.image,
+ size: '1024x1024',
+ lazy: true,
+ %}
+ </div>
+ {% endif %}
+
+ <div class="collection-header-content">
+ {% if use_masonry %}
+ {% render 'breadcrumbs' %}
+ <h1 class="page-title">{{ collection.title }}</h1>
+ {% endif %}
+
+ {% if collection.description != blank and section.settings.show_description %}
+ <div class="collection-description rte">
+ {{ collection.description }}
+ </div>
+ {% endif %}
+
+ {% if show_filters or show_sorting %}
+ <div class="collection-filters">
+ {% if show_filters and collection.filters.size > 0 %}
+ <!-- Approach B: Horizontal filter bar (proxies to Boost's hidden controls) -->
+ {% render 'collection-filters-horizontal' %}
+
+ <!-- Boost native filters (hidden by Approach B CSS, powers the filtering) -->
+ <div class="faceted-filters" data-faceted-filter>
+ {%
+ render "faceted-filters",
+ filters: collection.filters,
+ class_prefix: 'collection',
+ %}
+ </div>
+ {% endif %}
+ {% if show_sorting %}
+ <div class="collection-sorting__wrapper">
+ <label class="collection-filters__title label" for="sort-by">
+ {{- 'collections.collection.sort_title' | t -}}:
+ </label>
+
+ <div
+ class="
+ collection-dropdown
+ collection-dropdown--sort
+ select-wrapper
+ {% if collection.current_vendor %}
+ vendor-collection
+ {% endif %}
+ "
+ >
+ {% assign current_sort = collection.sort_by | default: collection.default_sort_by %}
+
+ <span class="selected-text"></span>
+
+ <select id="sort-by" class="select" data-collection-sorting>
+ {%- for option in collection.sort_options -%}
+ {% if current_sort == option.value %}
+ <option value="{{ option.value }}" selected="selected">{{ option.name }}</option>
+ {% else %}
+ <option value="{{ option.value }}">{{ option.name }}</option>
+ {% endif %}
+ {% endfor %}
+ </select>
+ </div>
+ </div>
+ {% endif %}
+ </div>
+ {% endif %}
+ </div>
+
+ {% if show_filters and collection.filters.size > 0 %}
+ {% for filter in collection.filters %}
+ {% if filter.active_values.size > 0 or filter.min_value.value or filter.max_value.value %}
+ {%-
+ render 'faceted-filters-active',
+ show_sorting: show_sorting,
+ filter: filter,
+ filters: collection.filters,
+ class_prefix: 'collection',
+ clear_url: collection.url,
+ %}
+ {% break %}
+ {% endif %}
+ {% endfor %}
+ {% endif %}
+ </div>
+ {% endif %}
+
+ <!-- Full Collection Toolbar: Sort + Grid Density Slider -->
+ {% include 'collection-toolbar' %}
+
+ <div
+ class="collection-products rows-of-{{ section.settings.products_per_row }} grid-cols-3"
+ data-collection-grid
+ {% if use_masonry %}data-masonry-grid{% endif %}
+ >
+ {%- if use_masonry -%}
+ <div class="product-grid-masonry-sizer" data-masonry-sizer></div>
+ {%- endif -%}
+
+ {%- if collection.handle == 'all' and collection.all_vendors.size == 0 and collection.all_types.size == 0 -%}
+ {%- for i in (1..section.settings.products_per_row) -%}
+ {%- capture productImage -%}
+ {%- cycle 'product-1', 'product-2', 'product-3' -%}
+ {%- endcapture -%}
+ {%- assign image = productImage | placeholder_svg_tag: 'placeholder-svg' -%}
+
+ {%- render 'home-onboard-product', image: image -%}
+ {%- endfor -%}
+ {%- else -%}
+ {% for product in collection.products %}
+ {%
+ render 'product-list-item',
+ product: product,
+ %}
+ {% else %}
+ {% capture continueLink %}
+ <a href="{{ routes.all_products_collection_url }}">{{ 'collections.collection.continue_link' | t }}</a>
+ {% endcapture %}
+ <p class="empty">{{ 'collections.collection.empty_html' | t: continue_link: continueLink }}</p>
+ {% endfor %}
+ {%- endif -%}
+ </div>
+ </section>
+
+ {%
+ render 'pagination',
+ paginate: paginate,
+ %}
+ {% endpaginate %}
+</div>
+
+<script src="{{ 'collection-grid-density.js' | asset_url }}" defer></script>
+
+{% schema %}
+{
+ "name": "Collection pages",
+ "settings": [
+ {
+ "type": "checkbox",
+ "id": "show_collection_image",
+ "label": "Show collection image"
+ },
+ {
+ "type": "checkbox",
+ "id": "show_description",
+ "label": "Show description"
+ },
+ {
+ "type": "checkbox",
+ "id": "sorting",
+ "label": "Enable sorting",
+ "info": "Parameters include: best selling, A-Z, newest to oldest, etc."
+ },
+ {
+ "type": "checkbox",
+ "id": "show_filters",
+ "label": "Enable filtering",
+ "default": true
+ },
+ {
+ "type": "select",
+ "id": "layout",
+ "label": "Layout",
+ "options": [
+ {
+ "value": "default",
+ "label": "Default"
+ },
+ {
+ "value": "masonry",
+ "label": "Masonry"
+ }
+ ],
+ "default": "default"
+ },
+ {
+ "type": "range",
+ "id": "products_per_row",
+ "label": "Products per row",
+ "min": 2,
+ "max": 4,
+ "step": 1,
+ "default": 3
+ },
+ {
+ "type": "range",
+ "id": "number_of_rows",
+ "label": "Rows",
+ "min": 1,
+ "max": 12,
+ "step": 1,
+ "default": 3
+ }
+ ]
+}
+
+{% endschema %}
\ No newline at end of file
diff --git a/shopify/collection-hero-fix/dw-collection-hero.css b/shopify/collection-hero-fix/dw-collection-hero.css
index 006e73cd..36bc48c4 100644
--- a/shopify/collection-hero-fix/dw-collection-hero.css
+++ b/shopify/collection-hero-fix/dw-collection-hero.css
@@ -53,6 +53,39 @@ body.template-collection .boost-sd__product-filter-fallback .page-title {
background-position: center;
}
+/* --- ROTATING HERO (DTD source=A / curation=C). The snippet emits a
+ [data-dw-hero-rotator] container with N .dw-hero-slide layers; the rotator
+ JS relocates it into the Boost/theme header band as a full-bleed back layer
+ and crossfades the slides. Each slide is an absolutely-positioned cover
+ image with a baked-in legibility scrim. Active slide fades in over the
+ previous one — NO layout shift (the band keeps its min-height). Identical on
+ mobile + desktop (the band is responsive). --- */
+.dw-hero-rotator {
+ position: absolute;
+ inset: 0;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ pointer-events: none;
+ z-index: 0;
+}
+.dw-hero-slide {
+ position: absolute;
+ inset: 0;
+ background-size: cover;
+ background-position: center;
+ background-repeat: no-repeat;
+ opacity: 0;
+ transition: opacity 1100ms ease-in-out;
+ will-change: opacity;
+}
+.dw-hero-slide.is-active { opacity: 1; }
+/* Reduced motion: the JS holds frame 1 and skips the timer; also kill the
+ fade transition so there is zero animation for those users. */
+@media (prefers-reduced-motion: reduce) {
+ .dw-hero-slide { transition: none; }
+}
+
/* The Boost (and theme) header title, hoisted into the hero band.
IMAGE PRESENT: keep white text + dark pill (legible over photo). */
.dw-collection-hero.dw-has-image .boost-sd__header-title,
@@ -108,16 +141,21 @@ body:not(.dw-collection-has-hero) .boost-sd__collection-header:not(:has(.boost-s
.dw-collection-hero.dw-has-image .boost-sd__header-description,
.dw-collection-hero.dw-has-image .boost-sd__header-description * { color: rgba(255,255,255,.92) !important; }
-/* --- F3: mobile header gap.
- theme.css mobile media query gives .header-branding{padding:36px 0}, making a
- 118px logo block with a big empty gap, while the CART(0) tools bar floats
- 42px above. Tighten both so the logo sits up near the cart. Surgical +
- reversible — only at mobile widths. --- */
-@media (max-width: 768px) {
- .header-branding { padding: 14px 0 !important; }
+/* --- F3 (FIXED, specificity cascade): mobile header gap.
+ theme.css ships `@media (max-width:769px){ .header-branding{padding:36px 0} }`
+ — a SINGLE-class rule (specificity 0,1,0) in theme.css, which loads AFTER
+ custom.css. Our earlier `.header-branding{...!important}` at max-width:768px
+ lost because it sat in the EARLIER sheet at the SAME specificity AND a
+ breakpoint mismatch (768 vs the theme's 769) left a 1px dead band. Fix WITHOUT
+ !important by RAISING SPECIFICITY: scope to `body.template-collection` (0,2,0)
+ which cleanly outranks the theme's 0,1,0, and MATCH the theme's 769px
+ breakpoint so the rule fires in the exact same media context. This drops the
+ branding block ~118px -> ~74px and closes the CART(0)->logo gap. --- */
+@media (max-width: 769px) {
+ body.template-collection .header-branding { padding: 14px 0; }
/* trim the standalone tools bar so cart isn't marooned at the top */
- .header-tools-wrapper { padding-top: 4px !important; padding-bottom: 0 !important; }
- .header-tools { padding-top: 0 !important; padding-bottom: 0 !important; }
+ body.template-collection .header-tools-wrapper { padding-top: 4px; padding-bottom: 0; }
+ body.template-collection .header-tools { padding-top: 0; padding-bottom: 0; }
/* pull the logo+icons row up closer to the cart row */
- .header-main-content { padding-top: 4px !important; }
+ body.template-collection .header-main-content { padding-top: 4px; }
}
diff --git a/shopify/collection-hero-fix/dw-hero-rotator.js b/shopify/collection-hero-fix/dw-hero-rotator.js
new file mode 100644
index 00000000..ba4474a9
--- /dev/null
+++ b/shopify/collection-hero-fix/dw-hero-rotator.js
@@ -0,0 +1,141 @@
+/* ====================================================================
+ DW collection-page rotating new-arrivals hero — crossfade rotator.
+ Owner: vp-dw-commerce · 2026-06-23 · DTD source=A / curation=C(hybrid).
+
+ The hero slides are emitted by snippet 'dw-collection-hero-bg' into a
+ [data-dw-hero-rotator] container that the theme renders ABOVE the
+ collection header. Boost-SD renders the real header band asynchronously,
+ so this script:
+ 1. Waits for the Boost header (or theme header) to exist,
+ 2. Relocates the rotator container INTO that header band as an
+ absolutely-positioned full-bleed layer behind the title,
+ 3. Crossfades the slides on a timer with no layout shift,
+ 4. Preloads the next image so the fade never reveals a blank frame,
+ 5. Honors prefers-reduced-motion (holds on frame 1, no timer),
+ 6. Pauses while the tab is hidden (Page Visibility) to save cycles.
+
+ Self-contained, dependency-free, idempotent (guards against double-init).
+ Mobile + desktop identical (the band is responsive via CSS).
+ Remove: delete this asset + its <script> include + the snippet.
+ ==================================================================== */
+(function () {
+ 'use strict';
+ if (window.__dwHeroRotatorInit) return;
+ window.__dwHeroRotatorInit = true;
+
+ var HEADER_SELECTORS = [
+ '.boost-sd__collection-header',
+ '.template-collection .collection-header',
+ '.collection-header'
+ ];
+
+ function findHeader() {
+ for (var i = 0; i < HEADER_SELECTORS.length; i++) {
+ var el = document.querySelector(HEADER_SELECTORS[i]);
+ if (el) return el;
+ }
+ return null;
+ }
+
+ function start(rotator, header) {
+ if (rotator.__dwStarted) return;
+ rotator.__dwStarted = true;
+
+ // Relocate the rotator into the header band as a full-bleed back layer.
+ rotator.style.position = 'absolute';
+ rotator.style.top = '0';
+ rotator.style.left = '0';
+ rotator.style.right = '0';
+ rotator.style.bottom = '0';
+ rotator.style.width = '100%';
+ rotator.style.height = '100%';
+ rotator.style.zIndex = '0';
+ rotator.style.pointerEvents = 'none';
+ if (getComputedStyle(header).position === 'static') {
+ header.style.position = 'relative';
+ }
+ if (rotator.parentElement !== header) {
+ header.insertBefore(rotator, header.firstChild);
+ }
+
+ var slides = Array.prototype.slice.call(
+ rotator.querySelectorAll('.dw-hero-slide')
+ );
+ if (!slides.length) return;
+
+ // Single slide (curated-only, or rotation off) -> just show it, no timer.
+ if (slides.length === 1) {
+ slides[0].classList.add('is-active');
+ return;
+ }
+
+ // prefers-reduced-motion -> hold on frame 1, no rotation.
+ var reduce = window.matchMedia &&
+ window.matchMedia('(prefers-reduced-motion: reduce)').matches;
+ if (reduce) {
+ slides.forEach(function (s, i) {
+ s.classList.toggle('is-active', i === 0);
+ });
+ return;
+ }
+
+ // Preload all slide images so a fade never reveals a blank frame.
+ slides.forEach(function (s) {
+ var m = /url\((['"]?)(.*?)\1\)/.exec(s.style.backgroundImage || '');
+ if (m && m[2]) {
+ var pre = new Image();
+ pre.src = m[2];
+ }
+ });
+
+ var interval = parseInt(rotator.getAttribute('data-interval'), 10);
+ if (!interval || interval < 2000) interval = 5200;
+
+ var cur = 0;
+ slides.forEach(function (s, i) { s.classList.toggle('is-active', i === 0); });
+
+ var timer = null;
+ function next() {
+ var nextIdx = (cur + 1) % slides.length;
+ slides[nextIdx].classList.add('is-active');
+ slides[cur].classList.remove('is-active');
+ cur = nextIdx;
+ }
+ function play() { if (!timer) timer = setInterval(next, interval); }
+ function pause() { if (timer) { clearInterval(timer); timer = null; } }
+
+ document.addEventListener('visibilitychange', function () {
+ if (document.hidden) pause(); else play();
+ });
+ play();
+ }
+
+ function attach() {
+ var rotator = document.querySelector('[data-dw-hero-rotator]');
+ if (!rotator) return false;
+ var header = findHeader();
+ if (!header) return false;
+ start(rotator, header);
+ return true;
+ }
+
+ // Try immediately, then observe for Boost hydrating the header in late.
+ function init() {
+ if (attach()) return;
+ var tries = 0;
+ var mo = new MutationObserver(function () {
+ if (attach() || ++tries > 200) mo.disconnect();
+ });
+ mo.observe(document.documentElement, { childList: true, subtree: true });
+ // Safety: also poll for ~12s in case the header swaps without a mutation we catch.
+ var poll = setInterval(function () {
+ if (attach() || ++tries > 200) clearInterval(poll);
+ }, 250);
+ }
+
+ if (document.readyState === 'loading') {
+ document.addEventListener('DOMContentLoaded', init);
+ } else {
+ init();
+ }
+})();
diff --git a/shopify/collection-hero-fix/patched/assets_dw-hero-rotator.js b/shopify/collection-hero-fix/patched/assets_dw-hero-rotator.js
new file mode 100644
index 00000000..ba4474a9
--- /dev/null
+++ b/shopify/collection-hero-fix/patched/assets_dw-hero-rotator.js
@@ -0,0 +1,141 @@
+/* ====================================================================
+ DW collection-page rotating new-arrivals hero — crossfade rotator.
+ Owner: vp-dw-commerce · 2026-06-23 · DTD source=A / curation=C(hybrid).
+
+ The hero slides are emitted by snippet 'dw-collection-hero-bg' into a
+ [data-dw-hero-rotator] container that the theme renders ABOVE the
+ collection header. Boost-SD renders the real header band asynchronously,
+ so this script:
+ 1. Waits for the Boost header (or theme header) to exist,
+ 2. Relocates the rotator container INTO that header band as an
+ absolutely-positioned full-bleed layer behind the title,
+ 3. Crossfades the slides on a timer with no layout shift,
+ 4. Preloads the next image so the fade never reveals a blank frame,
+ 5. Honors prefers-reduced-motion (holds on frame 1, no timer),
+ 6. Pauses while the tab is hidden (Page Visibility) to save cycles.
+
+ Self-contained, dependency-free, idempotent (guards against double-init).
+ Mobile + desktop identical (the band is responsive via CSS).
+ Remove: delete this asset + its <script> include + the snippet.
+ ==================================================================== */
+(function () {
+ 'use strict';
+ if (window.__dwHeroRotatorInit) return;
+ window.__dwHeroRotatorInit = true;
+
+ var HEADER_SELECTORS = [
+ '.boost-sd__collection-header',
+ '.template-collection .collection-header',
+ '.collection-header'
+ ];
+
+ function findHeader() {
+ for (var i = 0; i < HEADER_SELECTORS.length; i++) {
+ var el = document.querySelector(HEADER_SELECTORS[i]);
+ if (el) return el;
+ }
+ return null;
+ }
+
+ function start(rotator, header) {
+ if (rotator.__dwStarted) return;
+ rotator.__dwStarted = true;
+
+ // Relocate the rotator into the header band as a full-bleed back layer.
+ rotator.style.position = 'absolute';
+ rotator.style.top = '0';
+ rotator.style.left = '0';
+ rotator.style.right = '0';
+ rotator.style.bottom = '0';
+ rotator.style.width = '100%';
+ rotator.style.height = '100%';
+ rotator.style.zIndex = '0';
+ rotator.style.pointerEvents = 'none';
+ if (getComputedStyle(header).position === 'static') {
+ header.style.position = 'relative';
+ }
+ if (rotator.parentElement !== header) {
+ header.insertBefore(rotator, header.firstChild);
+ }
+
+ var slides = Array.prototype.slice.call(
+ rotator.querySelectorAll('.dw-hero-slide')
+ );
+ if (!slides.length) return;
+
+ // Single slide (curated-only, or rotation off) -> just show it, no timer.
+ if (slides.length === 1) {
+ slides[0].classList.add('is-active');
+ return;
+ }
+
+ // prefers-reduced-motion -> hold on frame 1, no rotation.
+ var reduce = window.matchMedia &&
+ window.matchMedia('(prefers-reduced-motion: reduce)').matches;
+ if (reduce) {
+ slides.forEach(function (s, i) {
+ s.classList.toggle('is-active', i === 0);
+ });
+ return;
+ }
+
+ // Preload all slide images so a fade never reveals a blank frame.
+ slides.forEach(function (s) {
+ var m = /url\((['"]?)(.*?)\1\)/.exec(s.style.backgroundImage || '');
+ if (m && m[2]) {
+ var pre = new Image();
+ pre.src = m[2];
+ }
+ });
+
+ var interval = parseInt(rotator.getAttribute('data-interval'), 10);
+ if (!interval || interval < 2000) interval = 5200;
+
+ var cur = 0;
+ slides.forEach(function (s, i) { s.classList.toggle('is-active', i === 0); });
+
+ var timer = null;
+ function next() {
+ var nextIdx = (cur + 1) % slides.length;
+ slides[nextIdx].classList.add('is-active');
+ slides[cur].classList.remove('is-active');
+ cur = nextIdx;
+ }
+ function play() { if (!timer) timer = setInterval(next, interval); }
+ function pause() { if (timer) { clearInterval(timer); timer = null; } }
+
+ document.addEventListener('visibilitychange', function () {
+ if (document.hidden) pause(); else play();
+ });
+ play();
+ }
+
+ function attach() {
+ var rotator = document.querySelector('[data-dw-hero-rotator]');
+ if (!rotator) return false;
+ var header = findHeader();
+ if (!header) return false;
+ start(rotator, header);
+ return true;
+ }
+
+ // Try immediately, then observe for Boost hydrating the header in late.
+ function init() {
+ if (attach()) return;
+ var tries = 0;
+ var mo = new MutationObserver(function () {
+ if (attach() || ++tries > 200) mo.disconnect();
+ });
+ mo.observe(document.documentElement, { childList: true, subtree: true });
+ // Safety: also poll for ~12s in case the header swaps without a mutation we catch.
+ var poll = setInterval(function () {
+ if (attach() || ++tries > 200) clearInterval(poll);
+ }, 250);
+ }
+
+ if (document.readyState === 'loading') {
+ document.addEventListener('DOMContentLoaded', init);
+ } else {
+ init();
+ }
+})();
diff --git a/shopify/collection-hero-fix/patched/dw-collection-hero.css b/shopify/collection-hero-fix/patched/dw-collection-hero.css
new file mode 100644
index 00000000..36bc48c4
--- /dev/null
+++ b/shopify/collection-hero-fix/patched/dw-collection-hero.css
@@ -0,0 +1,161 @@
+/* ====================================================================
+ DW COLLECTION HERO + DUP-TITLE + MOBILE-HEADER FIX
+ Owner: vp-dw-commerce · 2026-06-23 · DTD verdict F1=B / F2=A / F3=A
+ Appended (marked + idempotent) to a theme-controlled CSS asset.
+ Pairs with snippet 'dw-collection-hero-bg' (emits the per-collection
+ background-image inline) for the F1=B always-on hero.
+ Removable: delete everything between the START/END markers.
+ ==================================================================== */
+
+/* --- F2: kill the duplicate theme leftover title on collection pages.
+ Boost's h1.boost-sd__header-title is the live header (carries image +
+ description); the OOTS theme h1.page-title is a pre-Boost leftover that
+ stacks the same text. Hide the theme one ONLY on collection templates. --- */
+body.template-collection .collection > div > .page-title,
+body.template-collection section.collection .collection-header-content > .page-title,
+body.template-collection .boost-sd__product-filter-fallback .page-title {
+ display: none !important;
+}
+
+/* --- F1: the collection hero band.
+ .dw-collection-hero is a wrapper the snippet emits around the Boost header
+ (or, pre-hydration, the theme header). It always shows a background:
+ collection.image when set, else settings.collection_default_hero, else a
+ soft branded gradient. The title pill stays white-on-image ONLY when a real
+ image is behind it; with no image the title is clean centered dark type on
+ the soft band (no naked dark pill, no flat grey dead-block). --- */
+
+.dw-collection-hero {
+ position: relative;
+ width: 100%;
+ min-height: 220px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ text-align: center;
+ /* default soft branded band when no image var is set */
+ background:
+ linear-gradient(180deg, rgba(0,0,0,0.04), rgba(0,0,0,0.02)),
+ #f4f2ee;
+ background-size: cover;
+ background-position: center;
+ overflow: hidden;
+ margin-bottom: 8px;
+}
+
+/* When the snippet sets --dw-hero-img, paint it as a real cover background
+ with a legibility scrim so the white pill reads. */
+.dw-collection-hero[style*="--dw-hero-img"] {
+ background-image:
+ linear-gradient(180deg, rgba(0,0,0,0.18), rgba(0,0,0,0.34)),
+ var(--dw-hero-img);
+ background-size: cover;
+ background-position: center;
+}
+
+/* --- ROTATING HERO (DTD source=A / curation=C). The snippet emits a
+ [data-dw-hero-rotator] container with N .dw-hero-slide layers; the rotator
+ JS relocates it into the Boost/theme header band as a full-bleed back layer
+ and crossfades the slides. Each slide is an absolutely-positioned cover
+ image with a baked-in legibility scrim. Active slide fades in over the
+ previous one — NO layout shift (the band keeps its min-height). Identical on
+ mobile + desktop (the band is responsive). --- */
+.dw-hero-rotator {
+ position: absolute;
+ inset: 0;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ pointer-events: none;
+ z-index: 0;
+}
+.dw-hero-slide {
+ position: absolute;
+ inset: 0;
+ background-size: cover;
+ background-position: center;
+ background-repeat: no-repeat;
+ opacity: 0;
+ transition: opacity 1100ms ease-in-out;
+ will-change: opacity;
+}
+.dw-hero-slide.is-active { opacity: 1; }
+/* Reduced motion: the JS holds frame 1 and skips the timer; also kill the
+ fade transition so there is zero animation for those users. */
+@media (prefers-reduced-motion: reduce) {
+ .dw-hero-slide { transition: none; }
+}
+
+/* The Boost (and theme) header title, hoisted into the hero band.
+ IMAGE PRESENT: keep white text + dark pill (legible over photo). */
+.dw-collection-hero.dw-has-image .boost-sd__header-title,
+.dw-collection-hero.dw-has-image .page-title {
+ color: #fff !important;
+ background: rgba(0,0,0,0.42) !important;
+ border-radius: 4px !important;
+ padding: 12px 28px !important;
+ display: inline-block !important;
+ text-shadow: 0 1px 18px rgba(0,0,0,0.45);
+}
+
+/* NO IMAGE: clean centered dark type, NO pill, NO grey block. */
+.dw-collection-hero:not(.dw-has-image) .boost-sd__header-title,
+.dw-collection-hero:not(.dw-has-image) .page-title {
+ color: #1a1a1a !important;
+ background: transparent !important;
+ border-radius: 0 !important;
+ padding: 0 !important;
+ text-shadow: none !important;
+ letter-spacing: .14em;
+ text-transform: uppercase;
+ font-weight: 300;
+}
+
+/* Belt-and-suspenders: neutralize Boost's default dark pill whenever the
+ collection has NO hero. "No hero" = the snippet did NOT add .dw-has-hero
+ (set only when collection.image OR settings.collection_default_hero exists)
+ AND Boost rendered no native image-inner. Excludes .dw-has-hero so the
+ image case (painted by the snippet's inline <style>) is never stripped. */
+body:not(.dw-collection-has-hero) .boost-sd__collection-header:not(:has(.boost-sd__header-image-inner)) .boost-sd__header-title {
+ background: transparent !important;
+ color: #1a1a1a !important;
+ border-radius: 0 !important;
+ padding: 14px 0 !important;
+ text-shadow: none !important;
+ letter-spacing: .14em;
+ text-transform: uppercase;
+ font-weight: 300;
+}
+body:not(.dw-collection-has-hero) .boost-sd__collection-header:not(:has(.boost-sd__header-image-inner)) {
+ background: #f4f2ee;
+ min-height: 200px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ text-align: center;
+}
+
+/* keep the description readable inside the band */
+.dw-collection-hero .boost-sd__header-description,
+.dw-collection-hero .collection-description { margin-top: 10px; }
+.dw-collection-hero.dw-has-image .boost-sd__header-description,
+.dw-collection-hero.dw-has-image .boost-sd__header-description * { color: rgba(255,255,255,.92) !important; }
+
+/* --- F3 (FIXED, specificity cascade): mobile header gap.
+ theme.css ships `@media (max-width:769px){ .header-branding{padding:36px 0} }`
+ — a SINGLE-class rule (specificity 0,1,0) in theme.css, which loads AFTER
+ custom.css. Our earlier `.header-branding{...!important}` at max-width:768px
+ lost because it sat in the EARLIER sheet at the SAME specificity AND a
+ breakpoint mismatch (768 vs the theme's 769) left a 1px dead band. Fix WITHOUT
+ !important by RAISING SPECIFICITY: scope to `body.template-collection` (0,2,0)
+ which cleanly outranks the theme's 0,1,0, and MATCH the theme's 769px
+ breakpoint so the rule fires in the exact same media context. This drops the
+ branding block ~118px -> ~74px and closes the CART(0)->logo gap. --- */
+@media (max-width: 769px) {
+ body.template-collection .header-branding { padding: 14px 0; }
+ /* trim the standalone tools bar so cart isn't marooned at the top */
+ body.template-collection .header-tools-wrapper { padding-top: 4px; padding-bottom: 0; }
+ body.template-collection .header-tools { padding-top: 0; padding-bottom: 0; }
+ /* pull the logo+icons row up closer to the cart row */
+ body.template-collection .header-main-content { padding-top: 4px; }
+}
diff --git a/shopify/collection-hero-fix/patched/snippets_dw-collection-hero-bg.liquid b/shopify/collection-hero-fix/patched/snippets_dw-collection-hero-bg.liquid
new file mode 100644
index 00000000..cc97ebd2
--- /dev/null
+++ b/shopify/collection-hero-fix/patched/snippets_dw-collection-hero-bg.liquid
@@ -0,0 +1,128 @@
+{%- comment -%}
+ DW collection hero — ROTATING new-arrivals slideshow (F1=B evolution).
+ Owner: vp-dw-commerce · 2026-06-23 · DTD: source=A (theme-native new-arrivals),
+ curation=C (hybrid: curated collection.image is frame 1, then newest store-wide).
+
+ Behaviour (priority + composition):
+ FRAME 1 (curated floor, if present, in priority order):
+ 1. collection.image (per-collection hero — Steve's HARD rule)
+ 2. settings.collection_default_hero (one branded customizer fallback)
+ FRAMES 2..N (dynamic): the featured images of the newest store-wide active
+ SKUs, read live from collections['new-arrivals'].products. This self-updates
+ as the 18/hr cadence publishes new SKUs into new-arrivals — zero backend.
+ If NEITHER a curated image NOR any new-arrivals image exists -> no slides;
+ the polished imageless band + clean dark type kicks in (dw-collection-hero.css).
+
+ Customizer:
+ settings.collection_hero_rotate (checkbox, default true) — turn the rotation
+ on/off store-wide. When OFF and a curated image exists, only frame 1 shows
+ (Codex's "curated always wins" dissent path). When OFF and no curated image,
+ the single newest new-arrival image shows (still never the grey dead-state).
+
+ Sets html.dw-coll-hero + body.dw-collection-has-hero when ≥1 slide exists, so
+ the CSS switches the title to the white-on-image pill and never strips the band.
+ Targets BOTH the Boost header (live grid) and the theme pre-hydration header.
+ The crossfade is driven by assets/dw-hero-rotator.js (prefers-reduced-motion
+ aware: holds on frame 1 for those users). No layout shift — slides are absolutely
+ positioned inside the fixed-height header band.
+ Remove: delete the render call + this file + assets/dw-hero-rotator.js.
+{%- endcomment -%}
+
+{%- liquid
+ assign rotate_on = true
+ if settings.collection_hero_rotate == false
+ assign rotate_on = false
+ endif
+
+ assign curated_url = ''
+ if collection.image
+ assign curated_url = collection.image | image_url: width: 2000
+ elsif settings.collection_default_hero
+ assign curated_url = settings.collection_default_hero | image_url: width: 2000
+ endif
+
+ assign na = collections['new-arrivals']
+-%}
+
+{%- comment -%} Build the ordered, de-duplicated slide list (max 8). {%- endcomment -%}
+{%- capture dw_hero_slides -%}
+ {%- assign seen = '' -%}
+ {%- if curated_url != blank -%}
+ {{ curated_url }}|||{%- assign seen = curated_url | append: '~' | append: seen -%}
+ {%- endif -%}
+ {%- if rotate_on and na != blank -%}
+ {%- assign count = 0 -%}
+ {%- for p in na.products limit: 16 -%}
+ {%- if p.featured_image -%}
+ {%- assign slide = p.featured_image | image_url: width: 2000 -%}
+ {%- unless seen contains slide -%}
+ {{ slide }}|||{%- assign seen = slide | append: '~' | append: seen -%}{%- assign count = count | plus: 1 -%}
+ {%- endunless -%}
+ {%- endif -%}
+ {%- if count >= 8 -%}{%- break -%}{%- endif -%}
+ {%- endfor -%}
+ {%- endif -%}
+{%- endcapture -%}
+{%- assign dw_hero_slides = dw_hero_slides | strip -%}
+{%- assign slide_list = dw_hero_slides | split: '|||' -%}
+
+{%- if dw_hero_slides != blank -%}
+<script>
+ document.documentElement.classList.add('dw-coll-hero');
+ document.addEventListener('DOMContentLoaded', function () {
+ document.body && document.body.classList.add('dw-collection-has-hero');
+ });
+</script>
+<div class="dw-hero-rotator" aria-hidden="true" data-dw-hero-rotator data-interval="5200">
+ {%- assign idx = 0 -%}
+ {%- for url in slide_list -%}
+ {%- assign u = url | strip -%}
+ {%- if u != blank -%}
+ <div class="dw-hero-slide{% if idx == 0 %} is-active{% endif %}"
+ data-dw-slide="{{ idx }}"
+ style="background-image: linear-gradient(180deg, rgba(0,0,0,0.18), rgba(0,0,0,0.34)), url('{{ u }}');"></div>
+ {%- assign idx = idx | plus: 1 -%}
+ {%- endif -%}
+ {%- endfor -%}
+</div>
+<script src="{{ 'dw-hero-rotator.js' | asset_url }}" defer></script>
+<style>
+ /* Paint the rotator INTO the live Boost header band (and the theme header
+ pre-hydration). The .dw-hero-rotator is rendered just above the header in
+ collection.liquid; CSS pins it to fill the header band behind the title. */
+ .dw-coll-hero .boost-sd__collection-header,
+ .dw-coll-hero .template-collection .collection-header,
+ html.dw-coll-hero .template-collection .collection-header {
+ position: relative;
+ min-height: 240px;
+ display: flex; align-items: center; justify-content: center; text-align: center;
+ background-color: #1a1a1a !important; /* base under the slides while images decode */
+ overflow: hidden;
+ }
+ /* Boost paints opaque inner wrappers (boost-sd__header-main-2 + --middle,
+ bg rgb(246,246,248) / rgb(244,242,238)) that would cover the rotator
+ slides. Make them transparent so the rotating imagery shows through, and
+ lift their content above the slides. */
+ .dw-coll-hero .boost-sd__collection-header .boost-sd__header-main-2,
+ .dw-coll-hero .boost-sd__collection-header .boost-sd__header-main-2--middle,
+ .dw-coll-hero .boost-sd__collection-header .boost-sd__header-main-2-content,
+ .dw-coll-hero .boost-sd__collection-header .boost-sd__header-inner {
+ background: transparent !important;
+ position: relative;
+ z-index: 2;
+ }
+ /* image present -> white pill title (high specificity to win over neutralizer) */
+ body.dw-collection-has-hero .boost-sd__collection-header .boost-sd__header-title,
+ .dw-coll-hero .template-collection .collection-header .page-title {
+ color: #fff !important;
+ background: rgba(0,0,0,0.42) !important;
+ border-radius: 4px !important;
+ padding: 12px 28px !important;
+ display: inline-block !important;
+ text-shadow: 0 1px 18px rgba(0,0,0,0.45);
+ position: relative; z-index: 3;
+ }
+ body.dw-collection-has-hero .boost-sd__collection-header .boost-sd__header-description,
+ body.dw-collection-has-hero .boost-sd__collection-header .boost-sd__header-description * { color: rgba(255,255,255,.92) !important; }
+</style>
+{%- endif -%}
diff --git a/shopify/collection-hero-fix/snippets_dw-collection-hero-bg.liquid b/shopify/collection-hero-fix/snippets_dw-collection-hero-bg.liquid
index 92b5db9c..cc97ebd2 100644
--- a/shopify/collection-hero-fix/snippets_dw-collection-hero-bg.liquid
+++ b/shopify/collection-hero-fix/snippets_dw-collection-hero-bg.liquid
@@ -1,40 +1,117 @@
{%- comment -%}
- DW collection hero background (F1=B). Paints the collection hero band with,
- in priority order:
- 1. collection.image (the per-collection hero — Steve's HARD rule)
- 2. settings.collection_default_hero (one branded fallback, set in customizer)
- 3. nothing -> the soft branded band + clean centered dark type kicks in
- (dw-collection-hero.css), so an imageless collection still looks polished.
- Sets body.dw-collection-has-hero when (1) or (2) exists so the CSS can switch
- the Boost + theme header titles to the white-on-image pill and never strip
- the painted background. Targets BOTH the Boost header (live grid) and the
- theme pre-hydration header so the hero is correct before AND after hydration.
- Owner: vp-dw-commerce · 2026-06-23. Remove: delete the render call + this file.
+ DW collection hero — ROTATING new-arrivals slideshow (F1=B evolution).
+ Owner: vp-dw-commerce · 2026-06-23 · DTD: source=A (theme-native new-arrivals),
+ curation=C (hybrid: curated collection.image is frame 1, then newest store-wide).
+
+ Behaviour (priority + composition):
+ FRAME 1 (curated floor, if present, in priority order):
+ 1. collection.image (per-collection hero — Steve's HARD rule)
+ 2. settings.collection_default_hero (one branded customizer fallback)
+ FRAMES 2..N (dynamic): the featured images of the newest store-wide active
+ SKUs, read live from collections['new-arrivals'].products. This self-updates
+ as the 18/hr cadence publishes new SKUs into new-arrivals — zero backend.
+ If NEITHER a curated image NOR any new-arrivals image exists -> no slides;
+ the polished imageless band + clean dark type kicks in (dw-collection-hero.css).
+
+ Customizer:
+ settings.collection_hero_rotate (checkbox, default true) — turn the rotation
+ on/off store-wide. When OFF and a curated image exists, only frame 1 shows
+ (Codex's "curated always wins" dissent path). When OFF and no curated image,
+ the single newest new-arrival image shows (still never the grey dead-state).
+
+ Sets html.dw-coll-hero + body.dw-collection-has-hero when ≥1 slide exists, so
+ the CSS switches the title to the white-on-image pill and never strips the band.
+ Targets BOTH the Boost header (live grid) and the theme pre-hydration header.
+ The crossfade is driven by assets/dw-hero-rotator.js (prefers-reduced-motion
+ aware: holds on frame 1 for those users). No layout shift — slides are absolutely
+ positioned inside the fixed-height header band.
+ Remove: delete the render call + this file + assets/dw-hero-rotator.js.
{%- endcomment -%}
+
{%- liquid
- assign hero_url = ''
+ assign rotate_on = true
+ if settings.collection_hero_rotate == false
+ assign rotate_on = false
+ endif
+
+ assign curated_url = ''
if collection.image
- assign hero_url = collection.image | image_url: width: 2000
+ assign curated_url = collection.image | image_url: width: 2000
elsif settings.collection_default_hero
- assign hero_url = settings.collection_default_hero | image_url: width: 2000
+ assign curated_url = settings.collection_default_hero | image_url: width: 2000
endif
+
+ assign na = collections['new-arrivals']
-%}
-{%- if hero_url != blank -%}
-<script>document.documentElement.classList.add('dw-coll-hero');document.addEventListener('DOMContentLoaded',function(){document.body&&document.body.classList.add('dw-collection-has-hero');});</script>
+
+{%- comment -%} Build the ordered, de-duplicated slide list (max 8). {%- endcomment -%}
+{%- capture dw_hero_slides -%}
+ {%- assign seen = '' -%}
+ {%- if curated_url != blank -%}
+ {{ curated_url }}|||{%- assign seen = curated_url | append: '~' | append: seen -%}
+ {%- endif -%}
+ {%- if rotate_on and na != blank -%}
+ {%- assign count = 0 -%}
+ {%- for p in na.products limit: 16 -%}
+ {%- if p.featured_image -%}
+ {%- assign slide = p.featured_image | image_url: width: 2000 -%}
+ {%- unless seen contains slide -%}
+ {{ slide }}|||{%- assign seen = slide | append: '~' | append: seen -%}{%- assign count = count | plus: 1 -%}
+ {%- endunless -%}
+ {%- endif -%}
+ {%- if count >= 8 -%}{%- break -%}{%- endif -%}
+ {%- endfor -%}
+ {%- endif -%}
+{%- endcapture -%}
+{%- assign dw_hero_slides = dw_hero_slides | strip -%}
+{%- assign slide_list = dw_hero_slides | split: '|||' -%}
+
+{%- if dw_hero_slides != blank -%}
+<script>
+ document.documentElement.classList.add('dw-coll-hero');
+ document.addEventListener('DOMContentLoaded', function () {
+ document.body && document.body.classList.add('dw-collection-has-hero');
+ });
+</script>
+<div class="dw-hero-rotator" aria-hidden="true" data-dw-hero-rotator data-interval="5200">
+ {%- assign idx = 0 -%}
+ {%- for url in slide_list -%}
+ {%- assign u = url | strip -%}
+ {%- if u != blank -%}
+ <div class="dw-hero-slide{% if idx == 0 %} is-active{% endif %}"
+ data-dw-slide="{{ idx }}"
+ style="background-image: linear-gradient(180deg, rgba(0,0,0,0.18), rgba(0,0,0,0.34)), url('{{ u }}');"></div>
+ {%- assign idx = idx | plus: 1 -%}
+ {%- endif -%}
+ {%- endfor -%}
+</div>
+<script src="{{ 'dw-hero-rotator.js' | asset_url }}" defer></script>
<style>
- body.dw-collection-has-hero .boost-sd__collection-header,
+ /* Paint the rotator INTO the live Boost header band (and the theme header
+ pre-hydration). The .dw-hero-rotator is rendered just above the header in
+ collection.liquid; CSS pins it to fill the header band behind the title. */
+ .dw-coll-hero .boost-sd__collection-header,
.dw-coll-hero .template-collection .collection-header,
- html.dw-coll-hero.template-collection .collection-header {
- background-image:
- linear-gradient(180deg, rgba(0,0,0,0.18), rgba(0,0,0,0.34)),
- url("{{ hero_url }}") !important;
- background-size: cover !important;
- background-position: center !important;
+ html.dw-coll-hero .template-collection .collection-header {
+ position: relative;
min-height: 240px;
display: flex; align-items: center; justify-content: center; text-align: center;
+ background-color: #1a1a1a !important; /* base under the slides while images decode */
+ overflow: hidden;
+ }
+ /* Boost paints opaque inner wrappers (boost-sd__header-main-2 + --middle,
+ bg rgb(246,246,248) / rgb(244,242,238)) that would cover the rotator
+ slides. Make them transparent so the rotating imagery shows through, and
+ lift their content above the slides. */
+ .dw-coll-hero .boost-sd__collection-header .boost-sd__header-main-2,
+ .dw-coll-hero .boost-sd__collection-header .boost-sd__header-main-2--middle,
+ .dw-coll-hero .boost-sd__collection-header .boost-sd__header-main-2-content,
+ .dw-coll-hero .boost-sd__collection-header .boost-sd__header-inner {
+ background: transparent !important;
+ position: relative;
+ z-index: 2;
}
- /* image present -> white pill title (high specificity to win over the
- no-hero neutralizer) */
+ /* image present -> white pill title (high specificity to win over neutralizer) */
body.dw-collection-has-hero .boost-sd__collection-header .boost-sd__header-title,
.dw-coll-hero .template-collection .collection-header .page-title {
color: #fff !important;
@@ -43,6 +120,7 @@
padding: 12px 28px !important;
display: inline-block !important;
text-shadow: 0 1px 18px rgba(0,0,0,0.45);
+ position: relative; z-index: 3;
}
body.dw-collection-has-hero .boost-sd__collection-header .boost-sd__header-description,
body.dw-collection-has-hero .boost-sd__collection-header .boost-sd__header-description * { color: rgba(255,255,255,.92) !important; }
diff --git a/verify-rotating-hero.js b/verify-rotating-hero.js
new file mode 100644
index 00000000..c5dfa878
--- /dev/null
+++ b/verify-rotating-hero.js
@@ -0,0 +1,161 @@
+// Verify the ROTATING new-arrivals hero + F3 mobile fix by applying the EXACT
+// staged CSS + the snippet's rendered slide markup + the rotator JS onto the
+// real live collection-page DOM, both viewports (1440 desktop, iPhone-13).
+// Read-only network; $0 local. Run from ~/Projects/Designer-Wallcoverings.
+const { chromium } = require('playwright');
+const fs = require('fs');
+const https = require('https');
+
+const ROOT = __dirname;
+const CSS = fs.readFileSync(ROOT + '/shopify/collection-hero-fix/dw-collection-hero.css', 'utf8');
+const ROTATOR_JS = fs.readFileSync(ROOT + '/shopify/collection-hero-fix/dw-hero-rotator.js', 'utf8');
+// The snippet also emits a critical inline <style> (header min-height, base bg,
+// transparent Boost inner wrappers, white-pill title). Extract + inject it so
+// the test renders what production renders.
+const SNIPPET = fs.readFileSync(ROOT + '/shopify/collection-hero-fix/snippets_dw-collection-hero-bg.liquid', 'utf8');
+const SNIPPET_STYLE = (SNIPPET.match(/<style>([\s\S]*?)<\/style>/) || [, ''])[1];
+const SHOTS = '/tmp/dwrhshots';
+fs.mkdirSync(SHOTS, { recursive: true });
+
+const COLLECTION = 'https://www.designerwallcoverings.com/collections/all';
+
+// Pull the real newest new-arrivals featured images (what the Liquid snippet
+// would emit) so the test slides are the ACTUAL store-wide-newest imagery.
+function fetchNewest(n) {
+ return new Promise((resolve, reject) => {
+ https.get('https://www.designerwallcoverings.com/collections/new-arrivals/products.json?limit=16',
+ { headers: { 'User-Agent': 'Mozilla/5.0' } }, (res) => {
+ let b = '';
+ res.on('data', (c) => (b += c));
+ res.on('end', () => {
+ try {
+ const ps = JSON.parse(b).products || [];
+ const urls = [];
+ for (const p of ps) {
+ const im = (p.images || [])[0];
+ if (im && im.src) urls.push(im.src.split('?')[0] + '?width=2000');
+ if (urls.length >= n) break;
+ }
+ resolve(urls);
+ } catch (e) { reject(e); }
+ });
+ }).on('error', reject);
+ });
+}
+
+function slideMarkup(urls) {
+ const slides = urls.map((u, i) =>
+ `<div class="dw-hero-slide${i === 0 ? ' is-active' : ''}" data-dw-slide="${i}" ` +
+ `style="background-image: linear-gradient(180deg,rgba(0,0,0,.18),rgba(0,0,0,.34)), url('${u}');"></div>`
+ ).join('');
+ return `<div class="dw-hero-rotator" aria-hidden="true" data-dw-hero-rotator data-interval="2500">${slides}</div>`;
+}
+
+async function probe(page) {
+ return page.evaluate(() => {
+ const header = document.querySelector('.boost-sd__collection-header, .collection-header');
+ const rot = document.querySelector('[data-dw-hero-rotator]');
+ const active = document.querySelectorAll('.dw-hero-slide.is-active').length;
+ const total = document.querySelectorAll('.dw-hero-slide').length;
+ const inHeader = !!(rot && header && header.contains(rot));
+ const a = document.querySelector('.dw-hero-slide.is-active');
+ const activeIdx = a ? a.getAttribute('data-dw-slide') : null;
+ return { hasHeader: !!header, totalSlides: total, activeSlides: active, rotatorInHeader: inHeader, activeIdx };
+ });
+}
+
+(async () => {
+ const urls = await fetchNewest(8);
+ console.log('Newest new-arrivals images:', urls.length);
+ const SLIDES = slideMarkup(urls);
+ const browser = await chromium.launch();
+
+ for (const [name, vp, mobile, ua] of [
+ ['desktop', { width: 1440, height: 900 }, false, undefined],
+ ['mobile', { width: 390, height: 844 }, true,
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1'],
+ ]) {
+ const ctx = await browser.newContext({ viewport: vp, isMobile: mobile, deviceScaleFactor: mobile ? 3 : 1, userAgent: ua });
+ const page = await ctx.newPage();
+ await page.goto(COLLECTION, { waitUntil: 'domcontentloaded', timeout: 60000 });
+ await page.waitForTimeout(3500);
+
+ // BEFORE
+ await page.screenshot({ path: `${SHOTS}/${name}-BEFORE.png` });
+
+ // Inject staged CSS + the snippet's inline <style>, the slide markup, then the rotator JS.
+ await page.addStyleTag({ content: CSS });
+ await page.addStyleTag({ content: SNIPPET_STYLE });
+ await page.evaluate((html) => {
+ document.documentElement.classList.add('dw-coll-hero');
+ document.body.classList.add('dw-collection-has-hero');
+ const header = document.querySelector('.boost-sd__collection-header, .collection-header');
+ if (header) {
+ const wrap = document.createElement('div');
+ wrap.innerHTML = html;
+ document.body.insertBefore(wrap.firstChild, document.body.firstChild);
+ }
+ }, SLIDES);
+ await page.addScriptTag({ content: ROTATOR_JS });
+ await page.waitForTimeout(900);
+
+ await page.waitForTimeout(700);
+ const afterAttach = await probe(page);
+ await page.screenshot({ path: `${SHOTS}/${name}-AFTER-frame1.png` });
+
+ // Let it rotate (interval=2500) and shoot a later frame to prove crossfade.
+ await page.waitForTimeout(2900);
+ const afterRotate = await probe(page);
+ await page.screenshot({ path: `${SHOTS}/${name}-AFTER-frame2.png` });
+
+ console.log(`\n=== ${name.toUpperCase()} ===`);
+ console.log('attach :', JSON.stringify(afterAttach));
+ console.log('rotated:', JSON.stringify(afterRotate));
+ console.log('crossfade advanced (idx changed):', afterAttach.activeIdx !== afterRotate.activeIdx);
+
+ if (mobile) {
+ const f3 = await page.evaluate(() => {
+ const cart = document.querySelector('.cart-count, .cart-link, [data-cart-count]');
+ const brand = document.querySelector('.header-branding-mobile, .header-branding');
+ const mh = document.querySelector('.main-header, .site-header, header');
+ const r = (el) => el ? el.getBoundingClientRect() : null;
+ const b = r(brand), c = r(cart), m = r(mh);
+ return {
+ brandingHeight: b ? Math.round(b.height) : null,
+ headerHeight: m ? Math.round(m.height) : null,
+ cartToBrandGap: (b && c) ? Math.round(b.top - c.bottom) : null,
+ };
+ });
+ console.log('MOBILE F3 after-fix:', JSON.stringify(f3), '(target: branding ~74px, gap closed)');
+ }
+
+ // prefers-reduced-motion test (fresh context).
+ await ctx.close();
+ }
+
+ // Reduced-motion: confirm it holds on frame 1 (no rotation).
+ const rmCtx = await browser.newContext({ viewport: { width: 1440, height: 900 }, reducedMotion: 'reduce' });
+ const rmPage = await rmCtx.newPage();
+ await rmPage.goto(COLLECTION, { waitUntil: 'domcontentloaded', timeout: 60000 });
+ await rmPage.waitForTimeout(3000);
+ await rmPage.addStyleTag({ content: CSS });
+ await rmPage.addStyleTag({ content: SNIPPET_STYLE });
+ await rmPage.evaluate((html) => {
+ document.documentElement.classList.add('dw-coll-hero');
+ document.body.classList.add('dw-collection-has-hero');
+ const wrap = document.createElement('div'); wrap.innerHTML = html;
+ document.body.insertBefore(wrap.firstChild, document.body.firstChild);
+ }, SLIDES);
+ await rmPage.addScriptTag({ content: ROTATOR_JS });
+ await rmPage.waitForTimeout(500);
+ const rm1 = await probe(rmPage);
+ await rmPage.waitForTimeout(3000);
+ const rm2 = await probe(rmPage);
+ console.log('\n=== REDUCED-MOTION ===');
+ console.log('frame1 idx:', rm1.activeIdx);
+ console.log('after 3s (should still be 0 — held):', rm1.activeIdx === rm2.activeIdx && rm1.activeIdx === '0' ? 'HELD ✓' : 'ROTATED ✗');
+ await rmCtx.close();
+
+ await browser.close();
+ console.log('\nScreenshots in', SHOTS);
+})();
← b357a962 Designtex Step 1: canonical dw_unified fill-in loaded (2701
·
back to Designer Wallcoverings
·
Add Tres Tintas live-PDP click-through QA + reverify; draft 7227f977 →