[object Object]

← back to Wallpapercanada

sort-skill UI: add Light→Dark / Dark→Light / Color Wheel options

58615c38d88c271cbf0f22c6338ea05fc0998eae · 2026-05-10 12:44:10 -0700 · Steve

Files touched

Diff

commit 58615c38d88c271cbf0f22c6338ea05fc0998eae
Author: Steve <steve@designerwallcoverings.com>
Date:   Sun May 10 12:44:10 2026 -0700

    sort-skill UI: add Light→Dark / Dark→Light / Color Wheel options
---
 public/index.html | 302 +++++++++++++++++++++++-------------------------------
 1 file changed, 129 insertions(+), 173 deletions(-)

diff --git a/public/index.html b/public/index.html
index 5dbc6db..e63340b 100644
--- a/public/index.html
+++ b/public/index.html
@@ -179,163 +179,36 @@ textarea:focus-visible,
 <style id="ns-header-modal-styles">
         .ns-header { position: sticky; top: 0; z-index: 100; display: flex; align-items: center; justify-content: space-between; padding: 18px 36px; background: rgba(10,10,10,0.92) !important; backdrop-filter: blur(8px); border-bottom: 1px solid rgba(245,241,232,0.06); }
         .ns-brand { display: inline-flex; align-items: center; gap: 14px; text-decoration: none; }
