← back to Council 0809 Builds
ship Council #5 rolls AR deep-link Path B: install how-many-rolls PDP snippet on live theme 144396058675
6012bf05bcd5263bdec2ba39b5472a718e870975 · 2026-08-10 12:11:36 -0700 · vp-dw-commerce
- backed up sections/product.liquid before edit
- wired {% render 'how-many-rolls' %} below the product form / ATC-sample block
- verified live: width-present product renders the AR deep-link button (mode=width),
non-numeric-width product renders nothing (reliability gate holds)
- Path A backfill (backfill-pattern-repeat.js) deliberately NOT committed (not approved)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
A rolls-ar-deeplink/backup-sections_product-20260810-120607.liquidA rolls-ar-deeplink/verify-live.mjsA rolls-ar-deeplink/work-sections_product.liquid
Diff
commit 6012bf05bcd5263bdec2ba39b5472a718e870975
Author: vp-dw-commerce <steve@designerwallcoverings.com>
Date: Mon Aug 10 12:11:36 2026 -0700
ship Council #5 rolls AR deep-link Path B: install how-many-rolls PDP snippet on live theme 144396058675
- backed up sections/product.liquid before edit
- wired {% render 'how-many-rolls' %} below the product form / ATC-sample block
- verified live: width-present product renders the AR deep-link button (mode=width),
non-numeric-width product renders nothing (reliability gate holds)
- Path A backfill (backfill-pattern-repeat.js) deliberately NOT committed (not approved)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
.../backup-sections_product-20260810-120607.liquid | 412 ++++++++++++++++++++
rolls-ar-deeplink/verify-live.mjs | 50 +++
rolls-ar-deeplink/work-sections_product.liquid | 418 +++++++++++++++++++++
3 files changed, 880 insertions(+)
diff --git a/rolls-ar-deeplink/backup-sections_product-20260810-120607.liquid b/rolls-ar-deeplink/backup-sections_product-20260810-120607.liquid
new file mode 100644
index 0000000..279c88d
--- /dev/null
+++ b/rolls-ar-deeplink/backup-sections_product-20260810-120607.liquid
@@ -0,0 +1,412 @@
+{% render 'breadcrumbs' %}
+
+{% liquid
+ assign enable_zoom = section.settings.enable_zoom
+ assign enable_cart_redirection = section.settings.enable_cart_redirection
+ assign images_layout = section.settings.images_layout
+ assign enable_video_autoplay = section.settings.enable_video_autoplay
+ assign enable_video_looping = section.settings.enable_video_looping
+ assign enable_linked_options = true
+ assign show_vendor = settings.show_vendor
+ assign show_social_media_icons = section.settings.show_social_media_icons
+ assign show_payment_button = section.settings.show_payment_button
+
+ for block in section.blocks
+ if block.type == 'complementary_products'
+ assign product_recommendation_limit = block.settings.product_recommendation_limit
+ break
+ endif
+ endfor
+%}
+
+{% if images_layout == 'masonry' %}
+ {% comment %}Related products in masonry grid must be below product{% endcomment %}
+ {% assign related_products_position_right = false %}
+{% endif %}
+
+<script
+ type="application/json"
+ data-section-type="product"
+ data-section-id="{{ section.id }}"
+ data-section-data
+>
+ {
+ "product": {{ product | json }},
+ "product_settings": {
+ "addToCartText": {{ 'products.product.add_to_cart' | t | json }},
+ "enableHistory": true,
+ "processingText": {{ 'products.product.processing' | t | json }},
+ "setQuantityText": {{ 'products.product.set_quantity' | t | json }},
+ "soldOutText": {{ 'products.product.sold_out' | t | json }},
+ "unavailableText": {{ 'products.product.unavailable' | t | json }}
+ },
+ "images_layout": {{ images_layout | json }},
+ "enable_zoom": {{ enable_zoom | json }},
+ "enable_video_autoplay": {{ enable_video_autoplay | json }},
+ "enable_video_looping": {{ enable_video_looping | json }},
+ "enable_cart_redirection": {{ enable_cart_redirection | json }},
+ "enable_fixed_positioning": true,
+ "product_recommendation_limit": {{ product_recommendation_limit | json }}
+ }
+</script>
+
+{% render 'product-success-labels' %}
+<section class="product-container">
+ {%
+ render 'product',
+ product: product,
+ enable_zoom: enable_zoom,
+ images_layout: images_layout,
+ enable_linked_options: enable_linked_options,
+ show_vendor: show_vendor,
+ show_social_media_icons: show_social_media_icons,
+ show_payment_button: show_payment_button,
+ %}
+
+ {%- comment -%} Select Color for Coordinates (color-palette) — full-width, below the two-column
+ block, ABOVE "More Wallcoverings". Clicking a color serves coordinating products in a 2-row
+ full-width grid right under the bar (Steve 2026-07-28). {%- endcomment -%}
+ {% render 'color-palette' %}
+
+ {%- comment -%} More Wallcoverings Like This — full-width CLIP similarity row, moved here from the color-palette snippet so it spans the whole page below the two-column block (Steve 2026-07-28). {%- endcomment -%}
+{%- comment -%} CLIP "More like this" — PDP color-dot CLIP visual-similarity row.
+ Calls the SAME-BEHAVIOR public proxy /apps/similar (dwphoto → loopback CLIP :9914),
+ which returns the visually-nearest patterns to THIS product, softly re-ranked by the
+ same hex→color-family bucket + style overlap the swatches use. Additive: the swatch
+ spectrum + its color-family links above are unchanged. dw_sku / hex / style come from
+ the product's REAL fields. (Steve "ship the CLIP dots" 2026-07-08) {%- endcomment -%}
+{%- assign _dw_sku = product.selected_or_first_available_variant.sku | default: product.variants.first.sku | remove: '-Sample' -%}
+{%- assign _dw_hex = product.metafields.custom.primary_color_hex.value | default: product.metafields.custom.color_hex.value | default: product.metafields.dwc.dominant_hex.value -%}
+{%- assign _dw_style = product.metafields.custom.style.value | default: product.metafields.global.Style.value | default: product.type -%}
+{%- if _dw_sku != blank -%}
+<div id="dw-similar" class="dw-similar"
+ data-dw-sku="{{ _dw_sku | escape }}"
+ data-hex="{{ _dw_hex | escape }}"
+ data-style="{{ _dw_style | escape }}"
+ data-endpoint="https://photo.designerwallcoverings.com/apps/similar">
+ <h3 class="dw-similar__h">Coordinating Products</h3>
+ <div class="dw-similar__grid" aria-live="polite"></div>
+</div>
+<script>
+(function(){
+ var root=document.getElementById('dw-similar'); if(!root) return;
+ var sku=(root.dataset.dwSku||'').trim().replace(/-Sample$/i,''); // base SKU keys the CLIP index; the Sample variant SKU (usually first-available) has no embedding
+ if(!sku){ root.style.display='none'; return; }
+ var ep=root.dataset.endpoint||'https://photo.designerwallcoverings.com/apps/similar';
+ fetch(ep,{method:'POST',mode:'cors',headers:{'Content-Type':'application/json'},
+ body:JSON.stringify({dw_sku:sku, hex:root.dataset.hex||'', style:root.dataset.style||'', k:12})})
+ .then(function(r){return r.ok?r.json():{results:[]};})
+ .then(function(d){
+ var g=root.querySelector('.dw-similar__grid');
+ if(!d.results||!d.results.length){ root.style.display='none'; return; }
+ d.results.forEach(function(p){
+ var a=document.createElement('a'); a.className='dw-similar__card'; a.rel='nofollow';
+ // real PDP link when we have a storefront handle; else fall back to a SKU search (never a name-search)
+ a.href = p.handle ? ('/products/'+encodeURIComponent(p.handle))
+ : ('/search?q='+encodeURIComponent(p.dw_sku||'')+'&type=product');
+ var img=document.createElement('img'); img.loading='lazy'; img.src=p.image||''; img.alt=p.pattern||'';
+ var cap=document.createElement('span'); cap.className='dw-similar__cap'; cap.textContent=p.pattern||'';
+ a.appendChild(img); a.appendChild(cap); g.appendChild(a);
+ });
+ }).catch(function(){ root.style.display='none'; });
+})();
+</script>
+<style>
+/* Steve 2026-07-28: relocated OUT of the left gallery column to span the full page width.
+ DTD design-panel verdict A (front-page-steward + ui-ux-designer): clear:both makes the
+ full-width band collision-proof against the two-column block (specs) even if the theme
+ floats its columns — the strip always drops fully below both columns. */
+.dw-similar{clear:both;margin:34px auto 10px;max-width:1200px;width:100%;text-align:center;padding:0 20px;box-sizing:border-box}
+.dw-similar__h{font-family:Lora,serif;font-size:17px;font-weight:500;color:#3D4246;letter-spacing:-0.01em;margin:0 0 16px}
+/* Steve 2026-07-28: LARGER, uniform cards. min-width:0 on the card is the fix for the
+ grid "blowout" — without it, a 1fr track's implicit min-content minimum lets a large
+ natural image (e.g. 2520px) force its column wider than the others, so cards rendered
+ at different sizes. With min-width:0 every 1fr track shrinks equally → all cards identical. */
+.dw-similar__grid{display:grid!important;grid-template-columns:repeat(auto-fill,minmax(190px,1fr))!important;gap:18px!important}
+@media(min-width:1200px){.dw-similar__grid{grid-template-columns:repeat(6,1fr)!important}}
+/* FORCE every card identical (Steve 2026-07-28): min-width:0 !important defeats the grid
+ min-content blowout AND any theme img rule, so cards are ALWAYS the same size. */
+.dw-similar__card{display:block!important;text-decoration:none;color:inherit;min-width:0!important;width:auto!important;max-width:none!important}
+.dw-similar__card img{width:100%!important;height:auto!important;aspect-ratio:1/1!important;object-fit:cover!important;display:block!important;min-width:0!important;max-width:100%!important;border:1px solid #e5e5e5;border-radius:3px}
+.dw-similar__cap{display:block;font-family:Lora,serif;font-size:11px;color:#3D4246;margin-top:5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-transform:capitalize}
+.dw-similar:empty{display:none}
+</style>
+{%- endif -%}
+
+ {%- comment -%} Design Coordinate feature removed from the PDP (Steve 2026-07-28, DTD: "remove feature entirely"). {%- endcomment -%}
+
+ <div
+ class="product-recommendations-wrapper--right"
+ data-product-recommendations-right
+ >
+ </div>
+</section>
+
+{% schema %}
+{
+ "name": "Product pages",
+ "settings": [
+ {
+ "type": "checkbox",
+ "id": "enable_cart_redirection",
+ "label": "Enable cart redirection",
+ "info": "Automatically sends users to the Cart page after adding a product.",
+ "default": false
+ },
+ {
+ "type": "checkbox",
+ "id": "show_payment_button",
+ "label": "Show dynamic checkout button",
+ "info": "Each customer will see their preferred payment method from those available on your store, such as PayPal or Apple Pay. [Learn more](https://help.shopify.com/manual/using-themes/change-the-layout/dynamic-checkout)",
+ "default": true
+ },
+ {
+ "type": "header",
+ "content": "Media"
+ },
+ {
+ "type": "paragraph",
+ "content": "Learn more about [media types](https://help.shopify.com/en/manual/products/product-media/product-media-types)"
+ },
+ {
+ "type": "select",
+ "id": "images_layout",
+ "label": "Layout",
+ "options": [
+ {
+ "label": "Slideshow",
+ "value": "slideshow"
+ },
+ {
+ "label": "List",
+ "value": "list"
+ },
+ {
+ "label": "Masonry",
+ "value": "masonry"
+ }
+ ],
+ "default": "slideshow"
+ },
+ {
+ "type": "checkbox",
+ "id": "enable_zoom",
+ "label": "Enable image zoom",
+ "info": "Zoom only works with the slideshow image layout"
+ },
+ {
+ "type": "checkbox",
+ "id": "enable_video_autoplay",
+ "label": "Enable video autoplay",
+ "default": true
+ },
+ {
+ "type": "checkbox",
+ "id": "enable_video_looping",
+ "label": "Enable video looping"
+ }
+ ],
+ "blocks": [
+ {
+ "type": "@app"
+ },
+ {
+ "type": "collapsible-tab",
+ "name": "Collapsible tab",
+ "settings": [
+ {
+ "type": "text",
+ "id": "collapsible_tab_heading",
+ "label": "Heading",
+ "default": "Collapsible tab"
+ },
+ {
+ "type": "richtext",
+ "id": "collapsible_tab_text",
+ "label": "Text",
+ "default": "<p>Use this text to share information about your product.</p>"
+ }
+ ]
+ },
+ {
+ "type": "custom-liquid",
+ "name": "Custom liquid",
+ "settings": [
+ {
+ "type": "liquid",
+ "id": "custom_liquid",
+ "label": "Custom liquid",
+ "info": "Add app snippets or other Liquid code to create advanced customizations."
+ }
+ ]
+ },
+ {
+ "type": "tabs",
+ "name": "Tabs",
+ "limit": 1,
+ "settings": [
+ {
+ "type": "checkbox",
+ "id": "show_product_description",
+ "label": "Show product description",
+ "default": false
+ },
+ {
+ "type": "header",
+ "content": "Tab"
+ },
+ {
+ "type": "text",
+ "id": "tab_heading_1",
+ "label": "Heading",
+ "default": "Tab 1"
+ },
+ {
+ "type": "richtext",
+ "id": "tab_text_1",
+ "label": "Text",
+ "default": "<p>Tab 1 content goes here.</p>"
+ },
+ {
+ "type": "header",
+ "content": "Tab"
+ },
+ {
+ "type": "text",
+ "id": "tab_heading_2",
+ "label": "Heading",
+ "default": "Tab 2"
+ },
+ {
+ "type": "richtext",
+ "id": "tab_text_2",
+ "label": "Text",
+ "default": "<p>Tab 2 content goes here.</p>"
+ },
+ {
+ "type": "header",
+ "content": "Tab"
+ },
+ {
+ "type": "text",
+ "id": "tab_heading_3",
+ "label": "Heading",
+ "default": "Tab 3"
+ },
+ {
+ "type": "richtext",
+ "id": "tab_text_3",
+ "label": "Text",
+ "default": "<p>Tab 3 content goes here.</p>"
+ }
+ ]
+ },
+ {
+ "type": "title",
+ "name": "Title",
+ "limit": 1
+ },
+ {
+ "type": "vendor",
+ "name": "Vendor",
+ "limit": 1
+ },
+ {
+ "type": "social",
+ "name": "Social",
+ "limit": 1
+ },
+ {
+ "type": "description",
+ "name": "Description",
+ "limit": 1
+ },
+ {
+ "type": "price",
+ "name": "Price",
+ "limit": 1
+ },
+ {
+ "type": "form",
+ "name": "Form",
+ "limit": 1,
+ "settings": [
+ {
+ "type": "paragraph",
+ "content": "Customize form features for the product in the products portion of the theme settings."
+ },
+ {
+ "type": "checkbox",
+ "id": "show_gift_card_recipient_form",
+ "label": "t:sections.product.blocks.form.show_gift_card_recipient_form.label",
+ "info": "t:sections.product.blocks.form.show_gift_card_recipient_form.info",
+ "default": false
+ }
+ ]
+ },
+ {
+ "type": "rating",
+ "name": "Product rating",
+ "limit": 1,
+ "settings": [
+ {
+ "type": "paragraph",
+ "content": "To display a rating, add a product rating app. [Learn more](https://apps.shopify.com/product-reviews)"
+ }
+ ]
+ },
+ {
+ "type": "complementary_products",
+ "name": "Complementary products",
+ "limit": 1,
+ "settings": [
+ {
+ "type": "paragraph",
+ "content": "To select complementary products, add the Search & Discovery app. [Learn more](https:\/\/shopify.dev\/themes\/product-merchandising\/recommendations)"
+ },
+ {
+ "type": "text",
+ "id": "heading",
+ "label": "Heading",
+ "default": "Pairs well with"
+ },
+ {
+ "type": "range",
+ "id": "product_recommendation_limit",
+ "label": "Maximum products to show",
+ "min": 1,
+ "max": 10,
+ "default": 5
+ },
+ {
+ "type": "range",
+ "id": "products_per_slide",
+ "label": "Number of products per page",
+ "min": 1,
+ "max": 3,
+ "default": 2
+ }
+ ]
+ }
+ ]
+}
+
+{% endschema %}
+
+{%- comment -%} KEYWORDS (Steve 2026-07-28): serve full-width across the entire
+ screen. Removed the 80ch cap + the manual 96-char <br> wrapping so the tag links
+ now flow and wrap naturally at the full container width. {%- endcomment -%}
+<div class="keywords-desktop" style="width: 100%; max-width: none; box-sizing: border-box; padding: 0 3ch; line-height: 1.9; text-align: center;">
+ <h4 style="margin: 0 0 6px;">KEYWORDS:</h4>
+ <div class="keywords-desktop__list" style="width: 100%;">
+ {%- for tag in product.tags -%}
+ {%- unless tag == "display_variant" -%}<a href="/search?q={{ tag | url_encode }}">{{ tag }}</a>{%- unless forloop.last -%}, {% endunless -%}{%- endunless -%}
+ {%- endfor -%}
+ </div>
+</div>
+
+{% comment %} Recently Viewed Products — tracks current product + shows carousel {% endcomment %}
+{% if settings.dw_enable_recently_viewed %}
+
+ {% render 'recently-viewed' %}
+{% endif %}
diff --git a/rolls-ar-deeplink/verify-live.mjs b/rolls-ar-deeplink/verify-live.mjs
new file mode 100644
index 0000000..9c3e650
--- /dev/null
+++ b/rolls-ar-deeplink/verify-live.mjs
@@ -0,0 +1,50 @@
+import pw from '/Users/macstudio3/.npm-global/lib/node_modules/playwright/index.js';
+const { chromium } = pw;
+
+const cases = [
+ { label: "A width='36\" Wide' -> EXPECT BUTTON", handle: 'venezia-glass-beads-wall-paper-gold-gls-111-glass-beads-gold', expect: true },
+ { label: "B width='Covers 30 sq ft' -> EXPECT NOTHING", handle: '1800-s-vintage-brown-and-off-white-crest-pattern-wallcovering-wi-vin-900', expect: false },
+];
+
+const browser = await chromium.launch({ headless: true });
+const ctx = await browser.newContext({
+ userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126 Safari/537.36',
+});
+const page = await ctx.newPage();
+
+for (const c of cases) {
+ const url = `https://www.designerwallcoverings.com/products/${c.handle}`;
+ let title = '', hasBtn = false, href = null, label = null, note = '';
+ try {
+ await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 60000 });
+ // wait out a possible CF challenge
+ for (let i = 0; i < 20; i++) {
+ title = await page.title().catch(() => '');
+ if (!/verifying your connection|just a moment/i.test(title)) break;
+ await page.waitForTimeout(1500);
+ }
+ await page.waitForTimeout(1500);
+ const btn = await page.$('a.dw-rolls-btn, a[data-dw-rolls="1"]');
+ hasBtn = !!btn;
+ if (btn) {
+ href = await btn.getAttribute('href');
+ label = (await btn.innerText().catch(() => '')).trim();
+ }
+ // confirm it's really the PDP (section markers present)
+ const pdp = await page.$('.product-container, #dw-similar, .keywords-desktop');
+ note = pdp ? 'PDP-confirmed' : 'PDP-markers-missing';
+ } catch (e) {
+ note = 'ERROR ' + e.message.slice(0, 120);
+ }
+ const pass = hasBtn === c.expect;
+ console.log('====================================================');
+ console.log(c.label);
+ console.log(' url :', url);
+ console.log(' title :', title.slice(0, 60));
+ console.log(' page :', note);
+ console.log(' buttonFound:', hasBtn, ' expected:', c.expect, ' =>', pass ? 'PASS' : 'FAIL');
+ if (href) console.log(' href :', href);
+ if (label) console.log(' label :', label);
+}
+
+await browser.close();
diff --git a/rolls-ar-deeplink/work-sections_product.liquid b/rolls-ar-deeplink/work-sections_product.liquid
new file mode 100644
index 0000000..4afb76c
--- /dev/null
+++ b/rolls-ar-deeplink/work-sections_product.liquid
@@ -0,0 +1,418 @@
+{% render 'breadcrumbs' %}
+
+{% liquid
+ assign enable_zoom = section.settings.enable_zoom
+ assign enable_cart_redirection = section.settings.enable_cart_redirection
+ assign images_layout = section.settings.images_layout
+ assign enable_video_autoplay = section.settings.enable_video_autoplay
+ assign enable_video_looping = section.settings.enable_video_looping
+ assign enable_linked_options = true
+ assign show_vendor = settings.show_vendor
+ assign show_social_media_icons = section.settings.show_social_media_icons
+ assign show_payment_button = section.settings.show_payment_button
+
+ for block in section.blocks
+ if block.type == 'complementary_products'
+ assign product_recommendation_limit = block.settings.product_recommendation_limit
+ break
+ endif
+ endfor
+%}
+
+{% if images_layout == 'masonry' %}
+ {% comment %}Related products in masonry grid must be below product{% endcomment %}
+ {% assign related_products_position_right = false %}
+{% endif %}
+
+<script
+ type="application/json"
+ data-section-type="product"
+ data-section-id="{{ section.id }}"
+ data-section-data
+>
+ {
+ "product": {{ product | json }},
+ "product_settings": {
+ "addToCartText": {{ 'products.product.add_to_cart' | t | json }},
+ "enableHistory": true,
+ "processingText": {{ 'products.product.processing' | t | json }},
+ "setQuantityText": {{ 'products.product.set_quantity' | t | json }},
+ "soldOutText": {{ 'products.product.sold_out' | t | json }},
+ "unavailableText": {{ 'products.product.unavailable' | t | json }}
+ },
+ "images_layout": {{ images_layout | json }},
+ "enable_zoom": {{ enable_zoom | json }},
+ "enable_video_autoplay": {{ enable_video_autoplay | json }},
+ "enable_video_looping": {{ enable_video_looping | json }},
+ "enable_cart_redirection": {{ enable_cart_redirection | json }},
+ "enable_fixed_positioning": true,
+ "product_recommendation_limit": {{ product_recommendation_limit | json }}
+ }
+</script>
+
+{% render 'product-success-labels' %}
+<section class="product-container">
+ {%
+ render 'product',
+ product: product,
+ enable_zoom: enable_zoom,
+ images_layout: images_layout,
+ enable_linked_options: enable_linked_options,
+ show_vendor: show_vendor,
+ show_social_media_icons: show_social_media_icons,
+ show_payment_button: show_payment_button,
+ %}
+
+ {%- comment -%} "How Many Rolls?" AR deep-link button — Council idea #5, PATH B (TK-10385).
+ Rendered directly below the product form (Add-to-Cart / sample block, from the 'product'
+ snippet above). Hard reliability gate lives in the snippet: renders NOTHING unless a
+ numeric width metafield is present. {%- endcomment -%}
+ {% render 'how-many-rolls' %}
+
+ {%- comment -%} Select Color for Coordinates (color-palette) — full-width, below the two-column
+ block, ABOVE "More Wallcoverings". Clicking a color serves coordinating products in a 2-row
+ full-width grid right under the bar (Steve 2026-07-28). {%- endcomment -%}
+ {% render 'color-palette' %}
+
+ {%- comment -%} More Wallcoverings Like This — full-width CLIP similarity row, moved here from the color-palette snippet so it spans the whole page below the two-column block (Steve 2026-07-28). {%- endcomment -%}
+{%- comment -%} CLIP "More like this" — PDP color-dot CLIP visual-similarity row.
+ Calls the SAME-BEHAVIOR public proxy /apps/similar (dwphoto → loopback CLIP :9914),
+ which returns the visually-nearest patterns to THIS product, softly re-ranked by the
+ same hex→color-family bucket + style overlap the swatches use. Additive: the swatch
+ spectrum + its color-family links above are unchanged. dw_sku / hex / style come from
+ the product's REAL fields. (Steve "ship the CLIP dots" 2026-07-08) {%- endcomment -%}
+{%- assign _dw_sku = product.selected_or_first_available_variant.sku | default: product.variants.first.sku | remove: '-Sample' -%}
+{%- assign _dw_hex = product.metafields.custom.primary_color_hex.value | default: product.metafields.custom.color_hex.value | default: product.metafields.dwc.dominant_hex.value -%}
+{%- assign _dw_style = product.metafields.custom.style.value | default: product.metafields.global.Style.value | default: product.type -%}
+{%- if _dw_sku != blank -%}
+<div id="dw-similar" class="dw-similar"
+ data-dw-sku="{{ _dw_sku | escape }}"
+ data-hex="{{ _dw_hex | escape }}"
+ data-style="{{ _dw_style | escape }}"
+ data-endpoint="https://photo.designerwallcoverings.com/apps/similar">
+ <h3 class="dw-similar__h">Coordinating Products</h3>
+ <div class="dw-similar__grid" aria-live="polite"></div>
+</div>
+<script>
+(function(){
+ var root=document.getElementById('dw-similar'); if(!root) return;
+ var sku=(root.dataset.dwSku||'').trim().replace(/-Sample$/i,''); // base SKU keys the CLIP index; the Sample variant SKU (usually first-available) has no embedding
+ if(!sku){ root.style.display='none'; return; }
+ var ep=root.dataset.endpoint||'https://photo.designerwallcoverings.com/apps/similar';
+ fetch(ep,{method:'POST',mode:'cors',headers:{'Content-Type':'application/json'},
+ body:JSON.stringify({dw_sku:sku, hex:root.dataset.hex||'', style:root.dataset.style||'', k:12})})
+ .then(function(r){return r.ok?r.json():{results:[]};})
+ .then(function(d){
+ var g=root.querySelector('.dw-similar__grid');
+ if(!d.results||!d.results.length){ root.style.display='none'; return; }
+ d.results.forEach(function(p){
+ var a=document.createElement('a'); a.className='dw-similar__card'; a.rel='nofollow';
+ // real PDP link when we have a storefront handle; else fall back to a SKU search (never a name-search)
+ a.href = p.handle ? ('/products/'+encodeURIComponent(p.handle))
+ : ('/search?q='+encodeURIComponent(p.dw_sku||'')+'&type=product');
+ var img=document.createElement('img'); img.loading='lazy'; img.src=p.image||''; img.alt=p.pattern||'';
+ var cap=document.createElement('span'); cap.className='dw-similar__cap'; cap.textContent=p.pattern||'';
+ a.appendChild(img); a.appendChild(cap); g.appendChild(a);
+ });
+ }).catch(function(){ root.style.display='none'; });
+})();
+</script>
+<style>
+/* Steve 2026-07-28: relocated OUT of the left gallery column to span the full page width.
+ DTD design-panel verdict A (front-page-steward + ui-ux-designer): clear:both makes the
+ full-width band collision-proof against the two-column block (specs) even if the theme
+ floats its columns — the strip always drops fully below both columns. */
+.dw-similar{clear:both;margin:34px auto 10px;max-width:1200px;width:100%;text-align:center;padding:0 20px;box-sizing:border-box}
+.dw-similar__h{font-family:Lora,serif;font-size:17px;font-weight:500;color:#3D4246;letter-spacing:-0.01em;margin:0 0 16px}
+/* Steve 2026-07-28: LARGER, uniform cards. min-width:0 on the card is the fix for the
+ grid "blowout" — without it, a 1fr track's implicit min-content minimum lets a large
+ natural image (e.g. 2520px) force its column wider than the others, so cards rendered
+ at different sizes. With min-width:0 every 1fr track shrinks equally → all cards identical. */
+.dw-similar__grid{display:grid!important;grid-template-columns:repeat(auto-fill,minmax(190px,1fr))!important;gap:18px!important}
+@media(min-width:1200px){.dw-similar__grid{grid-template-columns:repeat(6,1fr)!important}}
+/* FORCE every card identical (Steve 2026-07-28): min-width:0 !important defeats the grid
+ min-content blowout AND any theme img rule, so cards are ALWAYS the same size. */
+.dw-similar__card{display:block!important;text-decoration:none;color:inherit;min-width:0!important;width:auto!important;max-width:none!important}
+.dw-similar__card img{width:100%!important;height:auto!important;aspect-ratio:1/1!important;object-fit:cover!important;display:block!important;min-width:0!important;max-width:100%!important;border:1px solid #e5e5e5;border-radius:3px}
+.dw-similar__cap{display:block;font-family:Lora,serif;font-size:11px;color:#3D4246;margin-top:5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-transform:capitalize}
+.dw-similar:empty{display:none}
+</style>
+{%- endif -%}
+
+ {%- comment -%} Design Coordinate feature removed from the PDP (Steve 2026-07-28, DTD: "remove feature entirely"). {%- endcomment -%}
+
+ <div
+ class="product-recommendations-wrapper--right"
+ data-product-recommendations-right
+ >
+ </div>
+</section>
+
+{% schema %}
+{
+ "name": "Product pages",
+ "settings": [
+ {
+ "type": "checkbox",
+ "id": "enable_cart_redirection",
+ "label": "Enable cart redirection",
+ "info": "Automatically sends users to the Cart page after adding a product.",
+ "default": false
+ },
+ {
+ "type": "checkbox",
+ "id": "show_payment_button",
+ "label": "Show dynamic checkout button",
+ "info": "Each customer will see their preferred payment method from those available on your store, such as PayPal or Apple Pay. [Learn more](https://help.shopify.com/manual/using-themes/change-the-layout/dynamic-checkout)",
+ "default": true
+ },
+ {
+ "type": "header",
+ "content": "Media"
+ },
+ {
+ "type": "paragraph",
+ "content": "Learn more about [media types](https://help.shopify.com/en/manual/products/product-media/product-media-types)"
+ },
+ {
+ "type": "select",
+ "id": "images_layout",
+ "label": "Layout",
+ "options": [
+ {
+ "label": "Slideshow",
+ "value": "slideshow"
+ },
+ {
+ "label": "List",
+ "value": "list"
+ },
+ {
+ "label": "Masonry",
+ "value": "masonry"
+ }
+ ],
+ "default": "slideshow"
+ },
+ {
+ "type": "checkbox",
+ "id": "enable_zoom",
+ "label": "Enable image zoom",
+ "info": "Zoom only works with the slideshow image layout"
+ },
+ {
+ "type": "checkbox",
+ "id": "enable_video_autoplay",
+ "label": "Enable video autoplay",
+ "default": true
+ },
+ {
+ "type": "checkbox",
+ "id": "enable_video_looping",
+ "label": "Enable video looping"
+ }
+ ],
+ "blocks": [
+ {
+ "type": "@app"
+ },
+ {
+ "type": "collapsible-tab",
+ "name": "Collapsible tab",
+ "settings": [
+ {
+ "type": "text",
+ "id": "collapsible_tab_heading",
+ "label": "Heading",
+ "default": "Collapsible tab"
+ },
+ {
+ "type": "richtext",
+ "id": "collapsible_tab_text",
+ "label": "Text",
+ "default": "<p>Use this text to share information about your product.</p>"
+ }
+ ]
+ },
+ {
+ "type": "custom-liquid",
+ "name": "Custom liquid",
+ "settings": [
+ {
+ "type": "liquid",
+ "id": "custom_liquid",
+ "label": "Custom liquid",
+ "info": "Add app snippets or other Liquid code to create advanced customizations."
+ }
+ ]
+ },
+ {
+ "type": "tabs",
+ "name": "Tabs",
+ "limit": 1,
+ "settings": [
+ {
+ "type": "checkbox",
+ "id": "show_product_description",
+ "label": "Show product description",
+ "default": false
+ },
+ {
+ "type": "header",
+ "content": "Tab"
+ },
+ {
+ "type": "text",
+ "id": "tab_heading_1",
+ "label": "Heading",
+ "default": "Tab 1"
+ },
+ {
+ "type": "richtext",
+ "id": "tab_text_1",
+ "label": "Text",
+ "default": "<p>Tab 1 content goes here.</p>"
+ },
+ {
+ "type": "header",
+ "content": "Tab"
+ },
+ {
+ "type": "text",
+ "id": "tab_heading_2",
+ "label": "Heading",
+ "default": "Tab 2"
+ },
+ {
+ "type": "richtext",
+ "id": "tab_text_2",
+ "label": "Text",
+ "default": "<p>Tab 2 content goes here.</p>"
+ },
+ {
+ "type": "header",
+ "content": "Tab"
+ },
+ {
+ "type": "text",
+ "id": "tab_heading_3",
+ "label": "Heading",
+ "default": "Tab 3"
+ },
+ {
+ "type": "richtext",
+ "id": "tab_text_3",
+ "label": "Text",
+ "default": "<p>Tab 3 content goes here.</p>"
+ }
+ ]
+ },
+ {
+ "type": "title",
+ "name": "Title",
+ "limit": 1
+ },
+ {
+ "type": "vendor",
+ "name": "Vendor",
+ "limit": 1
+ },
+ {
+ "type": "social",
+ "name": "Social",
+ "limit": 1
+ },
+ {
+ "type": "description",
+ "name": "Description",
+ "limit": 1
+ },
+ {
+ "type": "price",
+ "name": "Price",
+ "limit": 1
+ },
+ {
+ "type": "form",
+ "name": "Form",
+ "limit": 1,
+ "settings": [
+ {
+ "type": "paragraph",
+ "content": "Customize form features for the product in the products portion of the theme settings."
+ },
+ {
+ "type": "checkbox",
+ "id": "show_gift_card_recipient_form",
+ "label": "t:sections.product.blocks.form.show_gift_card_recipient_form.label",
+ "info": "t:sections.product.blocks.form.show_gift_card_recipient_form.info",
+ "default": false
+ }
+ ]
+ },
+ {
+ "type": "rating",
+ "name": "Product rating",
+ "limit": 1,
+ "settings": [
+ {
+ "type": "paragraph",
+ "content": "To display a rating, add a product rating app. [Learn more](https://apps.shopify.com/product-reviews)"
+ }
+ ]
+ },
+ {
+ "type": "complementary_products",
+ "name": "Complementary products",
+ "limit": 1,
+ "settings": [
+ {
+ "type": "paragraph",
+ "content": "To select complementary products, add the Search & Discovery app. [Learn more](https:\/\/shopify.dev\/themes\/product-merchandising\/recommendations)"
+ },
+ {
+ "type": "text",
+ "id": "heading",
+ "label": "Heading",
+ "default": "Pairs well with"
+ },
+ {
+ "type": "range",
+ "id": "product_recommendation_limit",
+ "label": "Maximum products to show",
+ "min": 1,
+ "max": 10,
+ "default": 5
+ },
+ {
+ "type": "range",
+ "id": "products_per_slide",
+ "label": "Number of products per page",
+ "min": 1,
+ "max": 3,
+ "default": 2
+ }
+ ]
+ }
+ ]
+}
+
+{% endschema %}
+
+{%- comment -%} KEYWORDS (Steve 2026-07-28): serve full-width across the entire
+ screen. Removed the 80ch cap + the manual 96-char <br> wrapping so the tag links
+ now flow and wrap naturally at the full container width. {%- endcomment -%}
+<div class="keywords-desktop" style="width: 100%; max-width: none; box-sizing: border-box; padding: 0 3ch; line-height: 1.9; text-align: center;">
+ <h4 style="margin: 0 0 6px;">KEYWORDS:</h4>
+ <div class="keywords-desktop__list" style="width: 100%;">
+ {%- for tag in product.tags -%}
+ {%- unless tag == "display_variant" -%}<a href="/search?q={{ tag | url_encode }}">{{ tag }}</a>{%- unless forloop.last -%}, {% endunless -%}{%- endunless -%}
+ {%- endfor -%}
+ </div>
+</div>
+
+{% comment %} Recently Viewed Products — tracks current product + shows carousel {% endcomment %}
+{% if settings.dw_enable_recently_viewed %}
+
+ {% render 'recently-viewed' %}
+{% endif %}
← 175932e auto-data-snapshot: 2026-08-09T10:17:32 (1 data files) — rol
·
back to Council 0809 Builds
·
fix --vendor arg parsing in Path A backfill (index-based, dr 7f39897 →