[object Object]

← back to Designer Wallcoverings

PDP specs: collapse to core 4 + move short description into specs (Steve 2026-07-28)

24e878585a1c75c17cc937cdd4babbf2ab894444 · 2026-07-28 10:40:38 -0700 · steve@designerwallcoverings.com

- product-description-meta.liquid: always-visible core = Product Type, Pattern
  Name, Color, SKU (sellable non-Sample variant's DW sku); all other specs moved
  into a collapsed <details> 'More specifications' panel. Short product
  descriptions (<=500 stripped chars) now render inside the specs block.
- product-gallery.liquid: wide 'Pattern Description:' block now renders ONLY when
  the description is long (>500 chars, e.g. Kravet-family) or in editor onboarding
  — same threshold, so the description shows in exactly one place.
- Pushed live to theme 144396058675 (PUT 200); verified core rows, collapse, and
  short/long description placement on live PDPs; SKU fix verified on cold-cache PDPs.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 24e878585a1c75c17cc937cdd4babbf2ab894444
Author: steve@designerwallcoverings.com <steve@designerwallcoverings.com>
Date:   Tue Jul 28 10:40:38 2026 -0700

    PDP specs: collapse to core 4 + move short description into specs (Steve 2026-07-28)
    
    - product-description-meta.liquid: always-visible core = Product Type, Pattern
      Name, Color, SKU (sellable non-Sample variant's DW sku); all other specs moved
      into a collapsed <details> 'More specifications' panel. Short product
      descriptions (<=500 stripped chars) now render inside the specs block.
    - product-gallery.liquid: wide 'Pattern Description:' block now renders ONLY when
      the description is long (>500 chars, e.g. Kravet-family) or in editor onboarding
      — same threshold, so the description shows in exactly one place.
    - Pushed live to theme 144396058675 (PUT 200); verified core rows, collapse, and
      short/long description placement on live PDPs; SKU fix verified on cold-cache PDPs.
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 .../snippets/product-description-meta.liquid       | 172 +++++++++++++++
 .../snippets/product-gallery.liquid                | 234 +++++++++++++++++++++
 2 files changed, 406 insertions(+)

diff --git a/shopify/theme-LIVE-pull-20260728-colorbar/snippets/product-description-meta.liquid b/shopify/theme-LIVE-pull-20260728-colorbar/snippets/product-description-meta.liquid
new file mode 100644
index 00000000..892a3324
--- /dev/null
+++ b/shopify/theme-LIVE-pull-20260728-colorbar/snippets/product-description-meta.liquid
@@ -0,0 +1,172 @@
+<style>
+.dw-specs { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 16px 0; }
+.dw-specs-title { font-size: 13px; font-weight: 600; color: #888; text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 8px; padding-bottom: 6px; border-bottom: 1px solid #eee; }
+.dw-spec-row { display: flex; padding: 6px 0; border-bottom: 1px solid #f5f5f5; font-size: 15px; line-height: 1.4; }
+.dw-spec-row:last-child { border-bottom: none; }
+.dw-spec-label { font-weight: 600; color: #333; width: 40%; min-width: 120px; flex-shrink: 0; }
+.dw-spec-value { color: #555; flex: 1; }
+/* Collapsed "more specifications" panel (Steve 2026-07-28): only Product Type,
+   Pattern Name, Color and SKU stay visible; everything else lives in here. */
+.dw-specs-more { margin: 0; }
+.dw-specs-more > summary { cursor: pointer; list-style: none; font-size: 13px; font-weight: 600; color: #888; text-transform: uppercase; letter-spacing: 0.06em; padding: 9px 0; display: flex; align-items: center; -webkit-user-select: none; user-select: none; border-bottom: 1px solid #f5f5f5; }
+.dw-specs-more > summary::-webkit-details-marker { display: none; }
+.dw-specs-more > summary::after { content: "+"; margin-left: auto; font-size: 17px; font-weight: 400; color: #aaa; line-height: 1; }
+.dw-specs-more[open] > summary::after { content: "\2013"; }
+.dw-specs-more > summary:hover { color: #333; }
+.dw-specs-more[open] > summary { border-bottom: none; }
+.dw-specs-more__body { padding-top: 2px; }
+/* Pattern description moved into the specs block when short enough (long ones stay wide) */
+.dw-specs-desc { margin-top: 14px; padding-top: 12px; border-top: 1px solid #eee; }
+.dw-specs-desc__label { font-size: 13px; font-weight: 600; color: #888; text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 6px; }
+.dw-specs-desc__body { font-size: 15px; color: #555; line-height: 1.5; }
+.dw-specs-desc__body p { margin: 0 0 8px; }
+.dw-specs-desc__body p:last-child { margin-bottom: 0; }
+</style>
+
+{% comment %} DW Specs — canonical namespace: custom.* — falls back to specs.* then global.* for legacy products {% endcomment %}
+
+{% assign has_specs = false %}
+{% assign w = product.metafields.custom.width.value | default: product.metafields.specs.width.value | default: product.metafields.global.Width.value | default: product.metafields.global.width.value %}
+{% comment %} bugfix 2026-07-16: specs.material (e.g. grasscloth lines) was missing from the chain, silently blanking Material; add specs.material + dwc.contents/content {% endcomment %}
+{% assign mat = product.metafields.custom.material.value | default: product.metafields.specs.material.value | default: product.metafields.specs.composition.value | default: product.metafields.dwc.contents.value | default: product.metafields.dwc.content.value | default: product.metafields.global.Content.value | default: product.metafields.global.Contents.value | default: product.metafields.global.Construction.value %}
+{% comment %} envelope-guard: unwrap a leaked raw metafield JSON wrapper e.g. {"type":"single_line_text_field","value":"Paper"} if one ever slips through, and prefer the canonical global.Material when the value is still an envelope {% endcomment %}
+{% if mat contains '"single_line_text_field"' and mat contains '"value"' %}{% assign mat = mat | split: '"value": "' | last | split: '"}' | first | default: product.metafields.global.Material.value %}{% endif %}
+{% assign col = product.metafields.custom.collection_name.value | default: product.metafields.specs.collection.value | default: product.metafields.global.Collection.value %}
+{% assign rep = product.metafields.custom.pattern_repeat.value | default: product.metafields.custom.repeat.value | default: product.metafields.specs.pattern_repeat.value | default: product.metafields.specs.repeat_v.value | default: product.metafields.dwc.repeat.value | default: product.metafields.global.repeat.value | default: product.metafields.global['Vert-Rpt'].value %}
+{% assign fin = product.metafields.custom.finish.value | default: product.metafields.specs.finish.value | default: product.metafields.global.Finish.value | default: product.metafields.global.FINISH.value %}
+{% assign care = product.metafields.custom.care.value | default: product.metafields.specs.care.value | default: product.metafields.global.Cleaning.value | default: product.metafields.global['Clean-Code'].value | default: product.metafields.global['Cleaning-Code'].value %}
+{% assign fire = product.metafields.custom.fire_rating.value | default: product.metafields.specs.fire_rating.value | default: product.metafields.global.fire_rating.value | default: product.metafields.global.FLAMMABILITY.value %}
+{% assign match = product.metafields.custom.match_type.value | default: product.metafields.specs.match_type.value | default: product.metafields.global.MATCH.value | default: product.metafields.global.Match.value %}
+{% assign app = product.metafields.custom.application.value | default: product.metafields.specs.application.value | default: product.metafields.global.application.value %}
+{% assign len = product.metafields.custom.length.value | default: product.metafields.global.length.value | default: product.metafields.global.Length.value %}
+{% assign pkg = product.metafields.custom.packaging.value | default: product.metafields.global.packaged.value | default: product.metafields.global.Packaged.value %}
+{% assign uom = product.metafields.custom.unit_of_measure.value | default: product.metafields.global.unit_of_measure.value %}
+{% assign coo = product.metafields.custom.origin.value | default: product.metafields.global.Country.value | default: product.metafields.global['Country-of-Origin'].value %}
+{% assign dur = product.metafields.custom.wyzenbeek.value | default: product.metafields.global['Wyzenbeek-#'].value %}
+{% assign mart = product.metafields.custom.martindale.value | default: product.metafields.global['Martindale-#'].value %}
+{% assign abr = product.metafields.custom.abrasion.value | default: product.metafields.specs.abrasion.value %}
+{% assign bk = product.metafields.custom.backing.value | default: product.metafields.specs.backing.value | default: product.metafields.global.Substrate.value | default: product.metafields.global.substrate.value %}
+{% assign brand = product.metafields.custom.brand.value | default: product.metafields.global.Brand.value %}
+{% assign wt = product.metafields.custom.product_weight.value | default: product.metafields.global.Weight.value %}
+{% comment %} blast-wide additions 2026-07-16 — TEXT-typed sources only (custom.style/type/horz_repeat/match/packaged are product_reference, never rendered) {% endcomment %}
+{% assign color = product.metafields.custom.color.value | default: product.metafields.specs.color.value | default: product.metafields.global.color.value | default: product.metafields.global.Color.value | default: product.metafields.dwc.color.value %}
+{% assign pname = product.metafields.custom.pattern_name.value | default: product.metafields.dwc.pattern_name.value %}
+{% assign style = product.metafields.specs.style.value | default: product.metafields.global.Style.value %}
+{% comment %} Type row dropped 2026-07-16: global.Type is redundant with product_type AND holds the banned word "Wallpapers" on ~14 products {% endcomment %}
+{% assign minord = product.metafields.custom.minimum.value | default: product.metafields.dwc.minimum_order_quantity.value | default: product.metafields.global.v_prods_quantity_order_min.value %}
+{% comment %} derive a human order unit from uom so "Minimum Order" isn't a bare integer; increment row dropped as redundant with min+packaged {% endcomment %}
+{% assign ulabel = '' %}
+{% if uom contains 'Double Roll' %}{% assign ulabel = 'double rolls' %}{% elsif uom contains 'Roll' %}{% assign ulabel = 'rolls' %}{% elsif uom contains 'Yard' %}{% assign ulabel = 'yards' %}{% elsif uom contains 'Meter' %}{% assign ulabel = 'meters' %}{% endif %}
+{% assign mfr = product.metafields.custom.manufacturer_sku.value | default: product.metafields.dwc.manufacturer_sku.value %}
+
+{% comment %} Double-roll lines (Thibaut/Malibu Wallpaper/Malibu Walls/York): explicit S/R + D/R
+   length metafields (D/R = 2 x S/R). AI Rooms note. Assigned up front so the collapsed-panel
+   presence check (has_more) can see them. (Steve 2026-07-08 "2 and 2") {% endcomment %}
+{% assign srlen = product.metafields.global.single_roll_length.value %}
+{% assign drlen = product.metafields.global.double_roll_length.value %}
+{% assign ai_note = product.metafields.specs.ai_rooms_note.value %}
+{% comment %} customer-facing DW SKU for the always-visible core: prefer the SELLABLE
+   (non-Sample) variant's SKU (the clean DW sku, e.g. KRAL-2023); only if every variant
+   is a Sample do we fall back to the first variant's SKU with the Sample suffix stripped
+   — handles both '-Sample' and a bare 'SAMPLE' suffix (Steve 2026-07-28). {% endcomment %}
+{% assign dwsku = '' %}
+{% for v in product.variants %}
+  {% unless v.title == 'Sample' or v.sku contains 'Sample' or v.sku contains 'SAMPLE' %}{% assign dwsku = v.sku %}{% break %}{% endunless %}
+{% endfor %}
+{% if dwsku == blank %}
+  {% assign dwsku = product.selected_or_first_available_variant.sku | default: product.variants.first.sku | remove: '-Sample' | remove: '-SAMPLE' | remove: 'Sample' | remove: 'SAMPLE' %}
+{% endif %}
+
+{% if product.type != blank or dwsku != blank or pname != blank or color != blank or w != blank or mat != blank or col != blank %}{% assign has_specs = true %}{% endif %}
+{% comment %} anything beyond the always-visible core → collapsed panel {% endcomment %}
+{% assign has_more = false %}
+{% if w != blank or len != blank or srlen != blank or drlen != blank or rep != blank or match != blank or mat != blank or bk != blank or wt != blank or col != blank or style != blank or brand != blank or fin != blank or fire != blank or care != blank or app != blank or pkg != blank or uom != blank or minord != blank or coo != blank or dur != blank or mart != blank or abr != blank or ai_note != blank %}{% assign has_more = true %}{% endif %}
+
+{% if has_specs %}
+<div class="dw-specs">
+  <div class="dw-specs-title">Specifications</div>
+
+  {%- comment -%} ALWAYS-VISIBLE CORE (Steve 2026-07-28): Product Type, Pattern Name, Color, SKU {%- endcomment -%}
+  {% if product.type != blank %}<div class="dw-spec-row"><span class="dw-spec-label">Product Type</span><span class="dw-spec-value">{{ product.type }}</span></div>{% endif %}
+  {% if pname != blank %}<div class="dw-spec-row"><span class="dw-spec-label">Pattern Name</span><span class="dw-spec-value">{{ pname }}</span></div>{% endif %}
+  {% if color != blank %}<div class="dw-spec-row"><span class="dw-spec-label">Color</span><span class="dw-spec-value">{{ color }}</span></div>{% endif %}
+  {% if dwsku != blank %}<div class="dw-spec-row"><span class="dw-spec-label">SKU</span><span class="dw-spec-value">{{ dwsku }}</span></div>{% endif %}
+
+  {%- comment -%} Everything else → collapsed "More specifications" panel (Steve 2026-07-28) {%- endcomment -%}
+  {% if has_more %}
+  <details class="dw-specs-more">
+    <summary>More specifications</summary>
+    <div class="dw-specs-more__body">
+      {% if w != blank %}<div class="dw-spec-row"><span class="dw-spec-label">Width</span><span class="dw-spec-value">{{ w }}</span></div>{% endif %}
+      {% if srlen != blank and drlen != blank %}
+        <div class="dw-spec-row"><span class="dw-spec-label">Length S/R</span><span class="dw-spec-value">{{ srlen }}</span></div>
+        <div class="dw-spec-row"><span class="dw-spec-label">Length D/R</span><span class="dw-spec-value">{{ drlen }}</span></div>
+      {% elsif len != blank %}<div class="dw-spec-row"><span class="dw-spec-label">{% if product.vendor == 'Designtex' %}Bolt size{% else %}Length{% endif %}</span><span class="dw-spec-value">{{ len }}</span></div>{% endif %}
+      {% if rep != blank %}<div class="dw-spec-row"><span class="dw-spec-label">Pattern Repeat</span><span class="dw-spec-value">{{ rep }}</span></div>{% endif %}
+      {% if match != blank %}<div class="dw-spec-row"><span class="dw-spec-label">Match</span><span class="dw-spec-value">{{ match }}</span></div>{% endif %}
+      {% if mat != blank %}<div class="dw-spec-row"><span class="dw-spec-label">Material</span><span class="dw-spec-value">{{ mat }}</span></div>{% endif %}
+      {% if bk != blank %}<div class="dw-spec-row"><span class="dw-spec-label">Backing</span><span class="dw-spec-value">{{ bk }}</span></div>{% endif %}
+      {% if wt != blank %}<div class="dw-spec-row"><span class="dw-spec-label">Weight</span><span class="dw-spec-value">{{ wt }}</span></div>{% endif %}
+      {% if col != blank %}<div class="dw-spec-row"><span class="dw-spec-label">Collection</span><span class="dw-spec-value">{{ col }}</span></div>{% endif %}
+      {% if style != blank %}<div class="dw-spec-row"><span class="dw-spec-label">Style</span><span class="dw-spec-value">{{ style }}</span></div>{% endif %}
+      {% if brand != blank %}<div class="dw-spec-row"><span class="dw-spec-label">Designer</span><span class="dw-spec-value">{{ brand }}</span></div>{% endif %}
+      {% if fin != blank %}<div class="dw-spec-row"><span class="dw-spec-label">Finish</span><span class="dw-spec-value">{{ fin }}</span></div>{% endif %}
+      {% if fire != blank %}<div class="dw-spec-row"><span class="dw-spec-label">Fire Rating</span><span class="dw-spec-value">{{ fire }}</span></div>{% endif %}
+      {% if care != blank %}<div class="dw-spec-row"><span class="dw-spec-label">Care</span><span class="dw-spec-value">{{ care }}</span></div>{% endif %}
+      {% if app != blank %}<div class="dw-spec-row"><span class="dw-spec-label">Application</span><span class="dw-spec-value">{{ app }}</span></div>{% endif %}
+      {% if pkg != blank %}<div class="dw-spec-row"><span class="dw-spec-label">Packaged</span><span class="dw-spec-value">{{ pkg }}</span></div>{% endif %}
+      {% if uom != blank %}<div class="dw-spec-row"><span class="dw-spec-label">Unit</span><span class="dw-spec-value">{{ uom }}</span></div>{% endif %}
+      {% if minord != blank and minord != '1' and minord != 1 %}<div class="dw-spec-row"><span class="dw-spec-label">Minimum Order</span><span class="dw-spec-value">{{ minord }}{% if ulabel != blank %} {{ ulabel }}{% endif %}</span></div>{% endif %}
+      {% if coo != blank %}<div class="dw-spec-row"><span class="dw-spec-label">Origin</span><span class="dw-spec-value">{{ coo }}</span></div>{% endif %}
+      {% comment %} mfr SKU row removed 2026-07-16 (DTD verdict A): raw mfr code is a private-label reverse-lookup key — backend metafield only, never customer-facing {% endcomment %}
+      {% if dur != blank %}<div class="dw-spec-row"><span class="dw-spec-label">Wyzenbeek</span><span class="dw-spec-value">{{ dur }}</span></div>{% endif %}
+      {% if mart != blank %}<div class="dw-spec-row"><span class="dw-spec-label">Martindale</span><span class="dw-spec-value">{{ mart }}</span></div>{% endif %}
+      {% if abr != blank %}<div class="dw-spec-row"><span class="dw-spec-label">Abrasion</span><span class="dw-spec-value">{{ abr }}</span></div>{% endif %}
+      {% if ai_note != blank %}
+      <div class="dw-spec-row" style="margin-top: 10px; padding-top: 10px; border-top: 1px solid #eee;">
+        <span class="dw-spec-label" style="color: #b45309; font-size: 13px;">AI Rooms</span>
+        <span class="dw-spec-value" style="color: #92400e; font-size: 13px; font-style: italic;">{{ ai_note }}</span>
+      </div>
+      {% endif %}
+    </div>
+  </details>
+  {% endif %}
+
+  {%- comment -%} PATTERN DESCRIPTION moved into the specs block when short enough (Steve 2026-07-28).
+     Long descriptions (e.g. Kravet-family products) exceed DESC_MAX chars and stay in the wide
+     gallery area instead — product-gallery.liquid gates on the SAME threshold so it renders in
+     exactly one place. DESC_MAX is tunable. {%- endcomment -%}
+  {% assign desc_len = product.description | strip_html | strip | size %}
+  {% if product.description != blank and desc_len <= 500 %}
+    <div class="dw-specs-desc">
+      <div class="dw-specs-desc__label">Description</div>
+      <div class="dw-specs-desc__body rte" itemprop="description">{{ product.description }}</div>
+    </div>
+  {% endif %}
+</div>
+{% endif %}
+
+{% comment %}
+Contact popup form
+{% endcomment %}
+<div id="custom-popup-overlay">
+  <div class="custom-popup-main">
+    <div class="custom-close">&times;</div>
+    <div class="content-main">
+      <div class="popup-content">
+        <h2 style="text-align:center;">Send us a message</h2>
+        {% form 'contact' %}
+        {% if form.errors %}<div class="error-message" style="display:none;"><span>{{ 'general.contact.error' | t }}</span></div>{% endif %}
+        {% if form.posted_successfully? %}<div class="success-message" style="display:none;">{{ 'general.contact.success' | t }}</div>{% endif %}
+        <div class="field-wrap sku"><input type="text" value="{{ product.variants.last.sku }}" name="contact[SKU]" readonly="true"></div>
+        <div class="field-wrap name"><input type="text" placeholder="Name" value="" name="contact2[name]" class="{% if form.errors contains 'author' %}error{% endif %}" required></div>
+        <div class="field-wrap email"><input type="email" name="contact[email]" autocorrect="off" autocapitalize="off" value="{% if form.email %}{{ form.email }}{% elsif customer %}{{ customer.email }}{% endif %}" class="{% if form.errors contains 'email' %}input--error{% endif %}" placeholder="Email" required></div>
+        <div class="field-wrap phone"><input type="text" placeholder="Phone number" value="" name="contact[phone number]" required></div>
+        <div class="field-wrap message"><textarea name="contact[message]" placeholder="Message" rows="5" required></textarea></div>
+        <input type="hidden" class="comment-check" value="" />
+        <input style="background-color:#000;color:#fff;" type="submit" value="{{ 'general.contact.submit' | t }}">
+        {% endform %}
+      </div>
+    </div>
+  </div>
+</div>
\ No newline at end of file
diff --git a/shopify/theme-LIVE-pull-20260728-colorbar/snippets/product-gallery.liquid b/shopify/theme-LIVE-pull-20260728-colorbar/snippets/product-gallery.liquid
new file mode 100644
index 00000000..5ad925ac
--- /dev/null
+++ b/shopify/theme-LIVE-pull-20260728-colorbar/snippets/product-gallery.liquid
@@ -0,0 +1,234 @@
+{% comment %}Updated: 2026-03-23T19:12:17.978750{% endcomment %}
+{% comment %}
+@param images_layout
+  Image layout setting - masonry, slideshow or list
+@param use_masonry
+@param product
+@param variant
+@param selected_media
+@param enable_zoom
+{% endcomment %}
+
+<div
+  class="
+    product-images
+    product-gallery
+    {% if images_layout == 'masonry' %}
+      product-images-masonry
+      product-images-masonry-{{ product.media.size }}
+    {% endif %}
+    "
+  {% if images_layout == 'masonry' and product.media.size > 1 %}
+    data-masonry-gallery
+  {% endif %}
+  data-product-gallery
+  data-product-gallery-layout="{{ images_layout }}"
+  {% if enable_zoom %}data-product-gallery-image-zoom{% endif %}
+>
+  {% if images_layout == 'masonry' and product.media.size > 1 %}
+    <div class="product-image-masonry-sizer" data-masonry-image-sizer></div>
+  {% endif %}
+    <div
+      class="
+        product-gallery--viewport
+        {% if images_layout == 'slideshow' and product.media.size > 1 %}product-gallery--viewport--has-navigation{% endif %}
+      "
+      data-product-gallery-viewport
+    >
+      {% assign models = product.media | where: 'media_type', 'model' %}
+      {%- if models.size > 0 -%}
+        <script>
+          window.ShopifyXR=window.ShopifyXR||function(){(ShopifyXR.q=ShopifyXR.q||[]).push(arguments)}
+          ShopifyXR('addModels', {{ models | json }});
+        </script>
+      {%- endif -%}
+      {% assign first_model = models | first %}
+      {% for media in product.media %}
+
+        {% assign use_large_image = false %}
+        {% if product.media.size == 2 %}
+          {% assign use_large_image = true %}
+        {% elsif forloop.first and use_masonry %}
+          {% assign use_large_image = true %}
+        {% endif %}
+
+        {% if media.media_type == 'model' %}
+          {% assign model = media %}
+        {% else %}
+          {% assign model = first_model %}
+        {% endif %}
+
+        {% if model %}
+          {% capture model_view_button %}
+            <button
+              class="product-gallery--viewinyourspace"
+              data-shopify-xr
+              data-shopify-model3d-id="{{ model.id }}"
+              data-shopify-title="{{ product.title }}"
+              data-shopify-xr-hidden
+              data-viewinyourspace
+            >
+              {% render 'icons', id: 'ar' %}
+              {{ 'products.media.view_in_your_space' | t }}
+            </button>
+          {% endcapture %}
+        {% endif %}
+
+        <figure
+          class="product-gallery--viewport--figure {% if use_large_image %}product-image-wide{% endif %}"
+          tabindex="-1"
+          {% if images_layout != 'list' %}
+            {% if selected_media.id != media.id %}
+              aria-hidden="true"
+            {% else %}
+              aria-hidden="false"
+            {% endif %}
+          {% endif %}
+          data-product-gallery-figure="{{ forloop.index0 }}"
+          {% if images_layout == 'slideshow' %}
+            data-product-gallery-selected="{%- if selected_media.id == media.id -%}true{%- else -%}false{%- endif -%}"
+          {% endif %}
+          data-media="{{ media.id }}"
+          data-media-type="{{ media.media_type }}"
+          >
+          <div class="product-gallery--media-wrapper">
+            {% case media.media_type %}
+            {% when 'image' %}
+              {%- capture data_attr -%}
+                {% if enable_zoom %}data-image-zoom="{{ media.id }}"{% endif %}
+              {%- endcapture -%}
+              {%
+                render 'rimg'
+                img: media.preview_image,
+                size: '1024x1024',
+                attr: data_attr,
+                lazy: true,
+              %}
+              {% if enable_zoom %}
+                <div class="product-zoom" data-product-zoom-id="{{ media.id }}"></div>
+              {% endif %}
+            {% when 'model' %}
+              {{ media | model_viewer_tag: image_size: '1024x', reveal: 'interaction' , toggleable: true, interaction-prompt-threshold: 0 }}
+            {% when 'video' %}
+              {{ media | media_tag: image_size: '1024x' }}
+            {% when 'external_video' %}
+              {{ media | media_tag: image_size: '1024x' }}
+            {% else %}
+              {{ media | media_tag }}
+            {% endcase %}
+          </div>
+          {% if images_layout == 'slideshow' %}
+            {{ model_view_button }}
+          {% endif %}
+        </figure>
+        {% if images_layout == 'list' %}
+            {{ model_view_button }}
+        {% endif %}
+      {% else %}
+        <figure
+          class="product-gallery--viewport--figure"
+          data-product-gallery-selected="true"
+        >
+          {{ 'product-1' | placeholder_svg_tag: 'placeholder-svg' }}
+        </figure>
+      {% endfor %}
+
+    </div>
+
+    {% comment %} Colors In This Pattern — big swatch cards w/ % (replaces color-dots). Sits between the product images and Other Colorways. {% endcomment %}
+    {% render 'color-palette' %}
+    {% render 'colorway-siblings' %}
+
+    {% if images_layout == 'slideshow' and product.media.size > 1 %}
+      <div class="product-gallery-navigation-outer-wrapper">
+        {% if product.media.size > 4 %}
+          <span class="product-thumbnails-navigation-previous">&#xe601;</span>
+        {% endif %}
+        <div class="product-gallery--navigation-wrapper">
+          <div
+             class="product-gallery--navigation {% if product.media.size > 4 %}has-side-scroll{% endif %}"
+            data-product-gallery-navigation
+          >
+            {% for media in product.media %}
+              <button
+                class="
+                  product-gallery--media-thumbnail
+                  product-gallery--{{ media.media_type }}-thumbnail
+                "
+                type="button"
+                tab-index="0"
+                aria-label="{{ media.alt }} {{ 'general.accessibility.nav_product_thumbnail' | t }}"
+                data-product-gallery-thumbnail="{{ forloop.index0 }}"
+                data-product-gallery-selected="{%- if selected_media.id == media.id -%}true{%- else -%}false{%- endif -%}"
+                data-media="{{ media.id }}"
+                data-media-type="{{ media.media_type }}"
+              >
+                {%
+                  render 'rimg'
+                  img: media.preview_image,
+                  size: '100x100',
+                  lazy: true
+                %}
+                {% case media.media_type %}
+                {% when 'model' %}
+                  {% render 'icons', id:'model-thumb' %}
+                {% when 'video' %}
+                  {% render 'icons', id: 'play-thumb' %}
+                {% when 'external_video' %}
+                  {% render 'icons', id: 'play-thumb' %}
+                {% endcase %}
+              </button>
+            {% endfor %}
+          </div>
+        </div>
+        {% if product.media.size > 4 %}
+          <span class="product-thumbnails-navigation-next">&#xe600;</span>
+        {% endif %}
+      </div>
+    {% endif %}
+    <div class="product__social" {{ block.shopify_attributes }}>
+      {% render 'share-buttons' %}
+    </div>
+    {%- comment -%} Pattern Description (Steve 2026-07-28): SHORT descriptions moved into the
+       left specs block (product-description-meta.liquid). Only render the wide block here when
+       the description is LONG (> DESC_MAX chars, e.g. Kravet-family products) or in the editor
+       onboarding state. SAME 500-char threshold as the specs snippet so it shows in exactly
+       one place. {%- endcomment -%}
+    {% assign desc_len = product.description | strip_html | strip | size %}
+    {% if product == blank or desc_len > 500 %}
+    <div class="product-content__desktop">
+      <h4 style="margin-bottom: 0.25em;"><strong>Pattern Description:</strong></h4>
+
+      {% if product != blank and product.description != blank %}
+        <div class="product-description rte" itemprop="description" style="margin-top: 0;">
+          {{ product.description }}
+        </div>
+      {% elsif product == blank %}
+        <div class="product-description rte" itemprop="description" style="margin-top: 0;">
+          {{ 'products.product.onboarding.description' | t }}
+        </div>
+      {% endif %}
+   </div>
+   {% endif %}
+</div>
+{% if images_layout == 'masonry' and product.media.size > 1 %}
+  <div class="mobile-slider-nav-wrapper">
+    {{ model_view_button }}
+    <div data-mobile-slider-navigation>
+      <button class="mobile-slider-prev-next" data-mobile-slider-button="prev">
+        {% render 'icons', id: 'prev-button' %}
+      </button>
+      <ol data-mobile-slider-dots>
+        {% for media in product.media %}
+          <li class='dot' aria-label="Page dot {{ forloop.index0 }}" data-mobile-slider-dot data-slide-dot-index="{{ forloop.index0 }}"></li>
+        {% endfor %}
+      </ol>
+      <button class="mobile-slider-prev-next" data-mobile-slider-button="next">
+        {% render 'icons', id: 'next-button' %}
+      </button>
+    </div>
+  </div>
+{% endif %}
+
+
+{% render 'full-monte-express' %}

← 4eeb4db8 auto-save: 2026-07-28T10:29:49 (4 files) — shopify/scripts/d  ·  back to Designer Wallcoverings  ·  auto-save: 2026-07-28T11:00:01 (7 files) — shopify/scripts/c 58ca2dbb →