-        .ns-dot { width: 28px; height: 28px; border-radius: 50%; background: radial-gradient(circle at 35% 35%, #a98b5b 0%, #5d4c32 60%, #332a1b 100%); box-shadow: 0 0 0 1px rgba(245,241,232,0.10), 0 2px 12px rgba(180,90,60,0.30); flex-shrink: 0; }
+        .ns-dot { width: 28px; height: 28px; border-radius: 50%; background: var(--ns-dot-bg, radial-gradient(circle at 35% 35%, #b66a4d 0%, #8a4a30 60%, #5a2d1c 100%)); box-shadow: 0 0 0 1px rgba(245,241,232,0.10), 0 2px 12px rgba(180,90,60,0.30); flex-shrink: 0; }
         .ns-name { font-family: -apple-system, "SF Pro Display", "Helvetica Neue", system-ui, sans-serif; font-size: 18px !important; font-weight: 300 !important; letter-spacing: 0.02em !important; color: #f5f1e8 !important; text-transform: none !important; margin: 0 !important; }
         .ns-name sup { font-size: 0.55em; font-weight: 300; margin-left: 1px; }
-        .ns-nav { display: flex; gap: 32px; align-items: center; list-style: none; padding: 0; margin: 0; }
-        .ns-nav a, .ns-nav button { font-family: -apple-system, "SF Pro Text", system-ui, sans-serif; font-size: 15px !important; font-weight: 400 !important; color: #f5f1e8 !important; text-decoration: none !important; background: none !important; border: 0 !important; cursor: pointer; padding: 0 !important; transition: color 200ms; letter-spacing: 0 !important; text-transform: none !important; }
+        .ns-nav a, .ns-nav button { font-family: -apple-system, "SF Pro Text", system-ui, sans-serif; font-size: 15px !important; font-weight: 400 !important; color: #f5f1e8 !important; text-decoration: none !important; background: none !important; border: 0 !important; cursor: pointer; transition: color 200ms; letter-spacing: 0 !important; text-transform: none !important; }
         .ns-nav a:hover, .ns-nav button:hover { color: #ffffff !important; }
-        @media (max-width: 820px) { .ns-header { padding: 14px 18px; } .ns-nav { gap: 16px; } .ns-nav a, .ns-nav button { font-size: 13px !important; } }
-        @media (max-width: 760px) {
-          .ns-header { flex-wrap: wrap; }
-          .ns-nav { display: none !important; flex-basis: 100%; flex-direction: column; align-items: flex-start; gap: 6px; padding: 14px 0 4px; }
-          .ns-nav.open { display: flex !important; }
-          .ns-nav a, .ns-nav button { padding: 10px 0 !important; border-bottom: 1px solid rgba(245,241,232,0.08); width: 100%; text-align: left; }
-          .ns-nav a:nth-child(n+5), .ns-nav button:nth-child(n+5) { display: block !important; }
-          .ns-header .mobile-toggle { display: flex !important; }
+        /* All widths: hide nav by default, hamburger always visible on right, nav opens as right-anchored dropdown panel */
+        .ns-nav {
+            display: none !important;
+            position: absolute; top: 100%; right: 18px;
+            flex-direction: column; align-items: stretch; gap: 0;
+            background: rgba(10,10,10,0.96); backdrop-filter: blur(10px);
+            border: 1px solid rgba(245,241,232,0.10); border-top: 0;
+            min-width: 220px; padding: 10px 0; margin: 0;
+            box-shadow: 0 16px 40px rgba(0,0,0,0.55);
+            z-index: 150;
         }
-        @media (min-width: 761px) {
-          .ns-header .mobile-toggle { display: none !important; }
+        .ns-nav.open { display: flex !important; }
+        .ns-nav a, .ns-nav button {
+            padding: 12px 22px !important;
+            border-bottom: 1px solid rgba(245,241,232,0.06);
+            width: 100%; text-align: left;
         }
-        .ns-modal { display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.78); z-index: 200; align-items: center; justify-content: center; padding: 24px; backdrop-filter: blur(6px); }
-        .ns-modal.show { display: flex; }
-        .ns-modal-card { max-width: 460px; width: 100%; background: #141414 !important; border: 1px solid rgba(245,241,232,0.14); border-radius: 6px; padding: 28px 30px 30px; position: relative; }
-        .ns-modal-card .close-x { position: absolute; top: 12px; right: 14px; width: 30px; height: 30px; background: none; border: 1px solid rgba(245,241,232,0.18); color: rgba(245,241,232,0.6) !important; border-radius: 50%; cursor: pointer; font-size: 14px; display: flex; align-items: center; justify-content: center; }
-        .ns-modal-card .close-x:hover { color: #ffffff !important; border-color: #ffffff; }
-        .ns-modal-card h3 { font-family: -apple-system, "SF Pro Display", system-ui; font-weight: 300 !important; font-size: 22px !important; margin: 0 0 6px !important; color: #f5f1e8 !important; }
-        .ns-modal-card .sub { color: rgba(245,241,232,0.65) !important; font-size: 13px; margin: 0 0 22px; }
-        .ns-actions { display: flex; flex-direction: column; gap: 10px; }
-        .ns-action { display: flex; align-items: center; gap: 14px; padding: 14px 16px; background: rgba(245,241,232,0.04) !important; border: 1px solid rgba(245,241,232,0.12) !important; color: #f5f1e8 !important; text-decoration: none !important; cursor: pointer; transition: all 200ms; font: inherit; text-align: left; }
-        .ns-action:hover { background: rgba(245,241,232,0.08) !important; border-color: #d4b683 !important; }
-        .ns-action .ico { width: 32px; height: 32px; border-radius: 50%; background: rgba(212,182,131,0.12); display: flex; align-items: center; justify-content: center; font-size: 15px; flex-shrink: 0; }
-        .ns-action .txt { flex: 1; }
-        .ns-action .txt b { display: block; font-weight: 500; font-size: 14px; color: #f5f1e8 !important; }
-        .ns-action .txt span { font-size: 12px; color: rgba(245,241,232,0.55) !important; }
-
-        /* ─── FINAL CONTRAST PASS — kill remaining gold-solid + white-island defects ─── */
-        /* Replace all gold-fill accents with off-white (Gucci-aesthetic, no DW gold solids) */
-        .new-badge, .new-arrivals-pill,
-        .color-filter-btn.active,
-        .drapery-btn, .sample-btn-chip, .cb-cta {
-          background: #f5f1e8 !important;
-          color: #0a0a0a !important;
-          border-color: #f5f1e8 !important;
-        }
-        .new-badge:hover, .new-arrivals-pill:hover,
-        .color-filter-btn.active:hover,
-        .drapery-btn:hover, .sample-btn-chip:hover, .cb-cta:hover {
-          background: #fff !important;
-          color: #0a0a0a !important;
-        }
-        /* Gold accents stay only as edge color (links, glyphs) — not fills */
-        a { color: #d4b683; }
-        a:hover { color: #f5d97a; }
-        /* Authorized-dealer footer line — small caps tracked, muted ink, no gold pill */
-        .authorized, .authorized-dealer p {
-          background: transparent !important;
-          color: rgba(245,241,232,0.5) !important;
-          font-size: 10px !important;
-          letter-spacing: 0.22em !important;
-          text-transform: uppercase !important;
-          padding: 0 !important;
-          border: none !important;
-          margin-top: 14px !important;
-        }
-        /* Kill any straggler white bg in info-card / sample-related cards */
-        .info-card, .info-card-link, .care-highlight, .feature-card, .spec-item {
-          background-color: rgba(245,241,232,0.04) !important;
-          border-color: rgba(245,241,232,0.12) !important;
-        }
-        /* Ensure modal content stays readable — Steve's earlier sweep made it #141414 with white text */
-        .modal-content { background: #141414 !important; color: #f5f1e8 !important; }
-        .modal-content * { color: #f5f1e8 !important; }
-        .modal-content input, .modal-content textarea, .modal-content select {
-          background: rgba(245,241,232,0.05) !important;
-          color: #f5f1e8 !important;
-          border-color: rgba(245,241,232,0.2) !important;
-        }
-        .modal-content label { color: rgba(245,241,232,0.6) !important; }
-        /* Force the wide-tracked NOVASUEDE wordmark to stay white */
-        .ns-wordmark, .ns-wordmark sup { color: #f5f1e8 !important; }
-
-        /* ─── Modal-internal contrast (post-QA defects) ─── */
-        /* Backdrop covers full viewport */
-        .modal { width: 100vw !important; height: 100vh !important; left: 0 !important; top: 0 !important; background: rgba(0, 0, 0, 0.78) !important; backdrop-filter: blur(6px); }
-        /* Chip — flip from white-on-white island to dark card */
-        .request-chip {
-          background: rgba(245, 241, 232, 0.06) !important;
-          color: #f5f1e8 !important;
-          border: 1px solid rgba(245, 241, 232, 0.18) !important;
-          border-radius: 4px !important;
-        }
-        .request-chip * { color: #f5f1e8 !important; }
-        .request-chip .chip-swatch {
-          /* swatch dot ALWAYS displays the inline-style hex from JS — fight any sweep */
-          border: 1px solid rgba(0, 0, 0, 0.4) !important;
-        }
-        /* + Add to request — hairline white-border on transparent (no gold) */
-        .add-to-request-btn {
-          background: transparent !important;
-          color: #f5f1e8 !important;
-          border: 1px solid rgba(245, 241, 232, 0.6) !important;
-          border-radius: 0 !important;
-          padding: 12px 22px !important;
-          font-size: 11px !important;
-          letter-spacing: 0.32em !important;
-          text-transform: uppercase !important;
-          font-weight: 400 !important;
-        }
-        .add-to-request-btn:hover {
-          background: #f5f1e8 !important;
-          color: #0a0a0a !important;
-          border-color: #f5f1e8 !important;
-        }
-        /* Hex caption visible */
-        .preview-hex, #colorPreviewHex {
-          display: block !important;
-          color: rgba(245, 241, 232, 0.55) !important;
-          font-family: ui-monospace, "SF Mono", Menlo, monospace !important;
-          font-size: 11px !important;
-          margin-top: 4px !important;
-          letter-spacing: 0.04em !important;
-          text-transform: lowercase !important;
-        }
-        /* Color preview name — stays single, prominent */
-        #colorPreviewName {
-          color: #f5f1e8 !important;
-          font-size: 11px !important;
-          letter-spacing: 0.32em !important;
-          text-transform: uppercase !important;
-          font-weight: 500 !important;
-          display: block !important;
-          margin-top: 12px !important;
-        }
-
-        /* ─── Mobile hamburger nav (replaces the overflow at <760px) ─── */
-        @media (max-width: 760px) {
-          header .nav-container { flex-wrap: wrap; }
-          header nav { display: none; flex-basis: 100%; flex-direction: column; gap: 6px; padding: 16px 0 6px; }
-          header nav.open { display: flex; }
-          header nav a { padding: 10px 0; border-bottom: 1px solid rgba(245,241,232,0.1); }
-          header .mobile-toggle {
-            display: flex !important;
-            flex-direction: column;
-            gap: 5px;
-            background: transparent;
-            border: 0;
-            cursor: pointer;
-            padding: 8px;
-          }
-          header .mobile-toggle span {
-            width: 22px; height: 1.5px;
-            background: #f5f1e8;
-            display: block;
-          }
-        }
-        @media (min-width: 761px) {
-          header .mobile-toggle { display: none !important; }
-        }
-
+        .ns-nav a:last-child, .ns-nav button:last-child { border-bottom: 0; }
+        .ns-nav a:hover, .ns-nav button:hover { background: rgba(245,241,232,0.06) !important; color: #ffffff !important; }
+        @media (max-width: 480px) { .ns-nav { right: 12px; min-width: 200px; } }
+        .ns-header .mobile-toggle { display: flex !important; align-items: center; justify-content: center; width: 36px; height: 36px; background: transparent; border: 0; cursor: pointer; padding: 0; gap: 4px; flex-direction: column; }
+        .ns-header .mobile-toggle span { display: block; width: 22px; height: 1.5px; background: #f5f1e8; transition: transform 200ms, opacity 200ms; }
+        .ns-header .mobile-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
+        .ns-header .mobile-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
+        .ns-header .mobile-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }
     </style>
 <style id="ns-gold-kill">
     /* novasuede: kill gold-solid fills, off-white instead. Edge color stays gold. */
@@ -356,17 +229,30 @@ textarea:focus-visible,
 <header class="ns-header">
         <a href="/" class="ns-brand" aria-label="Home">
             <span class="ns-dot"></span>
-            <span class="ns-name">Wallpaper Canada</span>
+            <svg class="ca-leaf" viewBox="0 0 24 24" width="18" height="18" aria-hidden="true" style="margin-right:2px;flex-shrink:0">
+              <path fill="#C8102E" d="M12 2 13.2 6.7 17 5l-1 4 5-1-3.5 3.6 5.5 2.9-6.5 1L17 19l-4.2-1.6L12 22l-.8-4.6L7 19l.5-3.5-6.5-1L6.5 11.5 3 7.9 8 8.9 7 5l3.8 1.7L12 2Z"/>
+            </svg>
+            <span class="ns-name" data-i18n="brand">Wallpaper Canada</span>
         </a>
         <nav class="ns-nav" id="nsPrimaryNav" aria-label="Primary">
-            <a href="/">Home</a>
-            <a href="/about">About</a>
-            <button type="button" onclick="nsContactOpen()">Contact</button>
+            <a href="/" data-i18n="home">Home</a>
+            <a href="/about" data-i18n="about">About</a>
+            <button type="button" onclick="nsContactOpen()" data-i18n="contact">Contact</button>
+            <button type="button" id="langToggle" class="lang-toggle" aria-label="Toggle language" onclick="wcToggleLang()"><span class="lang-en">EN</span> <span class="lang-sep">|</span> <span class="lang-fr">FR</span></button>
         </nav>
         <button type="button" class="mobile-toggle" aria-label="Toggle menu" aria-controls="nsPrimaryNav" aria-expanded="false" onclick="nsToggleNav(this)">
             <span></span><span></span><span></span>
         </button>
     </header>
+    <style>
+      .ns-brand { display:flex; align-items:center; gap:10px }
+      .lang-toggle { background:transparent !important; border:1px solid rgba(245,241,232,0.25) !important; padding:4px 10px !important; font-size:10px !important; letter-spacing:0.18em !important; color:#f5f1e8 !important; cursor:pointer; font-weight:600 !important; }
+      .lang-toggle:hover { border-color:#C8102E !important }
+      .lang-toggle .lang-sep { opacity:0.4; margin:0 2px }
+      .lang-toggle.lang-fr-on .lang-en { opacity:0.4 }
+      .lang-toggle:not(.lang-fr-on) .lang-fr { opacity:0.4 }
+      @media (max-width:760px) { .lang-toggle { margin-top:6px } }
+    </style>
 
 <div class="ns-modal" id="nsContactModal" role="dialog" aria-modal="true" aria-labelledby="nsContactTitle" onclick="if(event.target===this)nsContactClose()">
         <div class="ns-modal-card">
@@ -376,7 +262,7 @@ textarea:focus-visible,
             <div class="ns-actions">
                 <a class="ns-action" href="#contact" onclick="nsContactClose()"><span class="ico">📋</span><div class="txt"><b>Get a Quote</b><span>Project specs → priced estimate</span></div></a>
                 <a class="ns-action" href="#contact" onclick="nsContactClose();openModal();"><span class="ico">📦</span><div class="txt"><b>Order a Sample</b><span>Free swatch to your shop</span></div></a>
-                <a class="ns-action" href="mailto:info@wallpapercanada.com?subject=Heritage%20Atelier%20inquiry"><span class="ico">✉️</span><div class="txt"><b>Email Us</b><span>info@wallpapercanada.com</span></div></a>
+                <a class="ns-action" href="mailto:info@wallpapercanada.com?subject=Wallpaper%20Canada%20inquiry"><span class="ico">✉️</span><div class="txt"><b>Email Us</b><span>info@wallpapercanada.com</span></div></a>
                 <a class="ns-action" href="tel:888-373-4564"><span class="ico">📞</span><div class="txt"><b>Call Us</b><span>(888) 373-4564 · M–F, 9–5 PT</span></div></a>
             </div>
         </div>
@@ -410,11 +296,16 @@ textarea:focus-visible,
 
 <section class="cinema">
   <div class="cinema-bg" id="heroBg"></div>
-  <div class="corner-mark">Trade-Grade</div>
-  <div class="center-mark">Wallpaper Canada</div>
-  <div class="meta-line">Hotel · Restaurant · Spa · Class A<span class="num" id="heroNum"></span></div>
-  <a class="enter" href="#shop">Enter <svg viewBox="0 0 24 12" fill="none" stroke="currentColor" stroke-width="1.4"><path d="M0 6h22M16 1l6 5-6 5"/></svg></a>
+  <div class="corner-mark" data-i18n="cornerMark">Made for Canada · CAD Pricing</div>
+  <h1 class="center-mark" data-i18n="heroH1">Wallpaper, made for Canada.</h1>
+  <p class="hero-sub" data-i18n="heroSub">Premium wallcoverings shipped from coast to coast. CAD pricing, GST/PST handled at checkout. Free Canadian shipping on samples.</p>
+  <div class="meta-line" data-i18n="metaLine">BC · AB · ON · QC · NS · Coast to Coast<span class="num" id="heroNum"></span></div>
+  <a class="enter" href="#shop"><span data-i18n="enter">Enter</span> <svg viewBox="0 0 24 12" fill="none" stroke="currentColor" stroke-width="1.4"><path d="M0 6h22M16 1l6 5-6 5"/></svg></a>
 </section>
+<style>
+  .hero-sub { position:absolute; top:50%; left:50%; transform:translate(-50%, -10%); max-width:640px; padding:0 24px; text-align:center; color:#fff; font-family:'Cormorant Garamond', Georgia, serif; font-style:italic; font-weight:400; font-size:clamp(15px, 1.5vw, 19px); line-height:1.5; letter-spacing:0.02em; text-shadow:0 2px 8px rgba(0,0,0,0.65); z-index:5; opacity:0.92 }
+  @media (max-width:720px) { .hero-sub { font-size:14px; transform:translate(-50%, 0%); top:auto; bottom:32%; } }
+</style>
 
 
 <section class="section" id="ideas">
@@ -436,7 +327,7 @@ textarea:focus-visible,
       <div class="section-eyebrow">The Collection</div>
       <h2 class="section-title"><span class="accent" id="totalCount">—</span> Patterns.</h2>
     </div>
-    <div class="section-meta">Hotel · Restaurant · Spa · Class A</div>
+    <div class="section-meta" data-i18n="sectionMeta">Shipped Canada-wide · CAD pricing · Free sample delivery</div>
   </div>
 
   <div class="filters" id="facets">
@@ -447,6 +338,9 @@ textarea:focus-visible,
     <label>Sort</label>
     <select id="sortSelect" aria-label="Sort products" style="background:transparent;color:inherit;border:1px solid var(--line,rgba(255,255,255,.2));font:inherit;font-size:11px;letter-spacing:.10em;text-transform:uppercase;padding:4px 8px;cursor:pointer;outline:none;margin-right:14px">
       <option value="newest">Newest</option>
+      <option value="light-dark">Light → Dark</option>
+      <option value="dark-light">Dark → Light</option>
+      <option value="wheel">Color Wheel</option>
       <option value="color">Color</option>
       <option value="style">Style</option>
       <option value="sku">SKU A→Z</option>
@@ -473,27 +367,28 @@ textarea:focus-visible,
   <div class="footer-grid">
     <div>
       <div class="footer-brand">Wallpaper Canada</div>
-      <p class="footer-text">Wallpaper Canada — samples shipped free across Canada.</p>
+      <p class="footer-text" data-i18n="footerLead">Premium wallcoverings · made for Canada · CAD pricing. Free sample shipping coast to coast — DHL or Canada Post.</p>
       <p class="footer-text" style="margin-top:14px;font-size:11px;letter-spacing:0.18em;text-transform:uppercase;font-weight:600;color:var(--paper);opacity:0.7"><a href="/about" style="color:inherit;text-decoration:none;border-bottom:1px solid var(--accent)">About →</a></p>
     </div>
     <div class="footer-col">
-      <h4>Aesthetic</h4>
+      <h4 data-i18n="footerH4Aesthetic">Aesthetic</h4>
       <div id="footerFacets"></div>
     </div>
     <div class="footer-col">
-      <h4>Trade</h4>
-      <button onclick="dwmOpen('Inquiry')">Project Inquiry</button>
-      <button onclick="dwmOpen('Sample')">Request Sample</button>
-      <button onclick="dwmOpen('Contact')">Contact</button>
+      <h4 data-i18n="footerH4Trade">Trade</h4>
+      <button onclick="dwmOpen('Inquiry')" data-i18n="footerInquiry">Project Inquiry</button>
+      <button onclick="dwmOpen('Sample')" data-i18n="footerSample">Request Sample</button>
+      <button onclick="dwmOpen('Contact')" data-i18n="footerContact">Contact</button>
     </div>
-  
+
     <div class="footer-col">
-      <h4>Social</h4>
+      <h4 data-i18n="footerH4Social">Social</h4>
       <a class="fb-link" href="https://www.facebook.com/SteveAbramsDesigns.DesignerWallcoverings" target="_blank" rel="noopener">Facebook</a>
     </div>
   </div>
+  <p class="footer-text" style="max-width:1400px;margin:0 auto 18px;padding-top:18px;border-top:1px solid var(--line);font-size:11px;line-height:1.6;color:var(--muted);opacity:0.85" data-i18n="cadFootnote">Prices shown in CAD, converted from USD wholesale at 1 USD = 1.36 CAD. Final CAD pricing confirmed at checkout. GST/PST applied at checkout based on shipping province.</p>
   <div class="footer-bottom">
-    <span>wallpapercanada.com · Premium Wallcoverings · Made for Canada</span>
+    <span data-i18n="footerLine1">Designer Wallcoverings · Sherman Oaks, CA · Ships across Canada via DHL/Canada Post</span>
     <span><a href="mailto:info@wallpapercanada.com" style="color:var(--paper);text-decoration:none;border-bottom:1px solid var(--accent);padding-bottom:1px">info@wallpapercanada.com</a></span>
     <span id="footerStat"></span>
   </div>
@@ -569,12 +464,20 @@ const LABELS = {"all":"All"};
 function escAttr(s) { return String(s == null ? '' : s).replace(/[&<>"']/g, c => ({ '&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;' }[c])); }
 // Image-URL allowlist: only DW Shopify CDN + designerwallcoverings.com (defends against XSS via crafted products.json)
 function safeImg(u) { return /^https:\/\/(?:cdn\.shopify\.com|designerwallcoverings\.com)\//.test(u || '') ? u : '/hero-bg.jpg'; }
+// USD → CAD conversion (cosmetic; final price confirmed at checkout)
+const USD_CAD = 1.36;
+function cadPrice(usd) {
+  const n = Number(usd);
+  if (!isFinite(n) || n <= 0) return '';
+  return 'C$' + (n * USD_CAD).toFixed(2);
+}
 function cardHTML(p) {
   const eager = state.page === 1;
+  const cad = cadPrice(p.max_price);
   return '<img loading="' + (eager ? 'eager' : 'lazy') + '"' + (eager ? ' fetchpriority="high"' : '') + ' src="' + escAttr(safeImg(p.image_url)) + '" alt="' + escAttr(p.title) + '">'
     + '<div class="overlay">'
     + '<div class="pat">' + escAttr(p.pattern_name || p.title) + '</div>'
-    + '<div class="ven">' + escAttr((p.vendor || '').replace(/-/g, ' ')) + '</div>'
+    + '<div class="ven">' + escAttr((p.vendor || '').replace(/-/g, ' ')) + (cad ? ' · <span class="cad-price">from ' + cad + ' CAD</span>' : '') + '</div>'
     + '<div class="actions">'
     + '<button class="sample-btn" onclick="event.stopPropagation();dwmOpen(\'Sample\',' + JSON.stringify({sku:p.sku||p.handle, title:p.title, image_url:safeImg(p.image_url)}).replace(/"/g,'&quot;') + ')">Sample</button>'
     + '</div></div>';
@@ -955,10 +858,11 @@ loadGridPage();
     const curated = items.filter((_, i) => i % 5 === 3).slice(0, 12);
     function card(p) {
       const url = (p.image_url || '').replace(/(_\d+x\d*)(\.(jpg|jpeg|png|webp|gif))(\?|$)/i, '$2$4');
+      const cad = (typeof cadPrice === 'function') ? cadPrice(p.max_price) : '';
       return '<a class="rail-card" href="/sample/' + encodeURIComponent(p.handle || p.sku) + '">' +
         '<img src="' + url + '" alt="' + (p.title || '').replace(/"/g, '&quot;') + '" loading="lazy">' +
         '<div class="rc-title">' + ((p.title || '').split('|')[0] || '').trim() + '</div>' +
-        '<div class="rc-meta">' + (p.vendor || '') + '</div>' +
+        '<div class="rc-meta">' + (p.vendor || '') + (cad ? ' · ' + cad + ' CAD' : '') + '</div>' +
       '</a>';
     }
     const r1 = document.getElementById('railNewest');
@@ -970,5 +874,57 @@ loadGridPage();
 </script>
 
 <script src="/dw-fleet-nav.js" defer></script>
+
+<script>
+// EN | FR placeholder toggle. Swaps a small set of nav + hero strings.
+// Persists in localStorage. Full i18n / route-level FR will follow.
+(function(){
+  const FR = {
+    brand: 'Papier Peint Canada',
+    home: 'Accueil',
+    about: 'À propos',
+    contact: 'Contact',
+    cornerMark: 'Fait pour le Canada · Prix en CAD',
+    heroH1: 'Papier peint, fait pour le Canada.',
+    heroSub: "Revêtements muraux haut de gamme expédiés d'un océan à l'autre. Prix en CAD, TPS/TVP gérées au paiement. Livraison gratuite des échantillons partout au Canada.",
+    metaLine: 'CB · AB · ON · QC · NÉ · D’un océan à l’autre',
+    enter: 'Entrer',
+    sectionMeta: 'Expédié partout au Canada · Prix en CAD · Livraison gratuite des échantillons',
+    footerLead: 'Revêtements muraux haut de gamme · fait pour le Canada · prix en CAD. Expédition gratuite des échantillons d’un océan à l’autre — DHL ou Postes Canada.',
+    footerH4Aesthetic: 'Esthétique',
+    footerH4Trade: 'Commerce',
+    footerH4Social: 'Réseaux',
+    footerInquiry: 'Demande de Projet',
+    footerSample: 'Demander un Échantillon',
+    footerContact: 'Contact',
+    cadFootnote: 'Prix affichés en CAD, convertis du prix de gros USD à 1 USD = 1,36 CAD. Prix CAD final confirmé au paiement. TPS/TVP appliquées au paiement selon la province de livraison.',
+    footerLine1: 'Designer Wallcoverings · Sherman Oaks, CA · Expédition partout au Canada via DHL/Postes Canada'
+  };
+  const EN = {};
+  document.querySelectorAll('[data-i18n]').forEach(el => { EN[el.dataset.i18n] = el.textContent; });
+
+  function applyLang(lang) {
+    const dict = lang === 'fr' ? FR : EN;
+    document.querySelectorAll('[data-i18n]').forEach(el => {
+      const k = el.dataset.i18n;
+      if (dict[k] != null) el.textContent = dict[k];
+    });
+    const btn = document.getElementById('langToggle');
+    if (btn) btn.classList.toggle('lang-fr-on', lang === 'fr');
+    document.documentElement.setAttribute('lang', lang === 'fr' ? 'fr-CA' : 'en');
+    try { localStorage.setItem('wc_lang', lang); } catch(e){}
+  }
+
+  window.wcToggleLang = function() {
+    const cur = (localStorage.getItem('wc_lang') || 'en');
+    applyLang(cur === 'fr' ? 'en' : 'fr');
+  };
+
+  let saved = 'en';
+  try { saved = localStorage.getItem('wc_lang') || 'en'; } catch(e){}
+  if (saved === 'fr') applyLang('fr');
+  else applyLang('en');
+})();
+</script>
 </body>
 </html>

← a45c0e8 sort-skill canonical: add light-dark/dark-light/wheel + help  ·  back to Wallpapercanada  ·  snapshot before fleet-grid refine 1688435 →