← back to Dw Theme Live Signin Split
snapshot: LIVE theme (carnegie-color-swatch 145121607731) baseline before signin split
db40c7c74c4cc8bfaace21ecba307d13578fad1a · 2026-08-31 10:14:51 -0700 · Steve
Files touched
A .gitignoreA layout/theme.liquidA sections/header.liquidA snippets/dw-signin-modal.liquidA snippets/mobile-nav.liquidA templates/customers/account.liquidA templates/customers/register.liquid
Diff
commit db40c7c74c4cc8bfaace21ecba307d13578fad1a
Author: Steve <steve@designerwallcoverings.com>
Date: Mon Aug 31 10:14:51 2026 -0700
snapshot: LIVE theme (carnegie-color-swatch 145121607731) baseline before signin split
---
.gitignore | 8 +
layout/theme.liquid | 1389 +++++++++++++++++++++++++++++++++++
sections/header.liquid | 589 +++++++++++++++
snippets/dw-signin-modal.liquid | 175 +++++
snippets/mobile-nav.liquid | 135 ++++
templates/customers/account.liquid | 95 +++
templates/customers/register.liquid | 77 ++
7 files changed, 2468 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1924158
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+node_modules/
+.env*
+tmp/
+*.log
+.DS_Store
+dist/
+build/
+.next/
diff --git a/layout/theme.liquid b/layout/theme.liquid
new file mode 100644
index 0000000..2b78e43
--- /dev/null
+++ b/layout/theme.liquid
@@ -0,0 +1,1389 @@
+{% comment %}DW-CHINA-BLOCK-START{% endcomment %}
+{% assign dw_blocked_countries = "CN" | split: "," %}
+{% assign dw_visitor_country = localization.country.iso_code | upcase %}
+{% assign dw_is_blocked = false %}
+{% for dw_bc in dw_blocked_countries %}
+ {% assign dw_bc_trimmed = dw_bc | strip %}
+ {% if dw_visitor_country == dw_bc_trimmed %}
+ {% assign dw_is_blocked = true %}
+ {% endif %}
+{% endfor %}
+
+{% if dw_is_blocked %}
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<!-- DW-CACHE-TOUCH:20260804-1030-scrolljump -->
+<!-- DW-CHINA-JS-BLOCK-START -->
+<script>
+(function() {
+ var blockedCountries = ['CN'];
+ fetch('/browsing_context_suggestions.json', {method: 'GET', credentials: 'same-origin'})
+ .then(function(r) { return r.json(); })
+ .catch(function() { return null; })
+ .then(function(data) {
+ if (data && data.detected_values && data.detected_values.country && data.detected_values.country.handle) {
+ var detectedCountry = data.detected_values.country.handle.toUpperCase();
+ if (blockedCountries.indexOf(detectedCountry) !== -1) {
+ var container = document.createElement('div');
+ container.innerHTML = '<div style="position:fixed;top:0;left:0;width:100%;height:100%;background:#f5f5f5;z-index:999999;display:flex;align-items:center;justify-content:center;font-family:-apple-system,BlinkMacSystemFont,sans-serif"><div style="text-align:center;padding:60px 40px;background:#fff;border-radius:12px;box-shadow:0 4px 24px rgba(0,0,0,.08);max-width:520px;width:90%"><div style="font-size:48px;margin-bottom:20px">🌐</div><h1 style="font-size:24px;margin-bottom:16px;font-weight:600;color:#333">Region Not Available</h1><p style="font-size:16px;line-height:1.6;color:#666;margin-bottom:12px">This store is not available in your region.</p><p style="font-size:16px;line-height:1.6;color:#666">We do not ship to or serve customers in your area at this time.</p></div></div>';
+ document.body.innerHTML = '';
+ document.body.appendChild(container);
+ }
+ }
+ });
+})();
+</script>
+<!-- DW-CHINA-JS-BLOCK-END -->
+
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Region Not Available</title>
+ <style>
+ * { margin: 0; padding: 0; box-sizing: border-box; }
+ body {
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+ background: #f5f5f5;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ min-height: 100vh;
+ color: #333;
+ }
+ .container {
+ text-align: center;
+ padding: 60px 40px;
+ background: white;
+ border-radius: 12px;
+ box-shadow: 0 4px 24px rgba(0,0,0,0.08);
+ max-width: 520px;
+ width: 90%;
+ }
+ .icon { font-size: 48px; margin-bottom: 20px; }
+ h1 { font-size: 24px; margin-bottom: 16px; font-weight: 600; }
+ p { font-size: 16px; line-height: 1.6; color: #666; margin-bottom: 12px; }
+ .contact { margin-top: 24px; font-size: 14px; color: #999; }
+ .contact a { color: #2563eb; text-decoration: none; }
+ </style>
+<script src="{{ 'dw-grid-control.js' | asset_url }}" defer></script>
+
+
+
+
+
+<!-- cache-bust: 2026-03-25T00:54:55.724677 -->
+</head>
+<body>
+ <div class="container">
+ <div class="icon">🌐</div>
+ <h1>Region Not Available</h1>
+ <p>We're sorry, but this store is not available in your region.</p>
+ <p>We do not ship to or serve customers in your area at this time.</p>
+ <div class="contact">
+ Questions? Contact us at <a href="mailto:info@designerwallcoverings.com">info@designerwallcoverings.com</a>
+ </div>
+ </div>
+
+
+</body>
+</html>
+{% break %}
+{% endif %}
+{% comment %}DW-CHINA-BLOCK-END{% endcomment %}
+
+<!doctype html>
+<html
+ class="
+ no-js
+ loading
+ "
+ lang="{{ request.locale.iso_code }}"
+>
+<head>
+{% render 'cpc-collection-guard' %}
+<!-- Consent Mode v2 (TK-19): default-denied in EEA/UK/CH, analytics granted elsewhere; ads denied globally (DW runs no ads) -->
+<script>window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}
+gtag('consent','default',{analytics_storage:'granted',ad_storage:'denied',ad_user_data:'denied',ad_personalization:'denied'});
+gtag('consent','default',{analytics_storage:'denied',ad_storage:'denied',ad_user_data:'denied',ad_personalization:'denied',wait_for_update:500,region:["AT", "BE", "BG", "HR", "CY", "CZ", "DK", "EE", "FI", "FR", "DE", "GR", "HU", "IE", "IT", "LV", "LT", "LU", "MT", "NL", "PL", "PT", "RO", "SK", "SI", "ES", "SE", "IS", "LI", "NO", "GB", "CH"]});
+</script>
+<!-- Google tag (gtag.js) GA4 G-53F1QBZSG0 -->
+<script async src="https://www.googletagmanager.com/gtag/js?id=G-53F1QBZSG0"></script>
+<script>window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}gtag('js',new Date());gtag('config','G-53F1QBZSG0');</script>
+
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+
+ <!-- Preconnect Domains -->
+ <link rel="preconnect" href="https://cdn.shopify.com" crossorigin>
+ <link rel="preconnect" href="https://fonts.shopify.com" crossorigin>
+ <link rel="preconnect" href="https://monorail-edge.shopifysvc.com">
+
+ <!-- Preload Assets -->
+ <link rel="preload" href="{{ 'chiko-icons.woff' | asset_url }}" as="font" type="font/woff" crossorigin>
+ <link rel="preload" href="{{ 'pxu-social-icons.woff' | asset_url }}" as="font" type="font/woff" crossorigin>
+
+ <link rel="preload" href="{{ 'theme.css' | asset_url }}" as="style">
+
+ <link rel="preload" href="{{ 'modernizr-2.8.2.min.js' | asset_url }}" as="script">
+
+ {% if template contains 'cart' %}
+ <link rel="preload" href="{{ '/services/javascripts/countries.js' }}" as="script">
+ <link rel="preload" href="{{ 'shopify_common.js' | shopify_asset_url }}" as="script">
+ {% endif %}
+
+ {% if template contains 'customers' %}
+ <link rel="preload" href="{{ 'shopify_common.js' | shopify_asset_url }}" as="script">
+ <link rel="preload" href="{{ 'customer_area.js' | shopify_asset_url }}" as="script">
+ {% endif %}
+
+ <link rel="preload" href="{{ 'grid.js' | asset_url }}" as="script">
+
+ <script src="//cdata.modernpostcard.com/js/E3CA4636CEDAD4.js" async defer></script>
+
+ <title>
+ {{ page_title }}
+
+ {% if current_tags %}
+ – {{ current_tags | join: ', ' }}
+ {% endif %}
+
+ {% if current_page != 1 %}
+ – {{ 'general.pagination.page' | t: page_number: current_page }}
+ {% endif %}
+
+ {% unless page_title contains shop.name %}
+ – {{ shop.name }}
+ {% endunless %}
+ </title>
+
+ {% if page_description %}
+ <meta name="description" content="{{ page_description | escape }}" />
+ {% endif %}
+
+ {% if settings.favicon %}
+ <link rel="shortcut icon" href="{{ settings.favicon | img_url: '32x32' }}" type="image/png" />
+ {% endif %}
+
+ {% if template contains 'collection' and current_tags %}
+ <meta name="robots" content="noindex" />
+ <link rel="canonical" href="{{ shop.url }}{{ collection.url }}" />
+ {% else %}
+ <link rel="canonical" href="{{ canonical_url }}" />
+ {% endif %}
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
+
+ {%- render 'head.import-map' -%}
+ {%- render 'head.is-land' -%}
+
+ {% comment %}
+ {% render 'boost-sd-fallback' %}
+ {% endcomment %}
+ {% comment %}cache-touch 20260730-133317 recompile-guard{% endcomment %}{% render 'boost-infinite-override' %}
+ {%- if template.name == 'page' and page.handle == 'trade-only-benefits' -%}
+ <script>
+ (function(){
+ var append=Node.prototype.appendChild;
+ Node.prototype.appendChild=function(node){
+ if(node&&node.tagName==='SCRIPT'&&/cdn3?\.shopixai\.com/i.test(node.src||'')) return node;
+ return append.call(this,node);
+ };
+ })();
+ </script>
+ {%- endif -%}
+ {{ content_for_header }}
+
+ {% liquid
+ assign heading_text_transform = 'none'
+ if settings.heading-font-small-caps
+ assign heading_text_transform = 'uppercase'
+ endif
+
+ assign button_text_transform = 'none'
+ assign button_letter_spacing = '0em'
+ if settings.button-font-small-caps
+ assign button_text_transform = 'uppercase'
+ assign button_letter_spacing = '0.05em'
+ endif
+ %}
+
+ <style>
+ :root {
+ /* ------------------------------------------------------------
+ Typography
+ ------------------------------------------------------------ */
+ /* Body */
+ --element-text-font-size--body-lg: 1.286rem; /* Product price */
+ --element-text-font-size--body-sm: var(--text-size-3-5); /* SKU, installments, variant labels */
+ --element-text-font-family--body: {{ settings.font_body.family }}, {{ settings.font_body.fallback_families }};
+ --element-text-font-weight--body: {{ settings.font_body.weight }};
+
+ /* Headings */
+ --element-text-font-size--heading-xl: 2.5rem; /* Product title */
+ --element-text-font-family--heading: {{ settings.font_heading.family }}, {{ settings.font_heading.fallback_families }};
+ --element-text-font-weight--heading: {{ settings.font_heading.weight }};
+ --element-text-line-height--heading: 1.25;
+ --element-text-text-transform--heading: {{ heading_text_transform }};
+
+ /* Buttons */
+ --element-button-font-family: {{ settings.font_button.family }}, {{ settings.font_button.fallback_families }};
+ --element-button-text-transform: {{ button_text_transform }};
+ --element-button-letter-spacing: {{ button_letter_spacing }};
+
+ /* ------------------------------------------------------------
+ Colors
+ ------------------------------------------------------------ */
+ --color-primary: {{ settings['body-text-color'] }};
+ --color-secondary: {{ settings['background-color'] }};
+ --root-color-primary: {{ settings['body-text-color'] }};
+ --root-color-secondary: {{ settings['background-color'] }};
+ --color-focus: #0000ff;
+
+ --color-sale-tag-text: {{ settings['background-color'] }};
+ --color-sale-tag: {{ settings['product-badge-background-color'] }};
+
+ --element-button-color-primary: {{ settings['button-color'] }};
+ --element-button-color-secondary: {{ settings['accent-color'] }};
+
+ --element-text-color: {{ settings['body-text-color'] }};
+ --element-text-color--heading: {{ settings['heading-color'] }};
+
+ --element-input-color-primary: {{ settings['form-select-color'] }};
+ --element-input-color-secondary: {{ settings['form-select-background'] }};
+
+ /* ------------------------------------------------------------
+ Other
+ ------------------------------------------------------------ */
+ --element-badge-radius: 2px;
+ --element-button-radius: 2px;
+
+ --layout-section-max-inline-size: 1260px;
+ --layout-section-padding-inline: 30px;
+ }
+
+ /* ------------------------------------------------------------
+ Component overrides
+ ------------------------------------------------------------ */
+
+ ::before,
+ ::after {
+ box-sizing: content-box;
+ }
+ product-hot-reload ::before,
+ product-hot-reload ::after {
+ box-sizing: border-box;
+ }
+
+ /* Lightbox */
+ .overlay-lightbox__overlay {
+ z-index: 9999;
+ }
+
+ /* Pick up */
+ .element-icon-in-stock {
+ fill: currentColor;
+ }
+
+ /* Divider */
+ hr.element-divider {
+ height: 0;
+ background: transparent;
+ }
+
+ /* Drawer */
+ overlay-drawer .element-button {
+ --element-button-color-primary: {{ settings.body-text-color }};
+ --element-icon-stroke-width: 3px;
+ }
+
+ /* Heading */
+ .element-text:is([class*=element-text--heading]) {
+ --_color: var(--element-text-color--heading);
+ }
+
+ /* Element Input */
+ .element-input {
+ --_color-box-shadow: {{ settings['form-select-border-color'] }};
+ }
+
+ /* Variant Labels */
+ label.element-text:is([class*=element-text--body]):where(.element-text--body-sm) {
+ color: {{ settings['heading-color'] }};
+ font-size: 1rem;
+
+ .element-text:first-child {
+ color: {{ settings['heading-color'] }};
+ }
+ }
+
+ /* Element Select */
+ element-select {
+ --color-primary: {{ settings['form-select-border-color'] }};
+ --element-button-color-primary: {{ settings['form-select-color'] }};
+ --element-button-color-secondary: {{ settings['form-select-background'] }};
+ --element-button-box-shadow: inset 0 0 0 1px {{ settings['form-select-border-color'] }};
+ --element-button-font-family: {{ settings.font_body.family }}, {{ settings.font_body.fallback_families }};
+ --element-button-text-transform: none;
+ }
+ element-select.element-select__wrapper--focused .element-button {
+ box-shadow: inset 0 0 0 var(--element-button-border-width--focus) var(--_color-focus);
+ border: none;
+ }
+
+ /* Media Gallery */
+ .media-gallery__thumb {
+ border-radius: 0;
+ }
+
+ /* ATC */
+
+ product-form .element-button[type="submit"] {
+ --element-button-padding-block: var(--size-5);
+ --_color-text: {{ settings['button-color'] }};
+ --_color-background: {{ settings['accent-color'] }};
+ --_box-shadow: none;
+
+ &:disabled {
+ color: #888888 !important;
+ background-color: #cccccc !important;
+ }
+ }
+
+ product-form:has(.element-button--shopify-payment-wrapper) .element-button[type="submit"] {
+ --element-button-color-primary: {{ settings['secondary-button-color'] }};
+ --element-button-color-secondary: {{ settings['secondary-button-background'] }};
+ }
+
+ .shopify-payment-button .shopify-payment-button__button.shopify-payment-button__button--unbranded,
+ .shopify-payment-button .shopify-payment-button__button {
+ --element-text-line-height--body-md: 1;
+ --element-button-color-primary: {{ settings['accent-color'] }};
+ --element-button-color-secondary: {{ settings['button-color'] }};
+ --element-button-padding-block: var(--size-5);
+ --_box-shadow: none;
+
+ text-transform: var(--element-button-text-transform);
+ }
+ </style>
+
+ {% assign x_handle = settings.social-x-link | split: 'x.com/' | last | split: 'twitter.com/' | last %}
+ {%
+ render 'social-meta-tags',
+ twitter_handle: x_handle,
+ default_image: page_image,
+ %}
+
+ <!-- Theme CSS -->
+ <link rel="stylesheet" href="{{ 'theme.css' | asset_url }}">
+ {% render 'dw-product-styles' %}
+ <link rel="stylesheet" href="{{ 'custom.css' | asset_url }}">
+ <link rel="stylesheet" href="{{ 'dw-pdp-restyle.css' | asset_url }}">
+ {% if settings.custom-css != blank %}
+ <style>
+ {{ settings.custom-css }}
+ </style>
+ {% endif %}
+
+ <!-- Theme object -->
+ {% comment %}Inject theme-object begin{% endcomment %}
+ <script>
+ var Theme = {};
+ Theme.version = "7.1.0";
+ Theme.name = 'Grid';
+
+ Theme.currency = {{ shop.currency | json }};
+ Theme.moneyFormat = {{ shop.money_format | strip_html | json }};
+
+ Theme.pleaseSelectText = "{{ 'general.general.please_select' | t | strip_newlines | escape }}";
+
+ Theme.addToCartSuccess = "{{ 'products.product.success_html' | t: product: '**product**', cart_link: '**cart_link**', continue_link: '**continue_link**', checkout_link: '**checkout_link**' | strip_newlines | escape }}";
+
+ {% if shop.customer_accounts_enabled and customer %}
+ Theme.customerLoggedIn = true;
+ {% endif %}
+
+ Theme.shippingCalculator = true;
+ Theme.shippingButton = "{{ 'cart.shipping_calculator.submit' | t | strip_newlines | escape }}";
+ Theme.shippingDisabled = "{{ 'cart.shipping_calculator.disabled' | t | strip_newlines | escape }}";
+
+ {% if shop.customer_accounts_enabled and customer and customer.default_address %}
+ Theme.customerAddress = {{ customer.default_address | json }};
+ {% endif %}
+
+ Theme.shippingCalcErrorMessage = "{{ 'cart.shipping_calculator.error' | t | strip_newlines | replace: '"','\\"' }}";
+ Theme.shippingCalcMultiRates = "{{ 'cart.shipping_calculator.rates_html' | t | strip_newlines | replace: '"','\\"' }}";
+ Theme.shippingCalcOneRate = "{{ 'cart.shipping_calculator.rate' | t | strip_newlines | replace: '"','\\"' }}";
+ Theme.shippingCalcNoRates = "{{ 'cart.shipping_calculator.no_rates' | t | strip_newlines | replace: '"','\\"' }}";
+ Theme.shippingCalcRateValues = "{{ 'cart.shipping_calculator.rate_values_html' | t | strip_newlines | replace: '"','\\"' }}";
+
+ Theme.routes = {
+ "root_url": "{{ routes.root_url }}",
+ "account_url": "{{ routes.account_url }}",
+ "account_login_url": "{{ routes.account_login_url }}",
+ "account_logout_url": "{{ routes.account_logout_url }}",
+ "account_register_url": "{{ routes.account_register_url }}",
+ "account_addresses_url": "{{ routes.account_addresses_url }}",
+ "collections_url": "{{ routes.collections_url }}",
+ "all_products_collection_url": "{{ routes.all_products_collection_url }}",
+ "search_url": "{{ routes.search_url }}",
+ "cart_url": "{{ routes.cart_url }}",
+ "cart_add_url": "{{ routes.cart_add_url }}",
+ "cart_change_url": "{{ routes.cart_change_url }}",
+ "cart_clear_url": "{{ routes.cart_clear_url }}",
+ "product_recommendations_url": "{{ routes.product_recommendations_url }}",
+ "predictive_search_url": "{{ routes.predictive_search_url }}",
+ };
+ </script>
+ {% comment %}Inject theme-object end{% endcomment %}
+
+ {% render 'jquery-snippet' %}
+ <script src="{{ 'custom.js' | asset_url }}" defer></script>
+
+ <script>
+ (function() {
+ document.documentElement.classList.remove('no-js');
+ window.addEventListener('DOMContentLoaded', function() {
+ document.documentElement.classList.remove('loading');
+ });
+ window.setTimeout(function() {
+ document.documentElement.classList.remove('loading');
+ }, 2000);
+
+ if (!window.MutationObserver || !window.MutationObserver.prototype) {
+ return;
+ }
+ var originalObserve = window.MutationObserver.prototype.observe;
+ window.MutationObserver.prototype.observe = function(target, options) {
+ if (!(target instanceof Node)) {
+ return;
+ }
+ return originalObserve.call(this, target, options);
+ };
+ })();
+ </script>
+
+<script src="{{ 'dw-grid-control.js' | asset_url }}" defer></script>
+<script src="{{ 'dw-pdp-size-pills.js' | asset_url }}" defer></script>
+
+
+
+
+
+
+
+
+
+
+
+<!-- DW: Price hiding script REMOVED 2026-03-24 -->
+
+<style>
+/* DW 2026-06-25: grid price-hide REMOVED (Steve) — show prices everywhere */
+/* Restore on product pages + cart */
+#shopify-section-product [class*="price"],
+#shopify-section-product span.money,
+.product-add-to-cart span.money,
+.shopify-product-form span.money,
+.mini-cart span.money,
+.cart span.money {
+ display: inline !important;
+ visibility: visible !important;
+ opacity: 1 !important;
+ height: auto !important;
+ font-size: inherit !important;
+ line-height: inherit !important;
+ position: static !important;
+ pointer-events: auto !important;
+}
+/* Square images */
+.boost-sd__product-item [class*="product-image"],
+.boost-sd__product-item [class*="image-wrapper"] {
+ aspect-ratio: 1/1 !important;
+ overflow: hidden !important;
+}
+.boost-sd__product-item img {
+ width: 100% !important;
+ height: 100% !important;
+ object-fit: cover !important;
+}
+/* Hide View As toggle */
+[class*="view-as"], [class*="viewAs"], .boost-sd__toolbar [class*="view"], .boost-sd [class*="toolbar-view"] {
+ display: none !important;
+}
+/* Hide View As toggle */
+[class*="view-as"],[class*="viewAs"],.boost-sd__toolbar [class*="view"],.boost-sd [class*="toolbar"] [class*="view"]{display:none!important}
+/* Center text */
+.boost-sd__product-item,
+.boost-sd__product-item [class*="title"],
+.boost-sd__product-item [class*="vendor"],
+.boost-sd__product-item p,
+.dw-vendor-link {
+ text-align: center !important;
+}
+</style>
+<!-- DW: killPrices REMOVED 2026-03-24 -->
+
+<!-- /DW -->
+
+{% comment %} DW: ItemList structured data for the Shop-by-Brand page (script tags are stripped from page body_html, so injected here) {% endcomment %}
+{% if page.handle == 'brands' %}{% render 'brands-jsonld' %}{% endif %}
+
+<!-- cache-bust: 2026-03-25T00:54:55.724677 -->
+
+{% if template contains 'product' %}
+<!-- DW: qty-inline v1 — quantity stepper moved to the right of the price (2026-07-02) -->
+<style>
+ .dw-price-qty-row{display:flex;align-items:center;gap:18px;flex-wrap:wrap}
+ .dw-price-qty-row .product-price{margin:0}
+ .dw-price-qty-row .product-price__unit-price{flex-basis:100%}
+ .dw-qty-inline{display:inline-flex;align-items:center;gap:8px}
+ .dw-qty-inline .product-option-quantity-label{margin:0;white-space:nowrap}
+ .dw-qty-inline .mm_quantity{margin:0}
+ .dw-qty-inline .product-option-quantity-label.hidden,
+ .dw-qty-inline .mm_quantity.hidden{display:none!important}
+</style>
+<script>
+(function(){
+ function relocate(){
+ if(document.querySelector('.dw-qty-inline')) return;
+ var qty=document.querySelector('form[action*="/cart/add"] .mm_quantity');
+ if(!qty) return;
+ var form=qty.closest('form');
+ var priceBox=(form&&form.querySelector('.product__price'))||document.querySelector('.product__price');
+ if(!priceBox) return;
+ var label=(form||document).querySelector('label.product-option-quantity-label');
+ var wrap=document.createElement('span'); wrap.className='dw-qty-inline';
+ if(label) wrap.appendChild(label);
+ wrap.appendChild(qty);
+ priceBox.classList.add('dw-price-qty-row');
+ priceBox.appendChild(wrap);
+ }
+ function init(){ relocate(); setTimeout(relocate,400); setTimeout(relocate,1200); }
+ if(document.readyState!=='loading') init(); else document.addEventListener('DOMContentLoaded',init);
+})();
+</script>
+<!-- /DW qty-inline -->
+{% endif %}
+
+{% if template contains 'product' %}
+{% unless product.handle contains 'dig-' %}
+<!-- DW: price-buy v1 — add-to-cart by price; request pill + PDF row; collapse sample selector (2026-07-06) -->
+<style>
+ .product__price.dw-has-add{display:flex;align-items:center;gap:16px;flex-wrap:wrap}
+ /* unify SKU / price / Quantity to one size (16px) */
+ .product-sku-label{font-size:16px!important}
+ .product__price .product-price-minimum.money,.product__price .money{font-size:16px!important}
+ /* tighten the price row so the qty row sits close WITHOUT a negative margin (no overlap) */
+ .product__price{min-height:0!important}
+ .product__price .product-price{margin:0!important;line-height:1.2!important}
+ /* more space between SKU and price (theme's .product__price margin is locked; use higher specificity) */
+ .product__price.dw-price-qty-row{margin-top:12px!important}
+ /* quantity + add-to-cart on one line below the price */
+ .dw-qty-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:16px}
+ /* match "QUANTITY:" to the SKU/PRICE label style (grey, uppercase, 500); label wraps text in <strong> */
+ .dw-qty-row .product-option-quantity-label,.dw-qty-row .product-option-quantity-label strong{color:rgb(136,136,136)!important;font-weight:500!important;text-transform:uppercase!important;letter-spacing:0.96px!important;font-size:16px!important}
+ .dw-qty-row .product-option-quantity-label{margin:0!important}
+ .dw-qty-row .mm_quantity,.dw-qty-row .mm_quantity *{font-weight:400!important}
+ .dw-qty-row .mm_quantity input.qty,.dw-qty-row .mm_quantity input[name="quantity"]{font-weight:700!important}
+ /* add-to-cart pill to the right of the stepper, SAME size as Request Sample */
+ .dw-qty-row .cowlendar-add-to-cart{width:auto!important;margin:0!important;flex:0 0 auto!important;height:auto!important;min-height:0!important;border-radius:999px!important;font-size:12px!important;font-weight:500!important;padding:10px 30px!important}
+ /* hide add-to-cart until the overlay places it in the qty row (kills the load-flicker);
+ the JS fail-safe reveals it regardless after 15s so it can never stay hidden */
+ input.add-to-cart.cowlendar-add-to-cart{visibility:hidden}
+ input.add-to-cart.cowlendar-add-to-cart.dw-add-ready{visibility:visible}
+ .dw-price-buy-row2{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-top:14px;max-width:430px}
+ /* Steve 2026-07-28 fix — Download-PDF was clipping in a narrow / zoomed info column.
+ Make Sample + Download-PDF two EQUAL shrink-to-fit halves (box-sizing so padding
+ can't push them past the column edge); they can never overflow/clip, and stack
+ full-width below 600px. */
+ .dw-price-buy-row2 .dl-sample-btn{flex:1 1 calc(50% - 6px)!important;width:auto!important;min-width:0!important;box-sizing:border-box!important;margin:0!important;padding-left:16px!important;padding-right:16px!important;white-space:nowrap!important}
+ .dw-price-buy-row2 .spec-sheet-controls{margin:0!important;transform:none!important;flex:1 1 calc(50% - 6px)!important;width:auto!important;min-width:0!important;max-width:none!important;box-sizing:border-box!important}
+ /* Download PDF -> black pill filling its half (no fixed cap, so it can shrink not clip) */
+ .dw-price-buy-row2 .spec-sheet-btn{display:inline-flex!important;align-items:center!important;justify-content:center!important;width:100%!important;max-width:none!important;min-width:0!important;box-sizing:border-box!important;padding:10px 12px!important;white-space:nowrap!important;background:#000!important;color:#fff!important;border-color:#000!important}
+ .dw-price-buy-row2 .spec-sheet-btn:hover{background:#1a1a1a!important}
+ @media (max-width:600px){
+ .dw-price-buy-row2{max-width:none}
+ .dw-price-buy-row2 .dl-sample-btn,
+ .dw-price-buy-row2 .spec-sheet-controls{flex:1 1 100%!important}
+ }
+ /* single-roll pricing note + dimensions (bolt / min-2 products only) */
+ .dw-sr-note{font-size:12px!important;color:rgb(136,136,136)!important;letter-spacing:.02em;margin-left:6px}
+ .dw-sr-dims{font-size:12px!important;color:rgb(90,90,90)!important;margin-left:18px;white-space:nowrap}
+ .dw-2roll-note{font-size:13px!important;font-weight:600;color:rgb(60,66,70)!important;margin-top:6px;letter-spacing:.01em}
+</style>
+<script>
+(function () {
+ if (window.__dwPriceBuyLoaded) return;
+ window.__dwPriceBuyLoaded = true;
+ function collapseSelector(form) {
+ var select = form.querySelector('select.single-option-selector');
+ if (!select) return false;
+ var opts = Array.prototype.slice.call(select.options);
+ var samples = opts.filter(function (o) { return /sample/i.test(o.value); });
+ if (!(opts.length <= 2 && samples.length >= 1)) return false;
+ var sellable = opts.filter(function (o) { return !/sample/i.test(o.value); })[0];
+ if (sellable && select.value !== sellable.value) {
+ select.value = sellable.value;
+ try { select.dispatchEvent(new Event('change', { bubbles: true })); }
+ catch (e) { var ev = document.createEvent('HTMLEvents'); ev.initEvent('change', true, false); select.dispatchEvent(ev); }
+ }
+ var pills = form.querySelector('.dw-size-pills');
+ if (pills && pills.parentNode) pills.parentNode.removeChild(pills);
+ return true;
+ }
+ // On bolt / min-2-single-roll products only: mark the price "/ single roll",
+ // show the single-roll dimensions, and split Length into D/R + S/R.
+ function srEnhance() {
+ var qi = document.querySelector('.mm_quantity input.qty, .mm_quantity input[name="quantity"]');
+ if (!qi) return;
+ var isBolt = parseInt(qi.getAttribute('min'), 10) === 2 || parseInt(qi.getAttribute('step'), 10) === 2;
+ if (!isBolt) return;
+ // Steve 2026-07-09: min/step==2 ALONE mislabels per-yard FABRICS that carry a
+ // 2-unit factor (UFAC=2 leaked onto ~144 Kravet-family multipurpose/upholstery
+ // goods). Roll language must key off the actual UNIT, not the quantity floor:
+ // only enhance when the sellable variant is genuinely sold by the roll/bolt.
+ var unitText = '';
+ var uSel = document.querySelector('form[action*="/cart/add"] select.single-option-selector');
+ if (uSel) Array.prototype.forEach.call(uSel.options, function (o) {
+ if (!/sample/i.test(o.value)) unitText += ' ' + o.value;
+ });
+ if (!/\b(roll|bolt)\b/i.test(unitText)) return;
+ // read the VISIBLE SPECIFICATIONS (.dw-specs -> .dw-spec-row -> .dw-spec-label/.dw-spec-value)
+ var specs = document.querySelector('.dw-specs');
+ function specVal(re) {
+ var out = null;
+ if (specs) Array.prototype.forEach.call(specs.querySelectorAll('.dw-spec-row'), function (rw) {
+ var l = ((rw.querySelector('.dw-spec-label') || {}).textContent || '').trim();
+ if (re.test(l)) out = ((rw.querySelector('.dw-spec-value') || {}).textContent || '').trim();
+ });
+ return out;
+ }
+ // single-roll length + dimensions (D/R length / 2, since 1 bolt = 2 single rolls)
+ var srLen = specVal(/^Length S\/R$/i);
+ if (!srLen) {
+ var dr = specVal(/^Length(?:\s*D\/R)?$/i);
+ if (dr) { var srHalf = dr.replace(/[\d.]+/g, function (x) { return (Math.round((parseFloat(x) / 2) * 1000) / 1000) + ''; }); srLen = /\d/.test(srHalf) ? srHalf : null; }
+ }
+ var wVal = specVal(/^Width$/i);
+ var srDims = (wVal && srLen) ? (wVal.split(/\s*x\s*/i)[0].trim() + ' x ' + srLen) : null;
+ // rewrite the visible specs once: Length -> Length D/R, add Single Roll + Length S/R rows above it
+ if (specs && !specs.dataset.dwSr) {
+ var lengthRow = null;
+ Array.prototype.forEach.call(specs.querySelectorAll('.dw-spec-row'), function (rw) {
+ if (/^Length$/i.test(((rw.querySelector('.dw-spec-label') || {}).textContent || '').trim())) lengthRow = rw;
+ });
+ if (lengthRow) {
+ specs.dataset.dwSr = '1';
+ lengthRow.querySelector('.dw-spec-label').textContent = 'Length D/R';
+ if (srDims) {
+ var srRow = document.createElement('div'); srRow.className = 'dw-spec-row';
+ srRow.innerHTML = '<span class="dw-spec-label">Length S/R</span><span class="dw-spec-value">' + srLen + '</span>';
+ lengthRow.parentNode.insertBefore(srRow, lengthRow);
+ var dimRow = document.createElement('div'); dimRow.className = 'dw-spec-row';
+ dimRow.innerHTML = '<span class="dw-spec-label">Single Roll</span><span class="dw-spec-value">' + srDims + '</span>';
+ lengthRow.parentNode.insertBefore(dimRow, srRow);
+ }
+ }
+ }
+ // price note + dims
+ var money = document.querySelector('.product__price .product-price-minimum.money');
+ if (money && !document.querySelector('.dw-sr-note')) { var note = document.createElement('span'); note.className = 'dw-sr-note'; note.textContent = '/ single roll'; money.after(note); }
+ var price = document.querySelector('.product__price');
+ if (srDims && price && !price.querySelector('.dw-sr-dims')) { var d = document.createElement('span'); d.className = 'dw-sr-dims'; d.textContent = 'Single roll: ' + srDims; price.appendChild(d); }
+ // Steve 2026-07-08: every 2-roll-minimum product states the increment rule plainly in the buy box.
+ if (price && !price.querySelector('.dw-2roll-note')) { var n2 = document.createElement('div'); n2.className = 'dw-2roll-note'; n2.textContent = 'Sold in 2 roll increments only'; price.appendChild(n2); }
+ }
+
+ // Clean the KEYWORDS list (display-only): drop namespaced tags, spec/operational
+ // tags, leading-"and" artifacts, and case duplicates. Tags stay intact for search.
+ function kwFilter() {
+ var box = document.querySelector('.keywords-desktop');
+ if (!box || box.dataset.dwKw) return;
+ var links = Array.prototype.slice.call(box.querySelectorAll('a'));
+ if (!links.length) return;
+ box.dataset.dwKw = '1';
+ var seen = {};
+ var DROP = /(:|fire\s*rat|astm|class\s*"?a"?|suitable\s+for|coated\s+paper|traffic|light\s+duty|heavy\s+duty|residential\s+use|background\s+color|non[-\s]?woven|scrubbab|removable|paste\s+the|washab)/i;
+ links.forEach(function (a) {
+ var t = (a.textContent || '').trim();
+ var key = t.toLowerCase().replace(/^and\s+/, '').trim();
+ var drop = t === '' || DROP.test(t) || /^and\s+/i.test(t) || seen[key];
+ if (drop) {
+ var nxt = a.nextSibling;
+ if (nxt && nxt.nodeType === 3 && /^[\s,]+$/.test(nxt.nodeValue)) nxt.parentNode.removeChild(nxt);
+ else { var prev = a.previousSibling; if (prev && prev.nodeType === 3 && /^[\s,]+$/.test(prev.nodeValue)) prev.parentNode.removeChild(prev); }
+ a.parentNode.removeChild(a);
+ } else { seen[key] = 1; }
+ });
+ }
+
+ function build() {
+ var form = document.querySelector('.product__form') || document.querySelector('form[action*="/cart/add"]');
+ if (!form) return false;
+ var price = document.querySelector('.product__price');
+ if (!price) return false;
+ var req = form.querySelector('.dl-sample-btn');
+ var pdf = document.querySelector('.spec-sheet-controls');
+ var row2 = document.querySelector('.dw-price-buy-row2');
+ if (!row2 && req) {
+ row2 = document.createElement('div');
+ row2.className = 'dw-price-buy-row2';
+ price.parentNode.insertBefore(row2, price.nextSibling);
+ }
+ if (row2) {
+ if (req && req.parentNode !== row2) row2.appendChild(req);
+ if (pdf && pdf.parentNode !== row2) row2.appendChild(pdf);
+ }
+ // quantity + add-to-cart on their own line, between the price and row2.
+ var qty = document.querySelector('.mm_quantity');
+ var qlabel = document.querySelector('.product-option-quantity-label');
+ var qrow = document.querySelector('.dw-qty-row');
+ if (qty && !qrow) {
+ qrow = document.createElement('div');
+ qrow.className = 'dw-qty-row';
+ price.parentNode.insertBefore(qrow, price.nextSibling);
+ }
+ if (qrow) {
+ if (qlabel && qlabel.parentNode !== qrow) qrow.appendChild(qlabel);
+ if (qty && qty.parentNode !== qrow) qrow.appendChild(qty);
+ var add = document.querySelector('input.add-to-cart.cowlendar-add-to-cart, .cowlendar-add-to-cart');
+ if (add && add.offsetParent !== null && add.parentNode !== qrow) qrow.appendChild(add);
+ }
+ var collapsed = collapseSelector(form);
+ if (collapsed) {
+ Array.prototype.forEach.call(document.querySelectorAll('.dw-size-pill'), function (b) {
+ if (b.parentNode) b.parentNode.removeChild(b);
+ });
+ }
+ return !!(row2 && row2.querySelector('.dl-sample-btn'));
+ }
+ function placeAndReveal() {
+ build();
+ srEnhance();
+ kwFilter();
+ var placed = document.querySelector('.dw-qty-row .cowlendar-add-to-cart');
+ if (placed) placed.classList.add('dw-add-ready');
+ }
+ function init() {
+ placeAndReveal();
+ // cowlendar injects the add-to-cart late; keep trying to place it for ~20s
+ var tries = 0, iv = setInterval(function () { placeAndReveal(); if (++tries > 100) clearInterval(iv); }, 200);
+ try {
+ var mo = new MutationObserver(function () { placeAndReveal(); });
+ mo.observe(document.body, { childList: true, subtree: true });
+ setTimeout(function () { mo.disconnect(); }, 20000);
+ } catch (e) {}
+ // fail-safe: never leave the add-to-cart hidden, even if placement never happens
+ setTimeout(function () { var a = document.querySelector('.cowlendar-add-to-cart'); if (a) a.classList.add('dw-add-ready'); }, 15000);
+ }
+ if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init); else init();
+ window.addEventListener('load', function () { setTimeout(placeAndReveal, 800); });
+})();
+</script>
+<!-- /DW price-buy -->
+{% endunless %}
+{% endif %}
+
+</head>
+
+<body
+ class="
+ template-{{ template.name }}
+ template-suffix-{{ template.suffix }}
+
+ {% if customer %}
+ customer-logged-in
+ {% endif %}
+ "
+>
+
+ {%- comment -%}
+ ── China Region Block (added 2026-02-27) ──
+ Blocks visitors from CN country code with a full-screen overlay.
+ {%- endcomment -%}
+ {%- if localization.country.iso_code == 'CN' -%}
+ <div id="region-block" style="position:fixed;inset:0;z-index:999999;background:#ffffff;display:flex;align-items:center;justify-content:center;flex-direction:column;text-align:center;padding:40px;font-family:-apple-system,BlinkMacSystemFont,sans-serif;">
+ <h1 style="font-size:24px;color:#333;margin-bottom:16px;">This store is not available in your region</h1>
+ <p style="font-size:16px;color:#666;max-width:500px;">We apologize for the inconvenience, but this store does not currently serve customers in your region.</p>
+ </div>
+ <style>body{overflow:hidden !important;}</style>
+ {%- endif -%}
+
+ {% render 'dw-samples-banner' %}
+ {% sections 'header-group' %}
+
+ {%- assign dw_trade_experience = false -%}
+ {%- if customer and customer.tags contains 'trade_approved' -%}{%- assign dw_trade_experience = true -%}{%- endif -%}
+ {%- if template.name == 'page' and page.handle == 'trade-only-benefits' -%}
+ {% render 'dw-trade-apply' %}
+ {%- elsif template.name == 'index' and dw_trade_experience -%}
+ {% render 'dw-trade-home' %}
+ {%- else -%}
+ <div style="--background-color: {{ settings.background-color }}">
+ {%
+ render 'age-gate',
+ id: 'page',
+ sections: content_for_layout,
+ %}
+ </div>
+ {%- endif -%}
+
+ {% include 'quickshop' %}
+
+ {% comment %}Inject icon-star-symbol begin{% endcomment %}
+ <svg
+ class="icon-star-reference"
+ aria-hidden="true"
+ focusable="false"
+ role="presentation"
+ xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="3 3 17 17" fill="none"
+ >
+ <symbol id="icon-star">
+ <rect class="icon-star-background" width="20" height="20" fill="currentColor"/>
+ <path d="M10 3L12.163 7.60778L17 8.35121L13.5 11.9359L14.326 17L10 14.6078L5.674 17L6.5 11.9359L3 8.35121L7.837 7.60778L10 3Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
+ </symbol>
+ <clipPath id="icon-star-clip">
+ <path d="M10 3L12.163 7.60778L17 8.35121L13.5 11.9359L14.326 17L10 14.6078L5.674 17L6.5 11.9359L3 8.35121L7.837 7.60778L10 3Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+ </clipPath>
+ </svg>
+ {% comment %}Inject icon-star-symbol end{% endcomment %}
+
+ {%- unless template.name == 'page' and page.handle == 'trade-only-benefits' or template.name == 'index' and dw_trade_experience -%}
+ <div class="main-content">
+ {% comment %}cache-touch 20260730-133317 recompile-guard{% endcomment %}{% render "dw-boost-overrides" %}
+ {{ content_for_layout }}
+ </div>
+ {%- endunless -%}
+
+ <div class="site-overlay" data-site-overlay></div>
+
+ {% sections 'footer-group' %}
+
+ <!-- Scripts -->
+ <!-- Third Party JS Libraries -->
+ <script src="{{ 'modernizr-2.8.2.min.js' | asset_url }}" defer></script>
+
+ {% if template contains 'cart' %}
+ <script src="{{ '/services/javascripts/countries.js' }}" defer></script>
+ <script src="{{ 'shopify_common.js' | shopify_asset_url }}" defer></script>
+ {% endif %}
+
+ {% if template contains 'customers' %}
+ <script src="{{ 'shopify_common.js' | shopify_asset_url }}" defer></script>
+ <script src="{{ 'customer_area.js' | shopify_asset_url }}" defer></script>
+ {% endif %}
+
+ <script src="{{ 'grid.js' | asset_url }}" defer></script>
+
+ {% comment %}Inject @pixelunion/shopify-structured-data/structured-data-article begin{% endcomment %}
+ {% comment %}
+ Article structured data
+ https://developers.google.com/search/docs/data-types/articles
+ {% endcomment %}
+
+ {% if template contains 'article' %}
+ {%- capture article_description -%}
+ {%- if article.excerpt != blank -%}
+ {{ article.excerpt | strip_html }}
+ {%- else -%}
+ {{ article.content | truncatewords: 100 | strip_html }}
+ {%- endif -%}
+ {%- endcapture -%}
+
+ <script type="application/ld+json">
+ {
+ "@context": "http://schema.org",
+ "@type": "BlogPosting",
+ "mainEntityOfPage": {
+ "@type": "WebPage",
+ "@id": "{{ shop.url }}{{ article.url }}"
+ },
+ "headline": {{ article.title | json }},
+ {% if article.image %}
+ "image": {
+ "@type": "ImageObject",
+ "url": {{ article.image | img_url: '800x800' | prepend: 'https:' | json }},
+ "height": 800,
+ "width": 800
+ },
+ {% endif %}
+ "datePublished": {{ article.published_at | date: '%Y-%m-%dT%H:%M:%S%z' | json}},
+ "dateModified": {{ article.published_at | date: '%Y-%m-%dT%H:%M:%S%z' | json}},
+ "author": {
+ "@type": "Person",
+ "name": {{ article.author | json }}
+ },
+ "publisher": {
+ "@type": "Organization",
+ "name": {{ shop.name | json }},
+ "logo": {
+ "@type": "ImageObject",
+ "url": {{ article.user.image | img_url: '200x200' | prepend: 'https:' | json }}
+ }
+ },
+ "description": {{ article_description | json }}
+ }
+ </script>
+ {% endif %}
+ {% comment %}Inject @pixelunion/shopify-structured-data/structured-data-article end{% endcomment %}
+
+ {% comment %}Inject @pixelunion/shopify-structured-data/structured-data-breadcrumbs begin{% endcomment %}
+ {% comment %}
+ Breadcrumbs
+ https://developers.google.com/search/docs/data-types/breadcrumbs
+ {% endcomment %}
+
+ {%- if current_tags -%}
+ {%- assign tag_names = current_tags | join: ', ' %}
+ {% comment %}Converting an array to a handle converts it to a string{% endcomment %}
+ {%- capture tag_handles -%}
+ {%- for tag in current_tags -%}
+ {{- tag | handle | append: '|' -}}
+ {%- endfor -%}
+ {%- endcapture -%}
+ {%- endif -%}
+
+ {% if collection.url == blank %}
+ {% assign collection_url = '/collections/all' %}
+ {% else %}
+ {% assign collection_url = collection.url %}
+ {% endif %}
+
+ {% if template.name == 'product'
+ or template.name == 'list-collections'
+ or template.name == 'collection'
+ or template.name == 'blog'
+ or template.name == 'article'
+ or template.name == 'search'
+ or template.name == 'cart'
+ or template.name == 'page'
+ %}
+
+ <script type="application/ld+json">
+ {
+ "@context": "http://schema.org",
+ "@type": "BreadcrumbList",
+ "itemListElement": [
+ {% case template.name %}
+ {% when 'product' %}
+ {% if product.collections.size >= 1 %}
+ {
+ "@type": "ListItem",
+ "position": 1,
+ "item": {
+ "@id": "{{ shop.url }}/collections",
+ "name": {{ 'structured_data.breadcrumbs.collections' | t | json }}
+ }
+ },
+ {
+ "@type": "ListItem",
+ "position": 2,
+ "item": {
+ "@id": "{{ shop.url }}/collections/{{ product.collections.first.handle }}",
+ "name": {{ product.collections.first.title | json }}
+ }
+ },
+ {% else %}
+ {
+ "@type": "ListItem",
+ "position": 1,
+ "item": {
+ "@id": "{{ shop.url }}/products",
+ "name": {{ 'structured_data.breadcrumbs.products' | t | json }}
+ }
+ },
+ {% endif %}
+ {
+ "@type": "ListItem",
+ "position": {% if product.collections.size >= 1 %}3{% else %}2{% endif %},
+ "item": {
+ "@id": "{{ shop.url }}{{ product.url | within: collection }}",
+ "name": {{ product.title | json }}
+ }
+ }
+ {% when 'list-collections' %}
+ {
+ "@type": "ListItem",
+ "position": 1,
+ "item": {
+ "@id": "{{ shop.url }}/collections",
+ "name": {{ 'structured_data.breadcrumbs.collections' | t | json }}
+ }
+ }
+ {% if current_page != 1 %}
+ ,
+ {
+ "@type": "ListItem",
+ "position": 2,
+ "item": {
+ "@id": "{{ shop.url }}/collections",
+ "name": {{ 'structured_data.breadcrumbs.page' | t: page: current_page | json }}
+ }
+ }
+ {% endif %}
+ {% when 'collection' %}
+ {
+ "@type": "ListItem",
+ "position": 1,
+ "item": {
+ "@id": "{{ shop.url }}/collections",
+ "name": {{ 'structured_data.breadcrumbs.collections' | t | json }}
+ }
+ },
+ {
+ "@type": "ListItem",
+ "position": 2,
+ "item": {
+ "@id": "{{ shop.url }}{{ collection_url }}",
+ "name": {{ collection.title | json }}
+ }
+ }
+ {% if current_tags %}
+ ,
+ {
+ "@type": "ListItem",
+ "position": 3,
+ "item": {
+ "@id": "{{ shop.url }}{{ collection_url }}/{{- tag_handles | split: '|' | join: '+' -}}",
+ "name": {{ 'structured_data.breadcrumbs.tags_html' | t: tags: tag_names | json }}
+ }
+ }
+ {% endif %}
+ {% if current_page != 1 %}
+ {% if current_tags %}
+ {% assign position = 4 %}
+ {% else %}
+ {% assign position = 3 %}
+ {% endif %}
+ ,
+ {
+ "@type": "ListItem",
+ "position": {{ position }},
+ "item": {
+ "@id": "{{ shop.url }}/collections?page={{ current_page }}",
+ "name": {{ 'structured_data.breadcrumbs.page' | t: page: current_page | json }}
+ }
+ }
+ {% endif %}
+ {% when 'blog' or 'article' %}
+ {
+ "@type": "ListItem",
+ "position": 1,
+ "item": {
+ "@id": "{{ shop.url }}{{ blog.url }}",
+ "name": {{ blog.title | json }}
+ }
+ }
+ {% if template.name == 'article' %}
+ ,
+ {
+ "@type": "ListItem",
+ "position": 2,
+ "item": {
+ "@id": "{{ shop.url }}{{ article.url }}",
+ "name": {{ article.title | json }}
+ }
+ }
+ {% elsif current_tags %}
+ ,
+ {
+ "@type": "ListItem",
+ "position": 2,
+ "item": {
+ "@id": "{{ shop.url }}{{ blog.url }}/tagged/{{- tag_handles | split: '|' | join: '+' -}}",
+ "name": {{ 'structured_data.breadcrumbs.tags_html' | t: tags: tag_names | json }}
+ }
+ }
+ {% endif %}
+ {% if current_page != 1 %}
+ {% if current_tags %}
+ {% assign position = 3 %}
+ {%- capture url -%}
+ {{ shop.url }}{{ blog.url }}/tagged/{{ tag_handles | split: '|' | join: '+' }}?page={{ current_page }}
+ {%- endcapture -%}
+ {% else %}
+ {% assign position = 2 %}
+ {%- capture url -%}
+ {{ shop.url }}{{ blog.url }}?page={{ current_page }}
+ {%- endcapture -%}
+ {% endif %}
+ ,
+ {
+ "@type": "ListItem",
+ "position": {{ position }},
+ "item": {
+ "@id": "{{ url }}",
+ "name": {{ 'structured_data.breadcrumbs.page' | t: page: current_page | json }}
+ }
+ }
+ {% endif %}
+ {% when 'search' %}
+ {
+ "@type": "ListItem",
+ "position": 1,
+ "item": {
+ "@id": "{{ shop.url }}/search",
+ "name": {{ 'structured_data.breadcrumbs.search' | t | json }}
+ }
+ }
+ {% if search.performed %}
+ ,
+ {
+ "@type": "ListItem",
+ "position": 2,
+ "item": {
+ "@id": "{{ shop.url }}/search?q={{ search.terms }}",
+ "name": {{ search.terms | json }}
+ }
+ }
+ {% if current_page != 1 %}
+ ,
+ {
+ "@type": "ListItem",
+ "position": 3,
+ "item": {
+ "@id": "{{ shop.url }}/search?page={{ current_page }}&q={{ search.terms }}",
+ "name": {{ 'structured_data.breadcrumbs.page' | t: page: current_page | json }}
+ }
+ }
+ {% endif %}
+ {% endif %}
+ {% when 'cart' %}
+ {
+ "@type": "ListItem",
+ "position": 1,
+ "item": {
+ "@id": "{{ shop.url }}/cart",
+ "name": {{ 'structured_data.breadcrumbs.cart' | t | json }}
+ }
+ }
+ {% when 'page' %}
+ {
+ "@type": "ListItem",
+ "position": 1,
+ "item": {
+ "@id": "{{ page.url }}",
+ "name": {{ page.title | json }}
+ }
+ }
+ {% else %}
+ {% endcase %}
+ ]
+ }
+ </script>
+ {% endif %}
+ {% comment %}Inject @pixelunion/shopify-structured-data/structured-data-breadcrumbs end{% endcomment %}
+
+ {% comment %}Inject @pixelunion/shopify-structured-data/structured-data-product begin{% endcomment %}
+ {% comment %}
+ Product structured data
+ https://developers.google.com/search/docs/data-types/products
+ {% endcomment %}
+
+ {% if template contains 'product' %}
+ {% assign selected_variant = product.selected_or_first_available_variant | default: product.variants.first %}
+ {% assign product_image = selected_variant.featured_image | default: product.featured_image %}
+ {%- capture product_name -%}
+ {{ product.title }}
+ {%- if selected_variant.title != 'Default Title' and selected_variant.option1 == 'Default Title' -%}
+ - {{ selected_variant.title }}
+ {%- endif -%}
+ {%- endcapture -%}
+
+ {%- assign now = 'now' | date: '%Y-%m-%d' | split: '-' -%}
+ {% capture year_from_now %}{{ now[0] | plus: 1 }}-{{ now[1] }}-{{ now[2] | at_most: 28 }}{% endcapture %}
+
+ <script type="application/ld+json">
+ {
+ "@context": "http://schema.org/",
+ "@type": "Product",
+ "name": {{ product_name | strip_newlines | json }},
+ "image": {{ product_image | img_url: '1024x1024' | prepend: 'https:' | json }},
+ {% if product.description != blank %}
+ "description": {{ product.description | json }},
+ {% endif %}
+ {% if product.vendor %}
+ "brand": {
+ "@type": "Thing",
+ "name": {{ product.vendor | json }}
+ },
+ {% endif %}
+ {% if selected_variant.sku != blank %}
+ "sku": {{ selected_variant.sku | json }},
+ {% endif %}
+ {% if selected_variant.barcode != blank %}
+ "mpn": {{ selected_variant.barcode | json }},
+ {% endif %}
+ "offers": {
+ "@type": "Offer",
+ "priceCurrency": {{ cart.currency.iso_code | json }},
+ "price": {{ selected_variant.price | divided_by: 100.0 | json }},
+ "availability": "http://schema.org/{% if selected_variant.available %}InStock{% else %}OutOfStock{% endif %}",
+ "url": "{{ shop.url }}{{ selected_variant.url }}",
+ "seller": {
+ "@type": "Organization",
+ "name": {{ shop.name | json }}
+ },
+ "priceValidUntil": {{ year_from_now | json }}
+ }
+ }
+ </script>
+ {% endif %}
+ {% comment %}Inject @pixelunion/shopify-structured-data/structured-data-product end{% endcomment %}
+
+ {% comment %}Inject @pixelunion/shopify-structured-data/structured-data-website begin{% endcomment %}
+ {% comment %}
+ Store information
+ https://developers.google.com/search/docs/data-types/sitename
+ {% endcomment %}
+
+ <script type="application/ld+json">
+ {
+ "@context": "http://schema.org",
+ "@type": "WebSite",
+ "name": "{{ shop.name }}",
+ "url": "{{ shop.url }}"
+ }
+ </script>
+ {% comment %}Inject @pixelunion/shopify-structured-data/structured-data-website end{% endcomment %}
+
+ <form id="checkout_form" action="{{ routes.cart_url }}" method="POST" style="display: none;"></form>
+
+ <script>
+ (function () {
+ function handleFirstTab(e) {
+ if (e.keyCode === 9) { // the "I am a keyboard user" key
+ document.body.classList.add('user-is-tabbing');
+ window.removeEventListener('keydown', handleFirstTab);
+ }
+ }
+ window.addEventListener('keydown', handleFirstTab);
+ })();
+ </script>
+ <script>(function(n, v) {/* eslint-disable-next-line max-len */if (window.Shopify && window.Shopify.theme && navigator && navigator.sendBeacon && window.Shopify.designMode) {if (sessionStorage.getItem('oots_beacon')) return;navigator.sendBeacon('https://app.outofthesandbox.com/beacon', new URLSearchParams({shop_domain: window.Shopify.shop.toLowerCase(),shop_id: '{{ shop.id }}',shop_email: '{{ shop.email }}',theme_name: n.toLowerCase(),theme_version: v.toLowerCase(),theme_store_id: window.Shopify.theme.theme_store_id,theme_id: window.Shopify.theme.id,theme_role: window.Shopify.theme.role,}));sessionStorage.setItem('oots_beacon', '');}}('grid','7.1.0'))</script>
+
+<!--Start of Zendesk Chat Script-->
+<script async>
+window.$zopim||(function(d,s){var z=$zopim=function(c){z._.push(c)},$=z.s=
+d.createElement(s),e=d.getElementsByTagName(s)[0];z.set=function(o){z.set.
+_.push(o)};z._=[];z.set._=[];$.async=!0;$.setAttribute("charset","utf-8");
+$.src="https://v2.zopim.com/?RH5Yjru86SIJRwOxfiMAf2DTCgdROhhf";z.t=+new Date;$.
+type="text/javascript";e.parentNode.insertBefore($,e)})(document,"script");
+</script>
+<!--End of Zendesk Chat Script-->
+<!-- Statcounter code for DW - Started 3/5/19
+http://DesignerWallcoverings.com on Shopify -->
+<script type="text/javascript">
+var sc_project=11961678;
+var sc_invisible=1;
+var sc_security="9d9a53bd";
+var sc_https=1;
+</script>
+<script type="text/javascript"
+src="https://www.statcounter.com/counter/counter.js"
+async></script>
+<noscript><div class="statcounter"><a title="web statistics"
+href="https://statcounter.com/" target="_blank"><img
+class="statcounter"
+src="https://c.statcounter.com/11961678/0/9d9a53bd/1/"
+alt="web statistics"></a></div></noscript>
+<!-- End of Statcounter Code -->
+
+{% render 'hide-browse-hidden' %}
+
+<!-- DW: price restore band-aid removed 2026-06-11 — root cause (blank saw_variant_price) fixed in product-form-content.liquid; no price-hiding CSS exists. -->
+{%- comment -%} DW Shop-by-Color wheel {%- endcomment -%}
+<script>window.DW_CW_DATA="{{ 'dw-color-wheel-data.json' | asset_url }}";</script>
+<script src="{{ 'dw-color-wheel.js' | asset_url }}" defer></script>
+{%- comment -%} DW Phillip-Jeffries browse hide (stopgap) {%- endcomment -%}
+<script src="{{ 'dw-pj-hide.js' | asset_url }}" defer></script>
+{%- comment -%} DW card hover label: Pattern, Color + Vendor on hover (2026-06-22) {%- endcomment -%}
+<script src="{{ 'dw-card-hover.js' | asset_url }}" defer></script>
+
+<!-- DW min-qty start -->
+{% if template contains 'product' %}
+<script>
+(function () {
+ function minFromText(s) {
+ if (/sample/i.test(s)) return 1; // a sample is always a single unit
+ var m = String(s || '').match(/(\d+)\s*yd\s*min/i);
+ return m ? parseInt(m[1], 10) : null;
+ }
+ function qtyInput() {
+ return document.querySelector('.mm_quantity .input-text.qty, .mm_quantity input.qty, .input-text.qty');
+ }
+ // the Size selector = the single-option-selector whose selected label encodes a "yd min"
+ function sizeText() {
+ var sels = document.querySelectorAll('select.single-option-selector, select[name^="options"]');
+ for (var i = 0; i < sels.length; i++) {
+ var s = sels[i];
+ if (s.selectedIndex < 0 || !s.options[s.selectedIndex]) continue;
+ var t = s.options[s.selectedIndex].textContent;
+ if (/yd\s*min|wallcovering|sold\s*per\s*yard|sample/i.test(t)) return t;
+ }
+ return '';
+ }
+ function currentMin() { return minFromText(sizeText()) || 1; }
+
+ function clampUp(qi) {
+ if (qi && qi.getAttribute && qi.getAttribute('data-order-min')) return; // yield: custom.js data-order-* stepper owns MOQ qty
+ var min = parseInt(qi.getAttribute('min'), 10) || 1;
+ var v = parseInt(qi.value, 10);
+ if (isNaN(v) || v < min) { if (String(qi.value) !== String(min)) qi.value = min; }
+ }
+ function applyMin(forceValue) {
+ var qi = qtyInput();
+ if (!qi) return;
+ if (qi.getAttribute('data-order-min')) return; // yield: custom.js data-order-* stepper owns MOQ qty
+ var min = currentMin();
+ if (String(qi.getAttribute('min')) !== String(min)) qi.setAttribute('min', min);
+ if (qi.getAttribute('step') !== '1') qi.setAttribute('step', 1); // floor only; +1 increments above it
+ var cur = parseInt(qi.value, 10);
+ if (forceValue || isNaN(cur) || cur < min) {
+ if (String(qi.value) !== String(min)) { qi.value = min; qi.dispatchEvent(new Event('change', { bubbles: true })); }
+ } else { clampUp(qi); }
+ }
+
+ function wire() {
+ var qi = qtyInput();
+ if (qi && !qi.__minClamp) {
+ qi.__minClamp = true;
+ ['input', 'change', 'blur', 'keyup'].forEach(function (ev) { qi.addEventListener(ev, function () { clampUp(qi); }); });
+ }
+ // re-clamp after the ± buttons act
+ document.querySelectorAll('.mm_quantity .minus, .mm_quantity .plus').forEach(function (b) {
+ if (b.__minClamp) return; b.__minClamp = true;
+ b.addEventListener('click', function () { setTimeout(function () { clampUp(qtyInput() || {}); }, 20); });
+ });
+ // variant pickers -> jump to the new floor
+ document.querySelectorAll('select.single-option-selector, select[name^="options"], input[type="radio"][name*="ption"]').forEach(function (el) {
+ if (el.__minWired) return; el.__minWired = true;
+ el.addEventListener('change', function () { setTimeout(function () { applyMin(true); }, 40); });
+ });
+ applyMin(true);
+ }
+
+ function start() {
+ wire();
+ // the theme resets qty to 1 at ~1000ms — re-apply after that so the floor wins
+ [1100, 1600, 2500].forEach(function (t) { setTimeout(function () { applyMin(true); }, t); });
+ // the theme REBUILDS the qty widget on variant change (resetting min to 1); a light
+ // recurring re-assert keeps the floor correct without disrupting values at/above it
+ setInterval(function () { wire(); applyMin(false); }, 400);
+ }
+ if (document.readyState !== 'loading') start();
+ else document.addEventListener('DOMContentLoaded', start);
+ // re-wire if the form re-renders (debounced; keeps min synced, never forces value)
+ var d;
+ new MutationObserver(function () { clearTimeout(d); d = setTimeout(function () { wire(); applyMin(false); }, 150); })
+ .observe(document.documentElement, { subtree: true, childList: true });
+})();
+</script>
+{% endif %}
+<!-- DW min-qty end -->
+{% unless customer.tags contains 'trade' %}{% render 'dw-signin-modal' %}{% endunless %}
+{% comment %} Steve 2026-07-28: hover any product chip → show its SKU + product type (site-wide) {% endcomment %}
+{% render 'dw-hover-meta' %}
+{% render 'dw-tile-image-fix', ph: page.handle %}
+</body>
+</html>
+
diff --git a/sections/header.liquid b/sections/header.liquid
new file mode 100644
index 0000000..ea5bf13
--- /dev/null
+++ b/sections/header.liquid
@@ -0,0 +1,589 @@
+<style>
+ .main-header .header-content-right .customer-links{ display:inline-flex !important; align-items:center; position:relative; margin:0; }
+ .main-header .header-content-right .customer-links > .header-icon-link{ display:inline-flex; align-items:center; }
+ .dw-mobile-search{ display:none; }
+ /* Mobile header: logo row, full-width search row, then a clean icon row below; hamburger top-right */
+ @media(max-width:749px){
+ /* keep the phone number (aligned-left); only hide the now-empty account slot */
+ .main-header .header-tools .aligned-right{ display:none !important; }
+ .main-header .header-tools{ justify-content:center !important; }
+ .main-header .header-main-content{ display:flex !important; flex-wrap:wrap !important; align-items:center !important; justify-content:center !important; row-gap:14px !important; padding:14px !important; position:relative !important; }
+ .main-header .header-branding{ position:static !important; transform:none !important; left:auto !important; right:auto !important; top:auto !important; margin:0 auto !important; order:1 !important; flex:0 0 100% !important; width:100% !important; display:flex !important; justify-content:center !important; }
+ .dw-mobile-search{ display:flex !important; order:2 !important; flex:0 0 100% !important; width:100% !important; align-items:center; gap:9px; background:#f4f2ee; border:1px solid #e0dcd2; border-radius:999px; padding:11px 18px; }
+ .dw-mobile-search .dw-ms-icon{ display:inline-flex; flex:0 0 auto; }
+ .dw-mobile-search .dw-ms-icon svg{ width:16px; height:16px; }
+ .dw-mobile-search input{ border:0; background:transparent; outline:none; font:inherit; font-size:14px; width:100%; color:#26241f; }
+ .main-header .header-content-right{ order:3 !important; flex:0 0 100% !important; width:100% !important; display:flex !important; align-items:center !important; justify-content:space-around !important; position:static !important; }
+ .main-header .header-content-right > *{ position:static !important; margin:0 !important; top:auto !important; }
+ .main-header .header-content-right .header-quick-search{ display:none !important; }
+ .main-header .header-content-left{ order:4 !important; position:absolute !important; top:16px !important; right:16px !important; margin:0 !important; }
+ .main-header .header-content-left .navigation-toggle-open{ display:inline-flex !important; }
+ }
+</style>
+<script
+ type="application/json"
+ data-section-type="static-header"
+ data-section-id="{{ section.id }}"
+ data-section-data
+>
+ {
+ "stickyHeader": {{ section.settings.sticky_header }},
+ "compactCenter": "{{ section.settings.header_layout }}",
+ "enable_predictive_search": "{{ section.settings.enable_predictive_search }}"
+ }
+</script>
+
+{%- capture arrow_right -%}
+ {%-
+ render 'icons',
+ id: 'chevron-right'
+ -%}
+{%- endcapture -%}
+
+{% assign mega_nav_handle = section.settings.mega-nav-handle %}
+
+{%- capture header_classes -%}
+ header
+ header-layout-{{ section.settings.header_layout }}
+
+ {% if section.settings.header_full_width %}
+ header-full-width
+ {% else %}
+ header-content-width
+ {% endif %}
+
+ {% if section.settings.sticky_header and section.settings.sticky_header_logo %}
+ header-sticky-show-logo
+ {% endif %}
+
+ {% if section.settings.header_border and template != 'index' %}
+ header-border
+ {% endif %}
+{%- endcapture -%}
+
+<section
+ class="{{ header_classes | replace: ' ', ' ' | strip_newlines }}"
+ {% if section.settings.sticky_header %}data-sticky-header{% endif %}
+ {% if section.settings.header_layout == 'compact-center' %}data-header-compact-center{% endif %}
+ data-section-header
+>
+ <header
+ class="main-header"
+ role="banner"
+ data-header-main
+ >
+ <div class="header-tools-wrapper">
+ <div class="header-tools">
+
+ <div class="aligned-left">
+ <div id="coin-container"></div>
+ </div>
+
+ <div class="aligned-left">
+ {% assign customer_link_blocks = section.blocks | where: 'type', 'header_customer_link' %}
+ {% for block in customer_link_blocks %}
+ <div class="customer-links" {{ block.shopify_attributes }}>
+ <a href="{{ block.settings.link_url }}">{{ block.settings.link_text }}</a>
+ </div>
+ {% endfor %}
+ </div>
+
+ <div class="aligned-right"></div>
+
+ </div>
+ </div>
+
+ <div class="header-main-content" data-header-content>
+ {% unless section.settings.menu == blank %}
+ <div class="header-content-left">
+ <button
+ class="navigation-toggle navigation-toggle-open"
+ aria-label="{{ 'layout.header.menu' | t }}"
+ data-header-nav-toggle
+ >
+ <span class="navigation-toggle-icon">
+ {%-
+ render 'icons',
+ id: 'menu'
+ -%}
+ </span>
+ </button>
+ </div>
+ {% endunless %}
+
+ <div
+ class="
+ header-branding
+ header-branding-desktop
+ {% if section.settings.logo %}header-branding-desktop--has-logo{% endif %}
+ "
+ data-header-branding
+ >
+ <a class="logo-link" href="{{ routes.root_url }}">
+ {%- if section.settings.logo -%}
+ {%
+ render 'rimg',
+ img: section.settings.logo,
+ class: 'logo-image',
+ size: '200x100',
+ focal_point: section.settings.logo.presentation.focal_point,
+ %}
+ <span class="header-wordmark">Designer<br>Wallcoverings</span>
+ {%- else -%}
+ <h1>{{- shop.name -}}</h1>
+ {%- endif -%}
+ </a>
+ <span
+ class="navigation-toggle navigation-toggle-close"
+ data-header-nav-toggle
+ >
+ {%-
+ render 'icons',
+ id: 'close',
+ -%}
+ </span>
+ </div>
+
+ <form class="dw-mobile-search" action="{{ routes.search_url }}" method="get" role="search">
+ <span class="dw-ms-icon">{% render 'icons', id: 'search' %}</span>
+ <input type="search" name="q" placeholder="Search patterns, colors…" aria-label="{{ 'general.search.search' | t }}">
+ </form>
+
+ {% unless section.settings.menu == blank %}
+ <div class="navigation-wrapper" data-navigation-wrapper>
+ <nav class="navigation navigation-desktop navigation-has-mega-nav" data-navigation-content>
+ <ul class="navigation-menu">
+ {% for link in linklists[section.settings.menu].links %}
+ {% assign first_tier_link = link %}
+ {% assign uses_blocks = true %}
+ {% comment %}Inject is-dropdown-or-meganav begin{% endcomment %}
+ {% comment %}
+ A helper snippet for detecting if a link has a mega nav
+ or dropdown associated with it.
+
+ @param first_tier_link
+
+ @param uses_blocks
+ {% endcomment %}
+
+ {% assign is_dropdown = false %}
+ {% assign is_meganav = true %}
+
+ {% if first_tier_link.links == blank %}
+ {% assign is_meganav = false %}
+ {% else %}
+ {% assign is_dropdown = true %}
+ {% endif %}
+
+ {% for second_tier_link in first_tier_link.links %}
+ {% if second_tier_link.links == blank %}
+ {% assign is_meganav = false %}
+ {% else %}
+ {% assign is_dropdown = true %}
+ {% endif %}
+ {% endfor %}
+
+ {% if is_meganav %}
+ {% assign is_dropdown = false %}
+ {% endif %}
+
+ {% if uses_blocks %}
+ {% assign found_mega_item_handle = false %}
+ {% if section != blank and section.blocks != blank %}
+ {% for block in section.blocks %}
+ {% if block.type == 'mega_menu' %}
+ {% assign menu_item_handle = block.settings.menu_item | handle %}
+ {% if first_tier_link.handle == menu_item_handle %}
+ {% assign found_mega_item_handle = true %}
+ {% endif %}
+ {% endif %}
+ {% endfor %}
+ {% endif %}
+
+ {% if found_mega_item_handle %}
+ {% if is_dropdown %}
+ {% assign is_meganav = true %}
+ {% assign is_dropdown = false %}
+ {% endif %}
+ {% elsif found_mega_item_handle == false %}
+ {% if is_meganav %}
+ {% assign is_meganav = false %}
+ {% assign is_dropdown = true %}
+ {% endif %}
+ {% else %}
+ {% if is_meganav %}
+ {% assign is_meganav = false %}
+ {% assign is_dropdown = true %}
+ {% endif %}
+ {% endif %}
+ {% endif %}
+ {% comment %}Inject is-dropdown-or-meganav end{% endcomment %}
+
+
+ <li
+ class="{% if is_dropdown %}has-dropdown{% elsif is_meganav %}has-mega-nav{% endif %}"
+ {% if is_meganav %}data-mega-nav="true"{% endif %}
+ >
+ {% if is_dropdown or is_meganav %}
+ <details data-nav-details>
+ <summary data-href="{{ link.url }}"
+ {% else %}
+ <a href="{{ link.url }}"
+ {% endif %}
+ id="main-navigation-{{ link.handle }}"
+ class="navigation-menu-link"
+ {% if is_dropdown or is_meganav %}aria-haspopup{% endif %}
+ >
+ {{ link.title }}
+ {% if is_dropdown or is_meganav %}
+ <span
+ class="navigation-submenu-toggle"
+ tabIndex="0"
+ role="button"
+ aria-controls="navigation-{{ link.handle }}"
+ aria-expanded="false"
+ aria-label="{{ 'general.accessibility.toggle' | t }}"
+ data-subnav-toggle
+ >
+ {{- arrow_right -}}
+ </span>
+ {% endif %}
+ {% if is_dropdown or is_meganav %}
+ </summary>
+ {% else %}
+ </a>
+ {% endif %}
+
+ {% if is_dropdown %}
+ {% assign direction = 'right' %}
+ {% assign halfway = linklists[section.settings.menu].links.size | divided_by: 2 %}
+ {% if forloop.index0 > halfway %}
+ {% assign direction = 'left' %}
+ {% endif %}
+
+ {%- render 'dropdown', direction: direction, link: link -%}
+ </details>
+ {% elsif is_meganav %}
+ {%- render 'mega-nav', link: link -%}
+ {% endif %}
+ </li>
+ {% endfor %}
+
+ {% if shop.customer_accounts_enabled %}
+ {% if customer %}
+ <li class="mobile-link">
+ <a href="{{ routes.account_url }}">
+ {{ 'layout.header.my_account' | t }}
+ </a>
+ </li>
+ <li class="mobile-link">
+ {{ 'layout.header.logout' | t | customer_logout_link }}
+ </li>
+ {% else %}
+ <li class="mobile-link">
+ <a class="customer-login-link" href="{{ routes.account_login_url }}">{{ 'layout.header.account' | t }}</a>
+ </li>
+ {% endif %}
+ {% endif %}
+ </ul>
+ </nav>
+ {% render 'mobile-nav', arrow_right: arrow_right %}
+ </div>
+ {% endunless %}
+
+ <div class="header-content-right header-content-right--inline-search" data-header-content-right>
+ <div class="header-quick-search" data-quick-search>
+ <button
+ class="search-toggle header-icon-link"
+ type="button"
+ aria-label="{{ 'general.search.header' | t }}"
+ aria-expanded="false"
+ data-quick-search-toggle
+ >
+ {%
+ render 'icons',
+ id: 'search',
+ %}
+ </button>
+ {%
+ render 'search-form',
+ context: 'header',
+ %}
+ </div>
+
+ <a href="#" class="visual-search-clickable header-search-inline__visual" aria-controls="Visual Search">
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="30px" height="30px" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 20 20"><path d="M10 8a3 3 0 1 0 0 6a3 3 0 0 0 0-6zm8-3h-2.4a.888.888 0 0 1-.789-.57l-.621-1.861A.89.89 0 0 0 13.4 2H6.6c-.33 0-.686.256-.789.568L5.189 4.43A.889.889 0 0 1 4.4 5H2C.9 5 0 5.9 0 7v9c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm-8 11a5 5 0 0 1-5-5a5 5 0 1 1 10 0a5 5 0 0 1-5 5zm7.5-7.8a.7.7 0 1 1 0-1.4a.7.7 0 0 1 0 1.4z" fill="#000000"/></svg>
+ </a>
+
+ {% if shop.customer_accounts_enabled %}
+ <div class="customer-links">
+ {% if customer %}
+ <a href="{{ routes.account_url }}" class="header-icon-link" aria-label="{{ 'layout.header.my_account' | t }}" title="{{ 'layout.header.my_account' | t }}">{% render 'icons', id: 'person' %}</a>
+ <div class="customer-links-inner">
+ <span class="arrow"></span>
+ <ul>
+ <li><a href="{{ routes.account_url }}">{{ 'customers.general.purchases' | t }}</a></li>
+ <li><a href="{{ routes.account_addresses_url }}">{{ 'customers.addresses.header' | t }}</a></li>
+ <li>{{ 'layout.header.logout' | t | customer_logout_link }}</li>
+ </ul>
+ </div>
+ {% else %}
+ <a class="customer-login-link header-icon-link" href="{{ routes.account_login_url }}" data-dw-signin aria-label="{{ 'layout.header.account' | t }}" title="{{ 'layout.header.account' | t }}">{% render 'icons', id: 'person' %}</a>
+ {% endif %}
+ </div>
+ {% endif %}
+
+ <div class="mini-cart-wrapper">
+ <a class="cart-count header-icon-link" href="{{ routes.cart_url }}" data-cart-count aria-label="{{ 'layout.header.cart' | t }}" title="{{ 'layout.header.cart' | t }}">
+ <span class="cart-count-icon">{% render 'icons', id: 'cart' %}</span>
+ <span class="cart-count-number">{{ cart.item_count }}</span>
+ </a>
+
+ {% render 'mini-cart' %}
+ </div>
+ </div>
+
+ <div class="search-takeover" data-search-takeover>
+ <div class="search-takeover__wrapper">
+ {%
+ render 'search-form',
+ context: 'mobile',
+ %}
+
+ <button
+ class="search-takeover__close-button"
+ type="button"
+ aria-label="{{ 'general.search.close' | t }}"
+ data-search-takeover-close
+ >
+ {%
+ render 'icons',
+ id: 'close',
+ %}
+ </button>
+ </div>
+ </div>
+ </div>
+ </header>
+</section>
+
+<script>
+ (function () {
+ var wrap = document.querySelector('[data-section-header] [data-quick-search]');
+ if (!wrap) return;
+ var toggle = wrap.querySelector('[data-quick-search-toggle]');
+ if (!toggle) return;
+ function q() { return wrap.querySelector('.search-form__input'); }
+ function frm() { return wrap.querySelector('form'); }
+
+ /* ---- predictive dropdown (Shopify native /search/suggest.json) ---- */
+ var box = document.createElement('div');
+ box.className = 'hdr-suggest';
+ box.style.display = 'none';
+ document.body.appendChild(box);
+ var timer = null, lastQ = '';
+ function positionBox() {
+ var input = q(); if (!input) return;
+ var r = input.getBoundingClientRect();
+ box.style.left = Math.max(8, Math.min(r.left, window.innerWidth - 300)) + 'px';
+ box.style.top = (r.bottom + 6) + 'px';
+ box.style.width = Math.max(260, r.width) + 'px';
+ }
+ function hideBox() { box.style.display = 'none'; box.innerHTML = ''; }
+ function render(products, query) {
+ var safeQ = query.replace(/[<>]/g, '');
+ if (!products.length) {
+ box.innerHTML = '<div class="hdr-suggest__empty">No matches for “' + safeQ + '”</div>';
+ } else {
+ box.innerHTML = products.map(function (p) {
+ var img = p.image ? '<img src="' + p.image + '" alt="" loading="lazy">' : '<span class="hdr-suggest__noimg"></span>';
+ return '<a class="hdr-suggest__row" href="' + p.url + '">' + img +
+ '<span class="hdr-suggest__t">' + (p.title || '').replace(/[<>]/g, '') + '</span></a>';
+ }).join('') +
+ '<a class="hdr-suggest__all" href="/search?q=' + encodeURIComponent(query) + '">See all results →</a>';
+ }
+ positionBox();
+ box.style.display = 'block';
+ }
+ function fetchSuggest(query) {
+ var url = '/search/suggest.json?q=' + encodeURIComponent(query) +
+ '&resources[type]=product&resources[limit]=8&resources[options][unavailable_products]=last';
+ fetch(url, { headers: { 'Accept': 'application/json' } })
+ .then(function (r) { return r.json(); })
+ .then(function (d) {
+ if (query !== lastQ) return;
+ var prods = (((d.resources || {}).results || {}).products) || [];
+ render(prods.map(function (p) {
+ return { title: p.title, url: p.url, image: (p.featured_image && p.featured_image.url) || p.image || '' };
+ }), query);
+ }).catch(function () {});
+ }
+ function onInput() {
+ var input = q(); if (!input) return;
+ var val = input.value.trim(); lastQ = val;
+ clearTimeout(timer);
+ if (val.length < 2) { hideBox(); return; }
+ timer = setTimeout(function () { fetchSuggest(val); }, 160);
+ }
+ wrap.addEventListener('input', function (e) {
+ if (e.target && e.target.classList && e.target.classList.contains('search-form__input')) onInput();
+ });
+ window.addEventListener('resize', function () { if (box.style.display === 'block') positionBox(); });
+ window.addEventListener('scroll', function () { if (box.style.display === 'block') positionBox(); }, true);
+
+ function close() {
+ wrap.classList.remove('search-open');
+ toggle.setAttribute('aria-expanded', 'false');
+ hideBox();
+ }
+ toggle.addEventListener('click', function (e) {
+ e.preventDefault();
+ var input = q(), form = frm();
+ if (wrap.classList.contains('search-open')) {
+ if (input && input.value.trim() && form) { form.submit(); return; }
+ close();
+ return;
+ }
+ wrap.classList.add('search-open');
+ toggle.setAttribute('aria-expanded', 'true');
+ if (input) { setTimeout(function () { input.focus(); }, 60); }
+ });
+ document.addEventListener('keydown', function (e) { if (e.key === 'Escape') close(); });
+ document.addEventListener('click', function (e) { if (!wrap.contains(e.target) && !box.contains(e.target)) close(); });
+ })();
+</script>
+
+{% schema %}
+{
+ "name": "Header",
+ "settings": [
+ {
+ "type": "header",
+ "content": "Logo"
+ },
+ {
+ "type": "image_picker",
+ "id": "logo",
+ "label": "Logo image",
+ "info": "200px tall recommended"
+ },
+ {
+ "type": "header",
+ "content": "Header"
+ },
+ {
+ "type": "select",
+ "id": "header_layout",
+ "label": "Logo layout",
+ "info": "Logo layouts are only active on screens wider than 1080px",
+ "options": [
+ {
+ "value": "default",
+ "label": "Default"
+ },
+ {
+ "value": "compact-center",
+ "label": "Compact center"
+ },
+ {
+ "value": "compact-left",
+ "label": "Compact left"
+ }
+ ],
+ "default": "compact-left"
+ },
+ {
+ "type": "checkbox",
+ "id": "header_full_width",
+ "label": "Enable full width header ",
+ "default": false
+ },
+ {
+ "type": "checkbox",
+ "id": "header_border",
+ "label": "Show header border",
+ "default": true,
+ "info": "This will appear on all pages except the home page."
+ },
+ {
+ "type": "checkbox",
+ "id": "sticky_header",
+ "label": "Enable sticky header"
+ },
+ {
+ "type": "checkbox",
+ "id": "sticky_header_logo",
+ "default": true,
+ "label": "Show logo image in sticky header"
+ },
+ {
+ "type": "header",
+ "content": "Search behavior"
+ },
+ {
+ "type": "checkbox",
+ "id": "enable_predictive_search",
+ "label": "Enable predictive search",
+ "default": true
+ },
+ {
+ "type": "header",
+ "content": "Navigation"
+ },
+ {
+ "type": "link_list",
+ "id": "menu",
+ "label": "Menu",
+ "default": "main-menu"
+ },
+ {
+ "type": "header",
+ "content": "Mini Cart"
+ },
+ {
+ "type": "checkbox",
+ "id": "enable_checkout_lock_icon",
+ "label": "Show lock icon on checkout button in mini cart",
+ "default": false
+ }
+ ],
+ "blocks": [
+ {
+ "type": "mega_menu",
+ "name": "Mega menu",
+ "settings": [
+ {
+ "type": "text",
+ "id": "menu_item",
+ "label": "Menu item",
+ "info": "Enter menu item to apply a mega menu dropdown. [Learn more](https://support.pixelunion.net/hc/en-us/articles/360022052534-How-to-set-up-your-store-s-navigation)"
+ },
+ {
+ "type": "image_picker",
+ "id": "menu_image",
+ "label": "Featured image",
+ "info": "480 x 1000px recommended"
+ }
+ ]
+ },
+ {
+ "type": "header_customer_link",
+ "name": "Header customer link",
+ "settings": [
+ {
+ "type": "text",
+ "id": "link_text",
+ "label": "Link text",
+ "default": "Contact us: (888) 373-4564"
+ },
+ {
+ "type": "url",
+ "id": "link_url",
+ "label": "Link URL"
+ }
+ ]
+ }
+ ]
+}
+
+{% endschema %}
diff --git a/snippets/dw-signin-modal.liquid b/snippets/dw-signin-modal.liquid
new file mode 100644
index 0000000..2cb49dc
--- /dev/null
+++ b/snippets/dw-signin-modal.liquid
@@ -0,0 +1,175 @@
+{% comment %} DW sign-in popup — returning clients sign in first (passwordless, email-code); new visitors choose Retail (emailed code for 3 free samples) or Professional (moderated Apply for Trade). dw_trade flag consumed in templates/customers/account.liquid. {% endcomment %}
+<style>
+ .dwsm-overlay{position:fixed;inset:0;background:rgba(0,0,0,.55);z-index:99999;display:none;align-items:flex-start;justify-content:center;padding:6vh 16px;overflow-y:auto;font-family:Lora,serif;}
+ .dwsm-overlay.dwsm-open{display:flex;}
+ .dwsm-card{width:100%;max-width:460px;background:#fff;border:1px solid #e4e4e4;border-radius:4px;padding:40px 40px 40px;box-shadow:0 8px 44px rgba(0,0,0,.28);position:relative;}
+ .dwsm-close{position:absolute;top:12px;right:16px;background:none;border:none;font-size:28px;line-height:1;color:#999;cursor:pointer;}
+ .dwsm-close:hover{color:#000;}
+ .dwsm-offer{text-align:center;margin:0 0 20px;}
+ .dwsm-offer h2{font-weight:400;font-size:1.55rem;color:#000;margin:0 0 4px;letter-spacing:.02em;}
+ .dwsm-offer p{font-size:.86rem;color:#787878;margin:0;}
+ .dwsm-toggle{display:flex;gap:10px;margin:0 0 24px;}
+ .dwsm-opt{flex:1;text-align:center;border:1px solid #e4e4e4;border-radius:4px;padding:13px 8px;cursor:pointer;transition:all .15s ease;background:#fff;}
+ .dwsm-opt:hover{border-color:#b08212;}
+ .dwsm-opt.active{border-color:#b08212;background:#faf6ec;box-shadow:0 0 0 1px #b08212;}
+ .dwsm-opt .t{display:block;font-size:.8rem;text-transform:uppercase;letter-spacing:.06em;color:#444;margin-bottom:3px;}
+ .dwsm-opt .s{display:block;font-size:.92rem;color:#b08212;}
+ .dwsm-gbtn{display:flex;align-items:center;justify-content:center;gap:10px;width:100%;padding:12px 20px;background:#fff;border:1px solid #dadce0;border-radius:3px;cursor:pointer;font-family:Lora,serif;font-size:.92rem;color:#3c4043;margin-bottom:18px;}
+ .dwsm-gbtn:hover{background:#f7f8f8;}
+ .dwsm-div{display:flex;align-items:center;gap:14px;margin:0 0 18px;}
+ .dwsm-div span{font-size:.72rem;color:#999;text-transform:uppercase;letter-spacing:.1em;}
+ .dwsm-div i{flex:1;height:1px;background:#e4e4e4;}
+ .dwsm-field{margin-bottom:16px;}
+ .dwsm-field label{display:block;font-size:.76rem;text-transform:uppercase;letter-spacing:.03em;color:#444;margin-bottom:6px;}
+ .dwsm-field input{width:100%;padding:12px 14px;border:1px solid #e4e4e4;border-radius:3px;font-family:Lora,serif;font-size:.95rem;color:#444;box-sizing:border-box;}
+ .dwsm-field input:focus{outline:none;border-color:#b08212;box-shadow:0 0 0 1px #b08212;}
+ .dwsm-overlay input.dwsm-submit{width:100%;padding:14px;background:#000 !important;color:#fff !important;border:none !important;border-radius:3px;font-family:Lora,serif;font-size:.9rem;text-transform:uppercase;letter-spacing:.05em;cursor:pointer;}
+ .dwsm-overlay input.dwsm-submit:hover{background:#262626 !important;}
+ .dwsm-err{background:#fef2f2;border:1px solid #fca5a5;color:#991b1b;font-size:.85rem;padding:10px 14px;border-radius:3px;margin-bottom:16px;text-align:center;}
+ .dwsm-return{margin:0 0 8px;}
+ .dwsm-return h2{font-weight:400;font-size:1.55rem;color:#000;margin:0 0 14px;letter-spacing:.02em;text-align:center;}
+ .dwsm-return-cap{font-size:.82rem;color:#787878;margin:2px 0 0;text-align:center;}
+ .dwsm-newdiv{display:flex;align-items:center;gap:14px;margin:22px 0 20px;}
+ .dwsm-newdiv span{font-size:.72rem;color:#999;text-transform:uppercase;letter-spacing:.1em;white-space:nowrap;}
+ .dwsm-newdiv i{flex:1;height:1px;background:#e4e4e4;}
+ .dwsm-foot{text-align:center;margin-top:20px;padding-top:16px;border-top:1px solid #e4e4e4;font-size:.85rem;color:#787878;}
+ .dwsm-foot a{color:#b08212;text-decoration:none;}
+ .dwsm-foot a:hover{text-decoration:underline;}
+</style>
+
+<div class="dwsm-overlay" id="dw-signin" data-dwsm-overlay>
+ <div class="dwsm-card" role="dialog" aria-modal="true" aria-label="Sign in">
+ <button class="dwsm-close" type="button" data-dwsm-close aria-label="Close">×</button>
+
+ {%- comment -%} (0) RETURNING SIGN-IN — first and most prominent. Passwordless: email -> 6-digit code. {%- endcomment -%}
+ {%- unless customer -%}
+ <div class="dwsm-return">
+ <h2>Welcome back</h2>
+ <input type="button" class="dwsm-submit" data-dwsm-login="{{ routes.account_login_url }}" value="Sign In" style="margin-bottom:12px;">
+ <button type="button" class="dwsm-gbtn" data-dwsm-login="{{ routes.account_login_url }}">
+ <svg width="18" height="18" viewBox="0 0 18 18" aria-hidden="true"><path fill="#4285F4" d="M17.64 9.2c0-.64-.06-1.25-.16-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.72v2.26h2.92c1.7-1.57 2.68-3.88 2.68-6.62z"/><path fill="#34A853" d="M9 18c2.43 0 4.47-.8 5.96-2.18l-2.92-2.26c-.81.54-1.84.86-3.04.86-2.34 0-4.32-1.58-5.03-3.7H.96v2.33A9 9 0 0 0 9 18z"/><path fill="#FBBC05" d="M3.97 10.72a5.4 5.4 0 0 1 0-3.44V4.95H.96a9 9 0 0 0 0 8.1l3.01-2.33z"/><path fill="#EA4335" d="M9 3.58c1.32 0 2.5.45 3.44 1.35l2.58-2.58C13.47.9 11.43 0 9 0A9 9 0 0 0 .96 4.95l3.01 2.33C4.68 5.16 6.66 3.58 9 3.58z"/></svg>
+ Continue with Google
+ </button>
+ <p class="dwsm-return-cap">Returning customer? Just enter your email — no password needed.</p>
+ </div>
+
+ <div class="dwsm-newdiv"><i></i><span>New to Designer Wallcoverings?</span><i></i></div>
+
+ <div class="dwsm-offer">
+ <h2>Free Samples, On Us</h2>
+ <p>Sign in — we'll email you a code for 3 free samples.</p>
+ </div>
+
+ <div class="dwsm-toggle">
+ <div class="dwsm-opt active" data-dwsm-type="retail" role="button" tabindex="0">
+ <span class="t">Retail</span><span class="s">code for 3 free</span>
+ </div>
+ <div class="dwsm-opt" data-dwsm-type="professional" role="button" tabindex="0">
+ <span class="t">Professional</span><span class="s">apply for trade</span>
+ </div>
+ </div>
+
+ {%- comment -%} Google sign-up offered up front; deep-links to the hosted portal's native Google. {%- endcomment -%}
+ <div data-dwsm-google>
+ <button type="button" class="dwsm-gbtn" data-dwsm-login="{{ routes.account_login_url }}">
+ <svg width="18" height="18" viewBox="0 0 18 18" aria-hidden="true"><path fill="#4285F4" d="M17.64 9.2c0-.64-.06-1.25-.16-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.72v2.26h2.92c1.7-1.57 2.68-3.88 2.68-6.62z"/><path fill="#34A853" d="M9 18c2.43 0 4.47-.8 5.96-2.18l-2.92-2.26c-.81.54-1.84.86-3.04.86-2.34 0-4.32-1.58-5.03-3.7H.96v2.33A9 9 0 0 0 9 18z"/><path fill="#FBBC05" d="M3.97 10.72a5.4 5.4 0 0 1 0-3.44V4.95H.96a9 9 0 0 0 0 8.1l3.01-2.33z"/><path fill="#EA4335" d="M9 3.58c1.32 0 2.5.45 3.44 1.35l2.58-2.58C13.47.9 11.43 0 9 0A9 9 0 0 0 .96 4.95l3.01 2.33C4.68 5.16 6.66 3.58 9 3.58z"/></svg>
+ Continue with Google
+ </button>
+ <div class="dwsm-div"><i></i><span>or</span><i></i></div>
+ </div>
+
+ {%- endunless -%}
+ {%- if customer -%}
+ <div class="dwsm-return">
+ <h2>Apply for Trade Pricing</h2>
+ <p class="dwsm-return-cap">You're signed in — submit your business details and our team will review your trade account.</p>
+ </div>
+ {%- endif -%}
+ {%- comment -%} Moderated trade application — shown when "Professional" is selected. {%- endcomment -%}
+ <form class="dwsm-trade" data-dwsm-trade style="display:{% if customer %}block{% else %}none{% endif %};" novalidate>
+ <div class="dwsm-field">
+ <label>Business name</label>
+ <input type="text" name="business_name" autocomplete="organization" value="{{ customer.default_address.company }}" required>
+ </div>
+ <div class="dwsm-field">
+ <label>Work email</label>
+ <input type="email" name="email" autocomplete="email" value="{{ customer.email }}" required>
+ </div>
+ <div class="dwsm-field">
+ <label>Resale / business license #</label>
+ <input type="text" name="resale_cert">
+ </div>
+ <input type="button" class="dwsm-submit" data-dwsm-trade-submit value="Apply for Trade">
+ <p class="dwsm-trade-note" style="font-size:.78rem;color:#787878;margin:12px 0 0;text-align:center;">
+ Trade applications are reviewed by our team. We'll email you once approved.
+ </p>
+ </form>
+
+ {%- unless customer -%}
+ <div data-dwsm-retail>
+ <input type="button" class="dwsm-submit" data-dwsm-login="{{ routes.account_login_url }}" value="Sign In / Create Account">
+
+ <div class="dwsm-foot">
+ New to Designer Wallcoverings? <a href="{{ routes.account_register_url }}">Create account</a>
+ </div>
+ </div>
+ {%- endunless -%}
+ </div>
+</div>
+
+<script>
+(function(){
+ var overlay=document.getElementById('dw-signin');
+ if(!overlay) return;
+ var TRADE_APPLY_URL = 'https://signup.designerwallcoverings.com/trade/apply'; // fulfillment service public URL
+ function open(){overlay.classList.add('dwsm-open');document.body.style.overflow='hidden';}
+ function close(){overlay.classList.remove('dwsm-open');document.body.style.overflow='';}
+ function persistTrade(){
+ var proEl=overlay.querySelector('[data-dwsm-type="professional"]');
+ var pro=proEl&&proEl.classList.contains('active');
+ try{pro?sessionStorage.setItem('dw_trade','1'):sessionStorage.removeItem('dw_trade');}catch(e){}
+ }
+ document.addEventListener('click',function(e){
+ var t=e.target.closest('[data-dw-signin], a[href="#dw-signin"], a[href$="#dw-signin"]');
+ if(t){e.preventDefault();open();return;}
+ var login=e.target.closest('[data-dwsm-login]');
+ if(login){e.preventDefault();persistTrade();window.location.href=login.getAttribute('data-dwsm-login');return;}
+ if(e.target.closest('[data-dwsm-close]')||e.target===overlay){close();}
+ });
+ document.addEventListener('keydown',function(e){if(e.key==='Escape')close();});
+ var opts=overlay.querySelectorAll('[data-dwsm-type]');
+ var retailBox=overlay.querySelector('[data-dwsm-retail]');
+ var googleBox=overlay.querySelector('[data-dwsm-google]');
+ var tradeForm=overlay.querySelector('[data-dwsm-trade]');
+ function setType(type){
+ opts.forEach(function(o){o.classList.toggle('active',o.getAttribute('data-dwsm-type')===type);});
+ var pro=(type==='professional');
+ if(retailBox) retailBox.style.display=pro?'none':'';
+ if(googleBox) googleBox.style.display=pro?'none':'';
+ if(tradeForm) tradeForm.style.display=pro?'block':'none';
+ try{pro?sessionStorage.setItem('dw_trade','1'):sessionStorage.removeItem('dw_trade');}catch(e){}
+ }
+ // Moderated trade application submit -> POST /trade/apply on the fulfillment service.
+ overlay.addEventListener('click',function(e){
+ if(!e.target.closest('[data-dwsm-trade-submit]')) return;
+ e.preventDefault();
+ var f=tradeForm; if(!f) return;
+ var body={
+ business_name:(f.business_name.value||'').trim(),
+ email:(f.email.value||'').trim(),
+ resale_cert:(f.resale_cert.value||'').trim()
+ };
+ if(!body.email||!body.business_name){alert('Business name and work email are required.');return;}
+ fetch(TRADE_APPLY_URL,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(body)})
+ .then(function(r){return r.json();})
+ .then(function(){f.innerHTML='<p style="text-align:center;color:#444;padding:8px 0;">Thanks — your trade application is in review. We\'ll email you once it\'s approved.</p>';})
+ .catch(function(){alert('Sorry, something went wrong. Please try again.');});
+ });
+ opts.forEach(function(o){
+ o.addEventListener('click',function(){setType(o.getAttribute('data-dwsm-type'));});
+ o.addEventListener('keydown',function(e){if(e.key==='Enter'||e.key===' '){e.preventDefault();setType(o.getAttribute('data-dwsm-type'));}});
+ });
+ if(window.location.hash==='#dw-signin'){open();}
+})();
+</script>
+
diff --git a/snippets/mobile-nav.liquid b/snippets/mobile-nav.liquid
new file mode 100644
index 0000000..50a22c5
--- /dev/null
+++ b/snippets/mobile-nav.liquid
@@ -0,0 +1,135 @@
+<nav class="navigation navigation-mobile navigation-has-mega-nav" data-navigation-content>
+ <ul class="navigation-menu">
+ <li class="mobile-link mobile-link--utility mobile-link--primary">
+ <a href="/pages/custom">Custom Walls</a>
+ </li>
+ <li class="mobile-link mobile-link--utility mobile-link--primary">
+ <a href="/pages/trade-only-benefits">Apply for a Trade Account</a>
+ </li>
+ <li class="mobile-link mobile-nav-divider" aria-hidden="true"></li>
+
+ {% for link in linklists[section.settings.menu].links %}
+ {% assign first_tier_link = link %}
+ {% assign uses_blocks = true %}
+ {% comment %}Inject is-dropdown-or-meganav begin{% endcomment %}
+ {% comment %}
+ A helper snippet for detecting if a link has a mega nav
+ or dropdown associated with it.
+
+ @param first_tier_link
+
+ @param uses_blocks
+ {% endcomment %}
+
+ {% assign is_dropdown = false %}
+ {% assign is_meganav = true %}
+
+ {% if first_tier_link.links == blank %}
+ {% assign is_meganav = false %}
+ {% else %}
+ {% assign is_dropdown = true %}
+ {% endif %}
+
+ {% for second_tier_link in first_tier_link.links %}
+ {% if second_tier_link.links == blank %}
+ {% assign is_meganav = false %}
+ {% else %}
+ {% assign is_dropdown = true %}
+ {% endif %}
+ {% endfor %}
+
+ {% if is_meganav %}
+ {% assign is_dropdown = false %}
+ {% endif %}
+
+ {% if uses_blocks %}
+ {% assign found_mega_item_handle = false %}
+ {% if section != blank and section.blocks != blank %}
+ {% for block in section.blocks %}
+ {% if block.type == 'mega_menu' %}
+ {% assign menu_item_handle = block.settings.menu_item | handle %}
+ {% if first_tier_link.handle == menu_item_handle %}
+ {% assign found_mega_item_handle = true %}
+ {% endif %}
+ {% endif %}
+ {% endfor %}
+ {% endif %}
+
+ {% if found_mega_item_handle %}
+ {% if is_dropdown %}
+ {% assign is_meganav = true %}
+ {% assign is_dropdown = false %}
+ {% endif %}
+ {% elsif found_mega_item_handle == false %}
+ {% if is_meganav %}
+ {% assign is_meganav = false %}
+ {% assign is_dropdown = true %}
+ {% endif %}
+ {% else %}
+ {% if is_meganav %}
+ {% assign is_meganav = false %}
+ {% assign is_dropdown = true %}
+ {% endif %}
+ {% endif %}
+ {% endif %}
+ {% comment %}Inject is-dropdown-or-meganav end{% endcomment %}
+
+
+ <li
+ class="{% if is_dropdown %}has-dropdown{% elsif is_meganav %}has-mega-nav{% endif %}"
+ {% if is_meganav %}data-mega-nav="true"{% endif %}
+ >
+ <a
+ id="mobile-navigation-{{ link.handle }}"
+ class="navigation-menu-link"
+ href="{{ link.url }}"
+ {% if is_dropdown or is_meganav %}aria-haspopup{% endif %}
+ >
+ {{ link.title }}
+ {% if is_dropdown or is_meganav %}
+ <span
+ class="navigation-submenu-toggle"
+ tabIndex="0"
+ role="button"
+ aria-controls="navigation-{{ link.handle }}"
+ aria-expanded="false"
+ aria-label="{{ 'general.accessibility.toggle' | t }}"
+ data-subnav-toggle
+ >
+ {{- arrow_right -}}
+ </span>
+ {% endif %}
+ </a>
+
+ {% if is_dropdown %}
+ {% assign direction = 'right' %}
+ {% assign halfway = linklists[section.settings.menu].links.size | divided_by: 2 %}
+ {% if forloop.index0 > halfway %}
+ {% assign direction = 'left' %}
+ {% endif %}
+
+ {%- render 'mobile-dropdown', direction: direction, link: link -%}
+ {% elsif is_meganav %}
+ {%- render 'mega-nav', link: link -%}
+ {% endif %}
+ </li>
+ {% endfor %}
+
+ {% if shop.customer_accounts_enabled %}
+ {% if customer %}
+ <li class="mobile-link">
+ <a href="{{ routes.account_url }}">
+ {{ 'layout.header.my_account' | t }}
+ </a>
+ </li>
+ <li class="mobile-link">
+ {{ 'layout.header.logout' | t | customer_logout_link }}
+ </li>
+ {% else %}
+ <li class="mobile-link">
+ <a class="customer-login-link" href="{{ routes.account_login_url }}">{{ 'layout.header.account' | t }}</a>
+ </li>
+ {% endif %}
+ {% endif %}
+ </ul>
+</nav>
diff --git a/templates/customers/account.liquid b/templates/customers/account.liquid
new file mode 100644
index 0000000..5efd1aa
--- /dev/null
+++ b/templates/customers/account.liquid
@@ -0,0 +1,95 @@
+<script>
+ /* Route trade-professional signups to the benefits page after account creation. */
+ (function () {
+ try {
+ if (sessionStorage.getItem('dw_trade')) {
+ sessionStorage.removeItem('dw_trade');
+ window.location.replace('/pages/trade-only-benefits');
+ }
+ } catch (e) {}
+ })();
+</script>
+<div class="customer-section">
+ <h1 class="page-title">
+ {% if customer.first_name != blank %}
+ {{ 'customers.account.header' | t: customer_name: customer.first_name }}
+ {% else %}
+ {{ 'general.breadcrumbs.account' | t }}
+ {% endif %}
+ </h1>
+
+ {% render 'breadcrumbs' %}
+
+ {%- unless customer.tags contains 'trade' -%}
+ <p class="dw-trade-cta" style="margin:16px 0;">
+ <a href="#dw-signin" data-dw-signin style="color:#b08212;font-weight:600;text-decoration:none;">Apply for Trade Pricing →</a>
+ </p>
+ {%- endunless -%}
+
+ <div class="customer-wrapper">
+ <div class="account-info">
+
+ {% if customer.default_address != nil %}
+ <p class="customer-address">
+ {% assign address = customer.default_address %}
+ <span class="section-title">{{ address.first_name }} {{ address.last_name }}</span>
+ {% if address.company != blank %}
+ <span>{{ address.company }}</span><br>
+ {% endif %}
+ {% if address.street != blank %}
+ <span>{{ address.street }}</span><br>
+ {% endif %}
+ {% if address.city != blank or address.province_code != blank %}
+ <span>{{ address.city }}{% if address.province_code %}, {{ address.province_code }}{% endif %}</span><br>
+ {% endif %}
+ {% if address.country != blank or address.zip != blank %}
+ <span>{{ address.country }} {{ address.zip }}</span><br>
+ {% endif %}
+ {% if address.phone != blank %}
+ <span>{{ address.phone }}</span><br>
+ {% endif %}
+ </p>
+ {% endif %}
+
+ {% if customer.addresses_count == 0 %}
+ {% capture newAddressLink %}
+ <a href="{{ routes.account_addresses_url }}">{{ 'customers.account.new_address_link' | t }}</a>
+ {% endcapture %}
+ <p>{{ 'customers.account.no_addresses_html' | t: new_address_link: newAddressLink }}</p>
+ {% else %}
+ <p><a href="{{ routes.account_addresses_url }}">{{ 'customers.account.edit_addresses' | t }}</a></p>
+ {% endif %}
+
+ </div>
+
+ <div class="account-history">
+
+ {% if customer.orders.size > 0 %}
+ <table class="account-orders">
+ <thead>
+ <tr>
+ <th class="first">{{ 'customers.account.order' | t }}</th>
+ <th>{{ 'customers.account.payment' | t }}</th>
+ <th>{{ 'customers.account.fulfillment' | t }}</th>
+ <th class="last">{{ 'general.general.total' | t }}</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {% for order in customer.orders %}
+ <tr class="{% render 'for-looper', forloop: forloop %} {% if order.cancelled %}cancelled_order{% endif %}">
+ <td class="account-order-number first" data-title="{{ 'customers.account.order' | t }}">{{ order.name | link_to: order.customer_url }} <span class="date">- {{ order.created_at | date: format: 'short_month' }}</span></td>
+ <td class="account-order-payment-status {{ order.financial_status }}" data-title="{{ 'customers.account.payment' | t }}">{{ order.financial_status_label | capitalize }}</td>
+ <td class="account-order-fulfillment-status {{ order.fulfillment_status }}" data-title="{{ 'customers.account.fulfillment' | t }}">{{ order.fulfillment_status_label | capitalize }}</td>
+ <td class="account-order-total last" data-title="{{ 'general.general.total' | t }}"><span class="money">{{ order.total_price | money }}</span></td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ {% else %}
+ <p class="empty">{{ 'customers.account.empty' | t }}</p>
+ {% endif %}
+ </div>
+ </div>
+</div>
+
diff --git a/templates/customers/register.liquid b/templates/customers/register.liquid
new file mode 100644
index 0000000..6288949
--- /dev/null
+++ b/templates/customers/register.liquid
@@ -0,0 +1,77 @@
+<div class="customer-section">
+ <h1 class="page-title">{{ 'customers.register.header' | t }}</h1>
+
+ {% render 'breadcrumbs' %}
+
+ <div class="customer-wrapper">
+
+ {% form 'create_customer', class: 'customer-register' %}
+
+ {% if form.errors %}
+ {{ form.errors | default_errors }}
+ {% endif %}
+
+ {% if form.posted_successfully? %}
+ <script>
+ try {
+ if (sessionStorage.getItem('dw_trade')) {
+ sessionStorage.removeItem('dw_trade');
+ window.location.replace('/pages/trade-only-benefits');
+ }
+ } catch (e) {}
+ </script>
+ {% endif %}
+
+ <div class="input-wrapper">
+ <label class="label" for="customer[first_name]">{{ 'customers.general.first_name' | t }}</label>
+ <input type="text" placeholder="" value="{{ form.first_name }}" name="customer[first_name]" class="{% if form.errors contains "first_name" %}error input{% else %}input{% endif %}">
+ </div>
+
+ <div class="input-wrapper">
+ <label class="label" for="customer[last_name]">{{ 'customers.general.last_name' | t }}</label>
+ <input type="text" placeholder="" value="{{ form.last_name }}" name="customer[last_name]" class="{% if form.errors contains "last_name" %}error input{% else %}input{% endif %}">
+ </div>
+
+ <div class="input-wrapper">
+ <label class="label" for="customer[email]">{{ 'general.general.email' | t }}</label>
+ <input type="text" placeholder="{{ 'general.general.email_placeholder' | t }}" value="{{ form.email }}" name="customer[email]" class="{% if form.errors contains "email" %}error{% endif %} input">
+ </div>
+
+ <div class="input-wrapper">
+ <label class="label" for="customer[password]">{{ 'general.general.password' | t }}</label>
+ <input type="password" class="input" placeholder="" value="" name="customer[password]">
+ </div>
+
+ <div class="input-wrapper dw-professional-wrapper" style="display:flex;align-items:flex-start;gap:10px;margin:6px 0 14px;">
+ <input type="checkbox" id="dw-professional" name="dw_professional" value="1" style="width:18px;height:18px;margin-top:2px;flex-shrink:0;cursor:pointer;">
+ <label for="dw-professional" style="cursor:pointer;font-size:14px;line-height:1.4;">
+ I'm a trade professional (designer, architect, or industry pro) — unlock up to <strong>10 free samples</strong>. Retail customers receive 3.
+ </label>
+ </div>
+
+ <div class="input-wrapper">
+ <input type="submit" class="input" value="{{ 'customers.register.submit' | t }}">
+ </div>
+
+ <div class="or-separator">
+ <span class="or-text">OR</span>
+ </div>
+
+ {% endform %}
+ </div>
+</div>
+
+<script>
+ (function () {
+ var form = document.querySelector('form.customer-register');
+ var cb = document.getElementById('dw-professional');
+ if (!form || !cb) return;
+ form.addEventListener('submit', function () {
+ try {
+ if (cb.checked) { sessionStorage.setItem('dw_trade', '1'); }
+ else { sessionStorage.removeItem('dw_trade'); }
+ } catch (e) {}
+ });
+ })();
+</script>
+
(oldest)
·
back to Dw Theme Live Signin Split
·
Split top-banner sign-in: Trade Sign In -> /pages/trade-only 00fb8b8 →