{"title":"Gift Sets","description":"\u003cp\u003eHair accessory sets that make an easy gift: no sizing needed. Mix any 2 items to save 10%, 3 or more to save 15%, applied automatically at checkout.\u003c\/p\u003e","products":[{"product_id":"geometric-hair-clips-set-of-2","title":"Geometric Hair Clips, Set of 2 – Side Clips for Bangs","description":"\u003ch3\u003eKeep your bangs back, with a little color\u003c\/h3\u003e\n\u003cp\u003eTwo geometric side clips designed to hold bangs and face-framing pieces back, and to add a modern finishing touch on a low-key hair day.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cstrong\u003eHair off your face.\u003c\/strong\u003e Slide one in above your ear or along your part and get on with your day.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eLies flat.\u003c\/strong\u003e Slim clips that sit flat against your hair.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eSeven color pairs.\u003c\/strong\u003e Marble-look, tortoise-pattern and solid shades. Wear one on each side, or stack both together.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eAn easy add-on.\u003c\/strong\u003e Add them to any other Havendoa piece and the 2-item discount (10% off) is applied automatically at checkout.\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003cp\u003e\u003cstrong\u003eWhat you get:\u003c\/strong\u003e 2 coordinating clips in the color pair you choose.\u003c\/p\u003e\n\u003cp\u003e\u003cstrong\u003eGood to know:\u003c\/strong\u003e each clip carries the maker’s small printed mark.\u003c\/p\u003e\n\u003cp\u003e\u003cstrong\u003eSize:\u003c\/strong\u003e see the photos for scale. We’ll add exact measurements once we’ve measured our samples.\u003c\/p\u003e\n\u003cp\u003eFree US shipping on orders $60+ ($8 under $60) · 30-day returns on unworn items in original packaging.\u003c\/p\u003e\n\u003cp\u003eShips from our fulfillment partner overseas: processed in 1–3 business days, then typically 5–11 days in transit.\u003c\/p\u003e\n\u003c!-- hv-upsell v1 (Havendoa, adapted from hh-galixo v3): add-ons with quick view, delivery, trust. Remove from the hv-upsell v1 start marker to the \/hv-upsell v1 end marker to undo. --\u003e\n\u003cdiv class=\"hb\" data-handle=\"geometric-hair-clips-set-of-2\" hidden\u003e\u003cdiv class=\"hb-pay\"\u003e\u003c\/div\u003e\u003c\/div\u003e\n\u003cstyle\u003e\n.hb{--g:#7a5534;--line:#e3e3e3;font-size:15px;color:#2b2b2b}\n.hb-pay{display:flex;flex-wrap:wrap;justify-content:center;gap:6px;margin:12px 0 0}\n.hb-pay svg{width:38px;height:24px}\n.hb-add{margin:16px 0 0;border-radius:12px;background:#f5efe8;padding:12px}\n.hb-add-h{font-weight:700;font-size:17px;color:#1d1d1d;margin:0}\n.hb-add-p{font-size:14px;color:#555;margin:3px 0 6px;line-height:1.45}\n.hb-item{display:flex;align-items:center;gap:10px;background:#fff;border-radius:8px;padding:9px 10px;margin-top:7px;cursor:pointer}\n.hb-item input{width:20px;height:20px;accent-color:var(--g);flex:0 0 20px;margin:0}\n.hb-item img{width:54px;height:54px;object-fit:cover;border-radius:6px;flex:0 0 54px}\n.hb-item-t{flex:1;min-width:0;font-size:14px;line-height:1.35}\n.hb-item-t small{display:block;color:#6b6b6b;font-size:12.5px}\n.hb-item-p{text-align:right;white-space:nowrap;font-weight:700}\n.hb-item-p span{display:block;font-weight:400;font-size:12.5px;color:#c0392b}\n.hb-item-p s{color:#8a8a8a;margin-left:4px}\n.hb-ship{text-align:center;margin:16px 0 0;font-size:15px;line-height:1.5}\n.hb-ship b{color:var(--g)}\n.hb-trust{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:14px 0 18px;text-align:center;font-weight:700;font-size:13.5px;color:var(--g)}\n.hb-trust svg{display:block;margin:0 auto 5px;width:32px;height:32px}\n.hb-err{color:#c0392b;text-align:center;font-size:14px;margin-top:6px}\n.hb-item-a{color:inherit;text-decoration:underline;text-underline-offset:2px}\n.hb-item-img{display:block;flex:0 0 54px}\n.hb-ck{text-align:center;margin:0 0 16px;font-size:14px}\n.hb-ck a{color:var(--g);font-weight:600}\n.hq{position:fixed;inset:0;z-index:2147483000;background:rgba(0,0,0,.45);display:flex;align-items:center;justify-content:center;padding:16px}\n.hq[hidden]{display:none}\n.hq-box{background:#fff;border-radius:14px;max-width:780px;width:100%;max-height:90vh;overflow:auto;position:relative;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:28px;padding:30px 26px 24px;color:#1d1d1d;font-size:15px}\n.hq-box\u003ediv{min-width:0}\n.hq-x{position:absolute;top:8px;right:10px;background:none;border:0;font-size:28px;line-height:1;cursor:pointer;color:#444;padding:4px 8px}\n.hq-main{position:relative;aspect-ratio:1\/1;display:flex;align-items:center;justify-content:center}\n.hq-main img{max-width:100%;max-height:100%;object-fit:contain}\n.hq-nav{position:absolute;top:50%;transform:translateY(-50%);background:rgba(255,255,255,.9);border:0;border-radius:50%;width:36px;height:36px;font-size:24px;line-height:1;cursor:pointer;color:#333}\n.hq-prev{left:0}.hq-next{right:0}\n.hq-th{display:flex;gap:10px;overflow-x:auto;margin-top:14px;padding-bottom:4px}\n.hq-th button{flex:0 0 58px;padding:0 0 6px;border:0;border-bottom:2px solid transparent;background:none;cursor:pointer}\n.hq-th button.on{border-bottom-color:#1d1d1d}\n.hq-th img{width:58px;height:52px;object-fit:cover;border-radius:4px;display:block}\n.hq-t{font-size:21px;line-height:1.35;margin:0 30px 8px 0;font-weight:500}\n.hq-v{font-size:13.5px;color:#6b6b6b;margin:0 0 8px}\n.hq-p{font-size:20px;font-weight:700;margin:0 0 4px}\n.hq-p s{font-size:15px;color:#8a8a8a;font-weight:400;margin-left:6px}\n.hq-save{font-size:13.5px;color:#7a5534;margin:0 0 14px}\n.hq-ul{list-style:none;padding:0;margin:0 0 18px;font-size:14.5px;line-height:1.5}\n.hq-ul li{position:relative;padding-left:27px;margin:0 0 6px}\n.hq-ul li:before{content:\"\\2713\";position:absolute;left:0;top:2px;width:19px;height:19px;border-radius:4px;background:#a57549;color:#fff;font-size:13px;font-weight:700;line-height:19px;text-align:center}\n.hq-add{display:block;width:100%;border:0;border-radius:40px;background:#7a5534;color:#fff;font:inherit;font-weight:700;padding:12px;cursor:pointer;margin:0 0 14px}\n.hq-more{display:inline-block;color:#1d1d1d;font-weight:600;text-decoration:none;font-size:15.5px}\nbody.hq-lock{overflow:hidden}\n@media (max-width:640px){.hq-box{grid-template-columns:minmax(0,1fr);gap:14px;padding:42px 16px 18px}.hq-t{font-size:18px;margin-right:0}}\n\u003c\/style\u003e\n\u003cscript\u003e\n(() =\u003e {\n  const cs = document.currentScript;\n  const start = () =\u003e {\n  const root = (cs \u0026\u0026 cs.parentElement.querySelector('.hb')) || document.querySelector('.hb');\n  if (!root || root.dataset.ready) return;\n  root.dataset.ready = 1;\n  \/\/ what to offer under each product (handle -\u003e handles)\n  const PAIR = {\n    'duo-french-twist-set': ['elegant-claw-clip', 'pearl-crystal-flower-hair-pin-set', 'geometric-hair-clips-set-of-2'],\n    'tortoiseshell-french-hair-pin': ['elegant-claw-clip', 'pearl-crystal-flower-hair-pin-set'],\n    'elegant-claw-clip': ['tortoiseshell-french-hair-pin', 'geometric-hair-clips-set-of-2'],\n    'geometric-hair-clips-set-of-2': ['elegant-claw-clip', 'tortoiseshell-french-hair-pin'],\n    'pearl-crystal-flower-hair-pin-set': ['vintage-crystal-hair-pin-set-of-3', 'tortoiseshell-french-hair-pin'],\n    'vintage-crystal-hair-pin-set-of-3': ['pearl-crystal-flower-hair-pin-set', 'tortoiseshell-french-hair-pin'],\n    'heart-pearl-hair-clip': ['pearl-crystal-flower-hair-pin-set', 'vintage-crystal-hair-pin-set-of-3']\n  };\n  const HEAD = {};\n  \/\/ must match the store's automatic discounts: Buy 2 items 10%, Buy 3+ items 15%\n  const pctFor = n =\u003e n \u003e= 3 ? 15 : n \u003e= 2 ? 10 : 0;\n  const money = c =\u003e '$' + (c \/ 100).toFixed(2);\n  const info = document.querySelector('.product__info-container');\n  const form = info \u0026\u0026 info.querySelector('form[action*=\"\/cart\/add\"][data-type=\"add-to-cart-form\"]');\n  if (!info || !form) return;\n  const blockOf = el =\u003e { while (el \u0026\u0026 el.parentElement !== info) el = el.parentElement; return el; };\n  const buyBlock = blockOf(form);\n  const qtyInput = () =\u003e info.querySelector('.product-form__quantity input[name=\"quantity\"]') || document.querySelector('input[name=\"quantity\"]');\n  const mainQty = () =\u003e Math.max(1, parseInt((qtyInput() || {}).value, 10) || 1);\n  buyBlock.after(root);\n  root.hidden = false;\n  const pay = root.querySelector('.hb-pay'), footerPay = document.querySelector('.list-payment');\n  if (!pay.querySelector('svg') \u0026\u0026 footerPay) pay.innerHTML = [...footerPay.querySelectorAll('svg')].map(s =\u003e s.outerHTML).join('');\n  if (!pay.querySelector('svg')) pay.remove();\n  const icon = d =\u003e '\u003csvg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.7\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\u003e' + d + '\u003c\/svg\u003e';\n  root.insertAdjacentHTML('beforeend',\n    '\u003cdiv class=\"hb-add\" hidden\u003e\u003c\/div\u003e' +\n    '\u003cdiv class=\"hb-ship\"\u003e\u003cb\u003eFree US shipping\u003c\/b\u003e on orders $60+.\u003cbr\u003eTypical delivery: 5–11 days after dispatch.\u003c\/div\u003e' +\n    '\u003cdiv class=\"hb-trust\"\u003e' +\n    '\u003cdiv\u003e' + icon('\u003cpath d=\"M3 7h11v8H3zM14 10h4l3 3v2h-7\"\/\u003e\u003ccircle cx=\"7\" cy=\"17\" r=\"1.6\"\/\u003e\u003ccircle cx=\"17\" cy=\"17\" r=\"1.6\"\/\u003e') + 'Free Shipping $60+\u003c\/div\u003e' +\n    '\u003cdiv\u003e' + icon('\u003cpath d=\"M4 12a8 8 0 1 0 2.4-5.7\"\/\u003e\u003cpath d=\"M4 4v4h4\"\/\u003e') + '30-Day Returns\u003c\/div\u003e' +\n    '\u003cdiv\u003e' + icon('\u003crect x=\"5\" y=\"11\" width=\"14\" height=\"9\" rx=\"2\"\/\u003e\u003cpath d=\"M8 11V8a4 4 0 0 1 8 0v3\"\/\u003e') + 'Secure Checkout\u003c\/div\u003e' +\n    '\u003c\/div\u003e' +\n    '\u003cp class=\"hb-ck\"\u003e\u003ca href=\"\/blogs\/hair-guides\/how-to-use-a-french-hair-pin\"\u003eNew to French pins? Read our step-by-step guide \u0026rarr;\u003c\/a\u003e\u003c\/p\u003e');\n  const handles = PAIR[root.dataset.handle] || [];\n  let extras = [];\n  const add = root.querySelector('.hb-add');\n  const picks = () =\u003e [...add.querySelectorAll('input:checked')].map(c =\u003e extras[+c.dataset.x]);\n  const paint = () =\u003e {\n    const n = mainQty() + picks().length;\n    add.querySelectorAll('.hb-item').forEach(el =\u003e {\n      const e = extras[+el.dataset.x], on = el.querySelector('input').checked;\n      const pct = pctFor(on ? n : n + 1);\n      el.querySelector('.hb-item-p').innerHTML = (pct ? '\u003cspan\u003e-' + pct + '%\u003cs\u003e' + money(e.v.price) + '\u003c\/s\u003e\u003c\/span\u003e' : '') + money(e.v.price - Math.floor(e.v.price * pct \/ 100));\n    });\n  };\n  Promise.all(handles.map(h =\u003e fetch('\/products\/' + h + '.js').then(r =\u003e r.ok ? r.json() : null).catch(() =\u003e null))).then(list =\u003e {\n    extras = list.filter(Boolean).map(a =\u003e { const v = a.variants.find(x =\u003e x.available); return v \u0026\u0026 { a, v }; }).filter(Boolean);\n    if (!extras.length) return;\n    const img = s =\u003e s ? s + (s.includes('?') ? '\u0026' : '?') + 'width=120' : '';\n    const link = e =\u003e '\/products\/' + e.a.handle + '?variant=' + e.v.id;\n    add.innerHTML = '\u003cp class=\"hb-add-h\"\u003e' + (HEAD[root.dataset.handle] || 'Complete the look') + '\u003c\/p\u003e' +\n      '\u003cp class=\"hb-add-p\"\u003eCheck the box to add it to this order. 2 items save 10%, 3 or more save 15%, applied automatically at checkout.\u003c\/p\u003e' +\n      extras.map((e, i) =\u003e '\u003clabel class=\"hb-item\" data-x=\"' + i + '\"\u003e\u003cinput type=\"checkbox\" data-x=\"' + i + '\"\u003e' +\n        (e.a.featured_image ? '\u003ca class=\"hb-item-img\" href=\"' + link(e) + '\" tabindex=\"-1\" aria-hidden=\"true\"\u003e\u003cimg src=\"' + img(e.a.featured_image) + '\" alt=\"\" loading=\"lazy\"\u003e\u003c\/a\u003e' : '') +\n        '\u003cspan class=\"hb-item-t\"\u003e\u003ca class=\"hb-item-a\" href=\"' + link(e) + '\"\u003e' + e.a.title.split(' – ')[0] + '\u003c\/a\u003e' + (e.a.variants.length \u003e 1 ? '\u003csmall\u003e' + e.v.title.split(' \/ ')[0] + '\u003c\/small\u003e' : '') + '\u003c\/span\u003e' +\n        '\u003cspan class=\"hb-item-p\"\u003e\u003c\/span\u003e\u003c\/label\u003e').join('');\n    add.hidden = false;\n    add.addEventListener('click', ev =\u003e {\n      const a = ev.target.closest('.hb-item-a, .hb-item-img');\n      if (!a || !window.hhQV) return;\n      ev.preventDefault();\n      const i = +a.closest('.hb-item').dataset.x, e = extras[i], cb = add.querySelector('input[data-x=\"' + i + '\"]');\n      window.hhQV({ a: e.a, v: e.v, from: a, note: 'Add it to this order: 2 items save 10%, 3 or more save 15% at checkout.', addLabel: cb.checked ? 'Remove from this order' : 'Add to this order', onAdd: () =\u003e { cb.checked = !cb.checked; cb.dispatchEvent(new Event('change', { bubbles: true })); } });\n    });\n    add.addEventListener('change', paint);\n    document.addEventListener('change', e =\u003e { if (e.target.name === 'quantity') setTimeout(paint, 50); });\n    paint();\n  });\n  document.addEventListener('submit', async e =\u003e {\n    if (e.target !== form || !picks().length) return;\n    e.preventDefault(); e.stopImmediatePropagation();\n    const btn = form.querySelector('[type=\"submit\"]'); if (btn) btn.setAttribute('aria-disabled', 'true');\n    const items = [{ id: +form.querySelector('input[name=\"id\"]').value, quantity: mainQty() }, ...picks().map(x =\u003e ({ id: x.v.id, quantity: 1 }))];\n    let r = null;\n    try { r = await fetch('\/cart\/add.js', { method: 'POST', headers: { 'Content-Type': 'application\/json' }, body: JSON.stringify({ items }) }); } catch (x) {}\n    if (r \u0026\u0026 r.ok) { location.href = '\/cart'; return; }\n    if (btn) btn.removeAttribute('aria-disabled');\n    let err = root.querySelector('.hb-err'); if (!err) { err = document.createElement('p'); err.className = 'hb-err'; add.after(err); }\n    err.textContent = (r \u0026\u0026 (await r.json().catch(() =\u003e ({}))).description) || 'Could not add to cart. Please try again.';\n  }, true);\n  window.addEventListener('pageshow', e =\u003e { if (e.persisted) { const b = form.querySelector('[type=\"submit\"]'); if (b) b.removeAttribute('aria-disabled'); } });\n  };\n  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', start); else start();\n})();\n\u003c\/script\u003e\n\u003c!-- \/hv-upsell v1 --\u003e\n\u003c!-- hv-extra v1 (Havendoa, adapted from hh-downsell v2 + hh-nopantry v2): shared quick view, single\/duo switch, French Twist Kit. Remove from the hv-extra v1 start marker to the \/hv-extra v1 end marker to undo. --\u003e\n\u003cdiv class=\"hd\" data-handle=\"geometric-hair-clips-set-of-2\" hidden\u003e\u003c\/div\u003e\u003cdiv class=\"hn\" data-handle=\"geometric-hair-clips-set-of-2\" hidden\u003e\u003c\/div\u003e\n\u003cstyle\u003e\n.hd{--g:#7a5534;margin:6px 0 18px;border:1px solid #e5d6c6;border-radius:12px;padding:12px;background:#fff;font-size:15px;color:#2b2b2b}\n.hd-h{font-weight:700;font-size:17px;margin:0}\n.hd-p{font-size:14px;color:#555;margin:3px 0 8px;line-height:1.45}\n.hd-card{display:flex;gap:10px;align-items:flex-start;border-top:1px solid #eee;padding:10px 0 4px}\n.hd-card img{width:62px;height:62px;object-fit:cover;border-radius:8px;flex:0 0 62px}\n.hd-b{flex:1;min-width:0;font-size:13.5px;line-height:1.4}\n.hd-b a.hd-t{font-weight:700;color:#1d1d1d;text-decoration:underline;text-underline-offset:2px;font-size:14.5px}\n.hd-img{display:block;flex:0 0 62px}\n.hd-b .hd-in{color:#2f6b52}\n.hd-b .hd-out{color:#8a5a2b}\n.hd-btn{margin-top:6px;border:1.5px solid var(--g);background:#fff;color:var(--g);border-radius:30px;padding:7px 14px;font:inherit;font-weight:700;font-size:13.5px;cursor:pointer}\n.hd-btn:disabled{opacity:.6}\n.hn{--g:#7a5534;margin:6px 0 18px;border:2px solid var(--g);border-radius:14px;padding:14px;background:#f8f2ec;font-size:15px;color:#2b2b2b}\n.hn-k{font-size:12px;letter-spacing:.08em;text-transform:uppercase;font-weight:700;color:#c75b2a;margin:0}\n.hn-h{font-weight:700;font-size:18px;margin:2px 0 4px;color:var(--g)}\n.hn-p{font-size:14px;color:#555;margin:0 0 10px;line-height:1.45}\n.hn-list{display:grid;gap:8px;margin:0 0 10px}\n.hn-row{display:flex;gap:10px;align-items:center;background:#fff;border-radius:10px;padding:8px}\n.hn-row img{width:48px;height:48px;object-fit:cover;border-radius:6px;flex:0 0 48px}\n.hn-row span{flex:1;min-width:0;font-size:13.5px;line-height:1.35}\n.hn-row span small{display:block;color:#6b6b6b}\n.hn-row b{white-space:nowrap;font-size:14px}\n.hn-sum{display:flex;justify-content:space-between;font-size:14px;margin:2px 2px 0}\n.hn-sum.hn-you{font-weight:700;font-size:16px;color:var(--g)}\n.hn-btn{display:block;width:100%;margin-top:10px;border:0;border-radius:40px;background:var(--g);color:#fff;font:inherit;font-weight:700;font-size:16px;padding:13px;cursor:pointer}\n.hn-btn:disabled{opacity:.6}\n.hn-a{color:inherit;text-decoration:underline;text-underline-offset:2px}\n.hn-img{display:block;flex:0 0 48px}\n.hn-note{font-size:12.5px;color:#6b6b6b;margin:8px 0 0;text-align:center}\n\u003c\/style\u003e\n\u003cscript\u003e\n(() =\u003e {\n  const cs = document.currentScript;\n  if (!window.hhQV) window.hhQV = (() =\u003e {\n    const qv = document.createElement('div');\n    qv.className = 'hq'; qv.hidden = true;\n    document.body.appendChild(qv);\n    const px = (s, w) =\u003e s ? s + (s.includes('?') ? '\u0026' : '?') + 'width=' + w : '';\n    const esc = s =\u003e String(s).replace(\/[\u0026\u003c\u003e\"]\/g, c =\u003e ({ '\u0026': '\u0026amp;', '\u003c': '\u0026lt;', '\u003e': '\u0026gt;', '\"': '\u0026quot;' }[c]));\n    const cash = c =\u003e '$' + (c \/ 100).toFixed(2);\n    const fileOf = s =\u003e String(s || '').split('?')[0].split('\/').pop();\n    const bullets = html =\u003e {\n      const d = new DOMParser().parseFromString(html || '', 'text\/html');\n      d.querySelectorAll('script, style, .hb, .hd, .hn').forEach(x =\u003e x.remove());\n      let li = [...d.querySelectorAll('li')].map(x =\u003e x.textContent.replace(\/\\s+\/g, ' ').trim()).filter(Boolean);\n      if (!li.length) li = [...d.querySelectorAll('p')].map(x =\u003e x.textContent.trim()).filter(Boolean).slice(0, 1);\n      return li.slice(0, 5).map(t =\u003e t.length \u003e 95 ? t.slice(0, 92).replace(\/[\\s,.;:]+\\S*$\/, '') + '…' : t);\n    };\n    let back = null;\n    const close = () =\u003e { qv.hidden = true; document.body.classList.remove('hq-lock'); if (back) back.focus(); };\n    qv.addEventListener('click', ev =\u003e { if (ev.target === qv) close(); });\n    document.addEventListener('keydown', ev =\u003e {\n      if (qv.hidden) return;\n      if (ev.key === 'Escape') close();\n      if (ev.key === 'ArrowLeft') { const b = qv.querySelector('.hq-prev'); if (b) b.click(); }\n      if (ev.key === 'ArrowRight') { const b = qv.querySelector('.hq-next'); if (b) b.click(); }\n    });\n    return o =\u003e {\n      const a = o.a, v = o.v;\n      back = o.from || null;\n      const imgs = (a.images \u0026\u0026 a.images.length) ? a.images : [a.featured_image];\n      let k = v.featured_image ? Math.max(0, imgs.findIndex(s =\u003e fileOf(s) === fileOf(v.featured_image.src))) : 0;\n      qv.innerHTML = '\u003cdiv class=\"hq-box\" role=\"dialog\" aria-modal=\"true\" aria-label=\"' + esc(a.title) + '\"\u003e' +\n        '\u003cbutton type=\"button\" class=\"hq-x\" aria-label=\"Close\"\u003e\u0026times;\u003c\/button\u003e' +\n        '\u003cdiv\u003e\u003cdiv class=\"hq-main\"\u003e\u003cimg alt=\"\"\u003e' +\n        (imgs.length \u003e 1 ? '\u003cbutton type=\"button\" class=\"hq-nav hq-prev\" aria-label=\"Previous image\"\u003e\u0026lsaquo;\u003c\/button\u003e\u003cbutton type=\"button\" class=\"hq-nav hq-next\" aria-label=\"Next image\"\u003e\u0026rsaquo;\u003c\/button\u003e' : '') +\n        '\u003c\/div\u003e' + (imgs.length \u003e 1 ? '\u003cdiv class=\"hq-th\"\u003e' + imgs.map((s, j) =\u003e '\u003cbutton type=\"button\" data-j=\"' + j + '\" aria-label=\"Image ' + (j + 1) + '\"\u003e\u003cimg src=\"' + px(s, 120) + '\" alt=\"\" loading=\"lazy\"\u003e\u003c\/button\u003e').join('') + '\u003c\/div\u003e' : '') + '\u003c\/div\u003e' +\n        '\u003cdiv\u003e\u003ch2 class=\"hq-t\"\u003e' + esc(a.title) + '\u003c\/h2\u003e' +\n        (a.variants.length \u003e 1 ? '\u003cp class=\"hq-v\"\u003e' + esc(v.title.split(' \/ ')[0]) + '\u003c\/p\u003e' : '') +\n        '\u003cp class=\"hq-p\"\u003e' + cash(v.price) + (v.compare_at_price \u003e v.price ? '\u003cs\u003e' + cash(v.compare_at_price) + '\u003c\/s\u003e' : '') + '\u003c\/p\u003e' +\n        (o.note ? '\u003cp class=\"hq-save\"\u003e' + esc(o.note) + '\u003c\/p\u003e' : '') +\n        '\u003cul class=\"hq-ul\"\u003e' + bullets(a.description).map(t =\u003e '\u003cli\u003e' + esc(t) + '\u003c\/li\u003e').join('') + '\u003c\/ul\u003e' +\n        (o.onAdd ? '\u003cbutton type=\"button\" class=\"hq-add\"\u003e' + esc(o.addLabel || 'Add to cart') + '\u003c\/button\u003e' : '') +\n        '\u003ca class=\"hq-more\" href=\"\/products\/' + a.handle + '?variant=' + v.id + '\"\u003eView more details \u003cspan aria-hidden=\"true\"\u003e\u0026rarr;\u003c\/span\u003e\u003c\/a\u003e\u003c\/div\u003e\u003c\/div\u003e';\n      const main = qv.querySelector('.hq-main img'), th = [...qv.querySelectorAll('.hq-th button')];\n      const show = j =\u003e { k = (j + imgs.length) % imgs.length; main.src = px(imgs[k], 800); th.forEach((b, x) =\u003e b.classList.toggle('on', x === k)); };\n      th.forEach(b =\u003e b.addEventListener('click', () =\u003e show(+b.dataset.j)));\n      const prev = qv.querySelector('.hq-prev'), next = qv.querySelector('.hq-next');\n      if (prev) prev.addEventListener('click', () =\u003e show(k - 1));\n      if (next) next.addEventListener('click', () =\u003e show(k + 1));\n      qv.querySelector('.hq-x').addEventListener('click', close);\n      const addBtn = qv.querySelector('.hq-add');\n      if (addBtn) addBtn.addEventListener('click', () =\u003e { close(); o.onAdd(); });\n      show(k);\n      qv.hidden = false;\n      document.body.classList.add('hq-lock');\n      qv.querySelector('.hq-x').focus();\n    };\n  })();\n  \/\/ single \u003c-\u003e duo switch, per product page\n  const SWITCH = {\n    'duo-french-twist-set': { h: 'Just need one pin?', p: 'Start with a single pin and add a second one later.', items: [{ handle: 'tortoiseshell-french-hair-pin', name: 'French Hair Pin', inc: '1 French Hair Pin in the color you choose', out: 'the second pin (the Duo is $65, less than two single pins)' }] },\n    'tortoiseshell-french-hair-pin': { h: 'Want a spare? Get the Duo', p: 'One pin for a quick twist, two for a fuller, more secure bun. $65 for two: less than two single pins, even with the 2-item discount.', items: [{ handle: 'duo-french-twist-set', name: 'Duo French Twist Set', inc: '2 French Hair Pins in the color you choose', out: '' }] }\n  };\n  \/\/ French Twist Kit, shown on these pages\n  const KIT_ON = ['duo-french-twist-set', 'tortoiseshell-french-hair-pin', 'elegant-claw-clip'];\n  const SET = [\n    { h: 'duo-french-twist-set', name: 'Duo French Twist Set', note: 'two French pins for the twist' },\n    { h: 'elegant-claw-clip', name: 'Elegant Claw Clip', note: 'for quick half-up days' },\n    { h: 'pearl-crystal-flower-hair-pin-set', name: 'Simulated Pearl \u0026 Crystal Flower Pins', note: 'for weddings and special days' }\n  ];\n  const PCT = 15; \/\/ store's automatic discount for 3+ items\n  const money = c =\u003e '$' + (c \/ 100).toFixed(2);\n  const img = (s, w) =\u003e s ? s + (s.includes('?') ? '\u0026' : '?') + 'width=' + w : '';\n  const go = async items =\u003e { const r = await fetch('\/cart\/add.js', { method: 'POST', headers: { 'Content-Type': 'application\/json' }, body: JSON.stringify({ items }) }); return r.ok; };\n  const start = () =\u003e {\n    const d = (cs \u0026\u0026 cs.parentElement.querySelector('.hd')) || document.querySelector('.hd');\n    const n = (cs \u0026\u0026 cs.parentElement.querySelector('.hn')) || document.querySelector('.hn');\n    if (!d || d.dataset.ready) return;\n    d.dataset.ready = 1;\n    const handle = d.dataset.handle;\n    const anchor = () =\u003e document.querySelector('.hb:not([hidden])') || (document.querySelector('.product__info-container product-form') || {}).parentElement;\n    const sw = SWITCH[handle];\n    if (sw) Promise.all(sw.items.map(o =\u003e fetch('\/products\/' + o.handle + '.js').then(r =\u003e r.ok ? r.json() : null).catch(() =\u003e null))).then(list =\u003e {\n      const rows = sw.items.map((o, i) =\u003e ({ o, p: list[i] })).filter(x =\u003e x.p \u0026\u0026 x.p.available);\n      if (!rows.length) return;\n      d.innerHTML = '\u003cp class=\"hd-h\"\u003e' + sw.h + '\u003c\/p\u003e\u003cp class=\"hd-p\"\u003e' + sw.p + '\u003c\/p\u003e' + rows.map((x, i) =\u003e {\n        const v = x.p.variants.find(v =\u003e v.available), lk = '\/products\/' + x.o.handle + '?variant=' + v.id;\n        return '\u003cdiv class=\"hd-card\" data-i=\"' + i + '\"\u003e' + (x.p.featured_image ? '\u003ca class=\"hd-img\" href=\"' + lk + '\"\u003e\u003cimg src=\"' + img(x.p.featured_image, 140) + '\" alt=\"\"\u003e\u003c\/a\u003e' : '') +\n          '\u003cdiv class=\"hd-b\"\u003e\u003ca class=\"hd-t\" href=\"' + lk + '\"\u003e' + x.o.name + ' · ' + money(v.price) + (v.compare_at_price \u003e v.price ? ' \u003cs\u003e' + money(v.compare_at_price) + '\u003c\/s\u003e' : '') + '\u003c\/a\u003e\u003cbr\u003e' +\n          '\u003cspan class=\"hd-in\"\u003eIncludes: ' + x.o.inc + '.\u003c\/span\u003e' + (x.o.out ? '\u003cbr\u003e\u003cspan class=\"hd-out\"\u003eNot included: ' + x.o.out + '.\u003c\/span\u003e' : '') + '\u003cbr\u003e' +\n          '\u003cbutton type=\"button\" class=\"hd-btn\" data-v=\"' + v.id + '\"\u003eAdd to cart — ' + money(v.price) + '\u003c\/button\u003e' + (x.p.variants.length \u003e 1 ? ' \u003csmall\u003e(' + v.title.split(' \/ ')[0] + '; pick another color on its page)\u003c\/small\u003e' : '') + '\u003c\/div\u003e\u003c\/div\u003e';\n      }).join('');\n      const a = anchor(); if (a) a.after(d);\n      d.hidden = false;\n      d.addEventListener('click', ev =\u003e {\n        const l = ev.target.closest('a.hd-t, a.hd-img'); if (!l) return; ev.preventDefault();\n        const card = l.closest('.hd-card'), x = rows[+card.dataset.i], b = card.querySelector('.hd-btn');\n        window.hhQV({ a: x.p, v: x.p.variants.find(v =\u003e v.available), from: l, note: 'Includes: ' + x.o.inc + '.', addLabel: b.textContent, onAdd: () =\u003e b.click() });\n      });\n      d.querySelectorAll('.hd-btn').forEach(b =\u003e b.addEventListener('click', async () =\u003e { b.disabled = true; b.textContent = 'Adding…'; if (await go([{ id: +b.dataset.v, quantity: 1 }])) location.href = '\/cart'; else { b.disabled = false; b.textContent = 'Could not add. Try again'; } }));\n    });\n    if (n \u0026\u0026 KIT_ON.includes(handle)) Promise.all(SET.map(s =\u003e fetch('\/products\/' + s.h + '.js').then(r =\u003e r.ok ? r.json() : null).catch(() =\u003e null))).then(list =\u003e {\n      const rows = SET.map((s, i) =\u003e { const p = list[i]; if (!p) return null; const v = p.variants.find(v =\u003e v.available); return v ? { s, p, v } : null; });\n      if (rows.some(r =\u003e !r)) return;\n      const sum = rows.reduce((a, r) =\u003e a + r.v.price, 0), you = sum - Math.floor(sum * PCT \/ 100);\n      const lk = r =\u003e '\/products\/' + r.s.h + '?variant=' + r.v.id;\n      n.innerHTML = '\u003cp class=\"hn-k\"\u003eThe French Twist Kit\u003c\/p\u003e\u003cp class=\"hn-h\"\u003eEverything for an effortless updo.\u003c\/p\u003e' +\n        '\u003cp class=\"hn-p\"\u003eTwo French pins for the twist, a claw clip for quick half-up days, and simulated pearl flower pins for special occasions.\u003c\/p\u003e' +\n        '\u003cdiv class=\"hn-list\"\u003e' + rows.map((r, i) =\u003e '\u003cdiv class=\"hn-row\" data-i=\"' + i + '\"\u003e' + (r.p.featured_image ? '\u003ca class=\"hn-img\" href=\"' + lk(r) + '\"\u003e\u003cimg src=\"' + img(r.p.featured_image, 100) + '\" alt=\"\"\u003e\u003c\/a\u003e' : '') +\n          '\u003cspan\u003e\u003ca class=\"hn-a\" href=\"' + lk(r) + '\"\u003e' + r.s.name + '\u003c\/a\u003e\u003csmall\u003e' + r.s.note + (r.p.variants.length \u003e 1 ? ' · ' + r.v.title.split(' \/ ')[0] : '') + '\u003c\/small\u003e\u003c\/span\u003e\u003cb\u003e' + money(r.v.price) + '\u003c\/b\u003e\u003c\/div\u003e').join('') + '\u003c\/div\u003e' +\n        '\u003cdiv class=\"hn-sum\"\u003e\u003cspan\u003eBought separately\u003c\/span\u003e\u003cspan\u003e' + money(sum) + '\u003c\/span\u003e\u003c\/div\u003e' +\n        '\u003cdiv class=\"hn-sum hn-you\"\u003e\u003cspan\u003eWith ' + PCT + '% off 3+ items\u003c\/span\u003e\u003cspan\u003e' + money(you) + '\u003c\/span\u003e\u003c\/div\u003e' +\n        '\u003cbutton type=\"button\" class=\"hn-btn\"\u003eAdd all ' + rows.length + ' to cart — ' + money(you) + ' at checkout\u003c\/button\u003e' +\n        '\u003cp class=\"hn-note\"\u003eThe ' + PCT + '% applies automatically at checkout and can’t be combined with other discount codes. Items may arrive in separate parcels, each with its own tracking number.\u003c\/p\u003e';\n      const a = (d.hidden ? null : d) || anchor(); if (a) a.after(n);\n      n.hidden = false;\n      const btn = n.querySelector('.hn-btn');\n      const pickColor = () =\u003e { const i = document.querySelector('variant-picker input:checked, variant-selects input:checked, variant-radios input:checked'); return i ? i.value : null; };\n      const pickDuo = r =\u003e { const c = pickColor(); return (c \u0026\u0026 r.p.variants.find(v =\u003e v.available \u0026\u0026 v.title.split(' \/ ')[0] === c)) || r.v; };\n      const relabel = () =\u003e { rows.forEach((r, i) =\u003e { if (r.s.h !== 'duo-french-twist-set' || r.p.variants.length \u003c 2) return; const el = n.querySelector('.hn-row[data-i=\"' + i + '\"] small'); if (el) el.textContent = r.s.note + ' · ' + pickDuo(r).title.split(' \/ ')[0]; }); };\n      document.addEventListener('change', () =\u003e setTimeout(relabel, 200)); relabel();\n      btn.addEventListener('click', async () =\u003e { btn.disabled = true; btn.textContent = 'Adding…'; if (await go(rows.map(x =\u003e ({ id: (x.s.h === 'duo-french-twist-set' ? pickDuo(x) : x.v).id, quantity: 1 })))) location.href = '\/cart'; else { btn.disabled = false; btn.textContent = 'Could not add. Try again'; } });\n      n.addEventListener('click', ev =\u003e {\n        const l = ev.target.closest('a.hn-a, a.hn-img'); if (!l) return; ev.preventDefault();\n        const r = rows[+l.closest('.hn-row').dataset.i];\n        window.hhQV({ a: r.p, v: r.v, from: l, note: 'Part of the French Twist Kit: ' + r.s.note + '.', addLabel: btn.textContent, onAdd: () =\u003e btn.click() });\n      });\n    });\n  };\n  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', () =\u003e setTimeout(start, 50)); else setTimeout(start, 50);\n})();\n\u003c\/script\u003e\n\u003c!-- \/hv-extra v1 --\u003e\n\u003c!-- hv-tiers v1 (Havendoa): \"Buy more, save more\" 1\/2\/3 items, replaces the quantity box. Must match automatic discounts (2 items 10%, 3+ items 15%). Remove from the hv-tiers v1 start marker to the \/hv-tiers v1 end marker to undo. --\u003e\n\u003cdiv class=\"hv-tiers\" data-handle=\"geometric-hair-clips-set-of-2\" hidden\u003e\u003c\/div\u003e\n\u003cstyle\u003e\n.hv-tiers{margin:4px 0 16px;background:#f5efe8;border:1px solid #e5d6c6;border-radius:14px;padding:12px 12px 6px;font-size:15px;color:#2b2b2b}\n.hv-tiers__h{font-weight:700;font-size:16px;margin:0 0 8px;color:#7a5534}\n.hv-tier{display:flex;align-items:center;gap:10px;background:#fff;border:1px solid #eadfd3;border-radius:10px;padding:10px 12px;margin:0 0 8px;cursor:pointer}\n.hv-tier.is-on{box-shadow:0 0 0 2px #7a5534;border-color:#7a5534}\n.hv-tier input{width:20px;height:20px;accent-color:#7a5534;margin:0;flex:0 0 20px}\n.hv-tier__t{flex:1;min-width:0;line-height:1.3}\n.hv-tier__t small{display:block;color:#6b6b6b;font-size:12.5px}\n.hv-tier__b{display:inline-block;margin-left:6px;background:#7a5534;color:#fff;border-radius:20px;font-size:11.5px;font-weight:700;padding:2px 8px;vertical-align:middle}\n.hv-tier__p{text-align:right;font-weight:700;white-space:nowrap}\n.hv-tier__p s{display:block;font-weight:400;font-size:12.5px;color:#8a8a8a}\n.hv-tiers__note{font-size:12.5px;color:#6b6b6b;margin:0 2px 6px}\n\u003c\/style\u003e\n\u003cscript\u003e\n(() =\u003e {\n  const cs = document.currentScript;\n  const TIERS = [[1, 0, ''], [2, 10, 'Save 10%'], [3, 15, 'Save 15%']];\n  const money = c =\u003e '$' + (c \/ 100).toFixed(2);\n  const start = () =\u003e {\n    const box = (cs \u0026\u0026 cs.parentElement.querySelector('.hv-tiers')) || document.querySelector('.hv-tiers');\n    if (!box || box.dataset.ready) return;\n    box.dataset.ready = 1;\n    const info = document.querySelector('.product__info-container');\n    const form = info \u0026\u0026 info.querySelector('form[action*=\"\/cart\/add\"][data-type=\"add-to-cart-form\"]');\n    if (!info || !form) return;\n    const blockOf = el =\u003e { while (el \u0026\u0026 el.parentElement !== info) el = el.parentElement; return el; };\n    const qtyBox = info.querySelector('.product-form__quantity');\n    const anchor = qtyBox ? blockOf(qtyBox) : blockOf(form);\n    const qty = () =\u003e info.querySelector('input[name=\"quantity\"]') || document.querySelector('input[name=\"quantity\"]');\n    fetch('\/products\/' + box.dataset.handle + '.js').then(r =\u003e r.ok ? r.json() : null).then(p =\u003e {\n      if (!p) return;\n      const cur = () =\u003e { const id = +(form.querySelector('input[name=\"id\"]') || {}).value; return p.variants.find(v =\u003e v.id === id) || p.variants.find(v =\u003e v.available) || p.variants[0]; };\n      const render = () =\u003e {\n        const v = cur(), on = box.querySelector('input:checked'), pick = on ? +on.value : Math.max(1, Math.min(3, parseInt((qty() || {}).value, 10) || 1));\n        box.innerHTML = '\u003cp class=\"hv-tiers__h\"\u003eBuy more, save more\u003c\/p\u003e' + TIERS.map(([n, pct, badge]) =\u003e {\n          const full = v.price * n, you = full - Math.floor(full * pct \/ 100);\n          return '\u003clabel class=\"hv-tier' + (n === pick ? ' is-on' : '') + '\"\u003e\u003cinput type=\"radio\" name=\"hv-tier\" value=\"' + n + '\"' + (n === pick ? ' checked' : '') + '\u003e' +\n            '\u003cspan class=\"hv-tier__t\"\u003e\u003cb\u003e' + n + (n === 1 ? ' item' : ' items') + '\u003c\/b\u003e' + (badge ? '\u003cspan class=\"hv-tier__b\"\u003e' + badge + '\u003c\/span\u003e' : '') + (p.variants.length \u003e 1 ? '\u003csmall\u003e' + v.title.split(' \/ ')[0] + (n \u003e 1 ? ' x ' + n : '') + '\u003c\/small\u003e' : '') + '\u003c\/span\u003e' +\n            '\u003cspan class=\"hv-tier__p\"\u003e' + money(you) + (pct ? '\u003cs\u003e' + money(full) + '\u003c\/s\u003e' : '') + '\u003c\/span\u003e\u003c\/label\u003e';\n        }).join('') + '\u003cp class=\"hv-tiers__note\"\u003eWant different colors? Add each one to your cart: the discount counts every item in your order.\u003c\/p\u003e';\n      };\n      const setQty = n =\u003e { const q = qty(); if (q \u0026\u0026 q.value !== String(n)) { q.value = n; q.dispatchEvent(new Event('change', { bubbles: true })); } };\n      anchor.before(box);\n      if (qtyBox) anchor.style.display = 'none';\n      render(); box.hidden = false;\n      box.addEventListener('change', e =\u003e { if (e.target.name !== 'hv-tier') return; setQty(+e.target.value); render(); });\n      \/\/ the theme resets quantity to 1 on every variant change; put the tier back and refresh prices\n      document.addEventListener('change', e =\u003e { if (box.contains(e.target)) return; if (e.target \u0026\u0026 e.target.name === 'id') setTimeout(() =\u003e { const t = box.querySelector('input:checked'); if (t) setQty(+t.value); render(); }, 60); });\n      window.addEventListener('pageshow', () =\u003e setTimeout(() =\u003e { const t = box.querySelector('input:checked'); if (t) setQty(+t.value); }, 0));\n    });\n  };\n  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', start); else start();\n})();\n\u003c\/script\u003e\n\u003c!-- \/hv-tiers v1 --\u003e","brand":"Havendoa","offers":[{"title":"Tortoise \u0026 Olive","offer_id":49283867672759,"sku":"HV-GEO-TOL","price":34.0,"currency_code":"USD","in_stock":true},{"title":"Pink Marble \u0026 Blush","offer_id":49284520116407,"sku":"HV-GEO-PNK","price":34.0,"currency_code":"USD","in_stock":true},{"title":"Cream Marble \u0026 Amber","offer_id":49284520149175,"sku":"HV-GEO-CRM","price":34.0,"currency_code":"USD","in_stock":true},{"title":"Blue Marble \u0026 Teal","offer_id":49284520181943,"sku":"HV-GEO-BLU","price":34.0,"currency_code":"USD","in_stock":true},{"title":"Dalmatian \u0026 Red","offer_id":49284520214711,"sku":"HV-GEO-DAL","price":34.0,"currency_code":"USD","in_stock":true},{"title":"Ivory White","offer_id":49284520247479,"sku":"HV-GEO-WHT","price":34.0,"currency_code":"USD","in_stock":true},{"title":"Burgundy \u0026 Black","offer_id":49284520280247,"sku":"HV-GEO-BUB","price":34.0,"currency_code":"USD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0761\/4998\/1367\/files\/S6fa765fa725844ada34a52b8b9f42446V.webp?v=1790938307"},{"product_id":"vintage-crystal-hair-pin-set-of-3","title":"Vintage Crystal Hair Pin Set of 3 – Moon \u0026 Star Hair Clips","description":"\u003ch3\u003eMoon, stars and a little sparkle\u003c\/h3\u003e\n\u003cp\u003eThree vintage-inspired hair pins with moon and star designs, for the days that call for a little extra: weddings, holidays, date night. Wear them together or one at a time.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cstrong\u003eA set of 3.\u003c\/strong\u003e Line them up along a side part, scatter them through a braid, or wear just one.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eFive metal tones.\u003c\/strong\u003e Gold-tone, Silver-tone, Rose Gold-tone, Vintage Gold-tone or Vintage Silver-tone, each with rhinestones.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eVintage-inspired design.\u003c\/strong\u003e Metal and rhinestones in a celestial shape that works for an evening out or a winter wedding.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eMake it a pair.\u003c\/strong\u003e Mix with our \u003ca href=\"\/products\/pearl-crystal-flower-hair-pin-set\"\u003eSimulated Pearl \u0026amp; Crystal Flower Hair Pin Set\u003c\/a\u003e. Buy any 2 items and 10% comes off automatically at checkout.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eA thoughtful gift idea\u003c\/strong\u003e for a bride, bridesmaid or friend.\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003cp\u003e\u003cstrong\u003eWhat you get:\u003c\/strong\u003e 3 hair pins with moon and star designs in the metal tone you choose, as shown in the photos.\u003c\/p\u003e\n\u003cp\u003e\u003cstrong\u003eSize:\u003c\/strong\u003e see the photos for scale. We’ll add exact measurements once we’ve measured our samples.\u003c\/p\u003e\n\u003cp\u003e\u003cstrong\u003eOrdering for a wedding?\u003c\/strong\u003e Order at least 4 weeks ahead.\u003c\/p\u003e\n\u003cp\u003e\u003cstrong\u003eGood to know:\u003c\/strong\u003e adult accessory, not a toy. Small parts: keep away from young children.\u003c\/p\u003e\n\u003cp\u003eFree US shipping on orders $60+ ($8 under $60) · 30-day returns on unworn items in original packaging.\u003c\/p\u003e\n\u003cp\u003eShips from our fulfillment partner overseas: processed in 1–3 business days, then typically 5–11 days in transit.\u003c\/p\u003e\n\u003c!-- hv-upsell v1 (Havendoa, adapted from hh-galixo v3): add-ons with quick view, delivery, trust. Remove from the hv-upsell v1 start marker to the \/hv-upsell v1 end marker to undo. --\u003e\n\u003cdiv class=\"hb\" data-handle=\"vintage-crystal-hair-pin-set-of-3\" hidden\u003e\u003cdiv class=\"hb-pay\"\u003e\u003c\/div\u003e\u003c\/div\u003e\n\u003cstyle\u003e\n.hb{--g:#7a5534;--line:#e3e3e3;font-size:15px;color:#2b2b2b}\n.hb-pay{display:flex;flex-wrap:wrap;justify-content:center;gap:6px;margin:12px 0 0}\n.hb-pay svg{width:38px;height:24px}\n.hb-add{margin:16px 0 0;border-radius:12px;background:#f5efe8;padding:12px}\n.hb-add-h{font-weight:700;font-size:17px;color:#1d1d1d;margin:0}\n.hb-add-p{font-size:14px;color:#555;margin:3px 0 6px;line-height:1.45}\n.hb-item{display:flex;align-items:center;gap:10px;background:#fff;border-radius:8px;padding:9px 10px;margin-top:7px;cursor:pointer}\n.hb-item input{width:20px;height:20px;accent-color:var(--g);flex:0 0 20px;margin:0}\n.hb-item img{width:54px;height:54px;object-fit:cover;border-radius:6px;flex:0 0 54px}\n.hb-item-t{flex:1;min-width:0;font-size:14px;line-height:1.35}\n.hb-item-t small{display:block;color:#6b6b6b;font-size:12.5px}\n.hb-item-p{text-align:right;white-space:nowrap;font-weight:700}\n.hb-item-p span{display:block;font-weight:400;font-size:12.5px;color:#c0392b}\n.hb-item-p s{color:#8a8a8a;margin-left:4px}\n.hb-ship{text-align:center;margin:16px 0 0;font-size:15px;line-height:1.5}\n.hb-ship b{color:var(--g)}\n.hb-trust{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:14px 0 18px;text-align:center;font-weight:700;font-size:13.5px;color:var(--g)}\n.hb-trust svg{display:block;margin:0 auto 5px;width:32px;height:32px}\n.hb-err{color:#c0392b;text-align:center;font-size:14px;margin-top:6px}\n.hb-item-a{color:inherit;text-decoration:underline;text-underline-offset:2px}\n.hb-item-img{display:block;flex:0 0 54px}\n.hb-ck{text-align:center;margin:0 0 16px;font-size:14px}\n.hb-ck a{color:var(--g);font-weight:600}\n.hq{position:fixed;inset:0;z-index:2147483000;background:rgba(0,0,0,.45);display:flex;align-items:center;justify-content:center;padding:16px}\n.hq[hidden]{display:none}\n.hq-box{background:#fff;border-radius:14px;max-width:780px;width:100%;max-height:90vh;overflow:auto;position:relative;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:28px;padding:30px 26px 24px;color:#1d1d1d;font-size:15px}\n.hq-box\u003ediv{min-width:0}\n.hq-x{position:absolute;top:8px;right:10px;background:none;border:0;font-size:28px;line-height:1;cursor:pointer;color:#444;padding:4px 8px}\n.hq-main{position:relative;aspect-ratio:1\/1;display:flex;align-items:center;justify-content:center}\n.hq-main img{max-width:100%;max-height:100%;object-fit:contain}\n.hq-nav{position:absolute;top:50%;transform:translateY(-50%);background:rgba(255,255,255,.9);border:0;border-radius:50%;width:36px;height:36px;font-size:24px;line-height:1;cursor:pointer;color:#333}\n.hq-prev{left:0}.hq-next{right:0}\n.hq-th{display:flex;gap:10px;overflow-x:auto;margin-top:14px;padding-bottom:4px}\n.hq-th button{flex:0 0 58px;padding:0 0 6px;border:0;border-bottom:2px solid transparent;background:none;cursor:pointer}\n.hq-th button.on{border-bottom-color:#1d1d1d}\n.hq-th img{width:58px;height:52px;object-fit:cover;border-radius:4px;display:block}\n.hq-t{font-size:21px;line-height:1.35;margin:0 30px 8px 0;font-weight:500}\n.hq-v{font-size:13.5px;color:#6b6b6b;margin:0 0 8px}\n.hq-p{font-size:20px;font-weight:700;margin:0 0 4px}\n.hq-p s{font-size:15px;color:#8a8a8a;font-weight:400;margin-left:6px}\n.hq-save{font-size:13.5px;color:#7a5534;margin:0 0 14px}\n.hq-ul{list-style:none;padding:0;margin:0 0 18px;font-size:14.5px;line-height:1.5}\n.hq-ul li{position:relative;padding-left:27px;margin:0 0 6px}\n.hq-ul li:before{content:\"\\2713\";position:absolute;left:0;top:2px;width:19px;height:19px;border-radius:4px;background:#a57549;color:#fff;font-size:13px;font-weight:700;line-height:19px;text-align:center}\n.hq-add{display:block;width:100%;border:0;border-radius:40px;background:#7a5534;color:#fff;font:inherit;font-weight:700;padding:12px;cursor:pointer;margin:0 0 14px}\n.hq-more{display:inline-block;color:#1d1d1d;font-weight:600;text-decoration:none;font-size:15.5px}\nbody.hq-lock{overflow:hidden}\n@media (max-width:640px){.hq-box{grid-template-columns:minmax(0,1fr);gap:14px;padding:42px 16px 18px}.hq-t{font-size:18px;margin-right:0}}\n\u003c\/style\u003e\n\u003cscript\u003e\n(() =\u003e {\n  const cs = document.currentScript;\n  const start = () =\u003e {\n  const root = (cs \u0026\u0026 cs.parentElement.querySelector('.hb')) || document.querySelector('.hb');\n  if (!root || root.dataset.ready) return;\n  root.dataset.ready = 1;\n  \/\/ what to offer under each product (handle -\u003e handles)\n  const PAIR = {\n    'duo-french-twist-set': ['elegant-claw-clip', 'pearl-crystal-flower-hair-pin-set', 'geometric-hair-clips-set-of-2'],\n    'tortoiseshell-french-hair-pin': ['elegant-claw-clip', 'pearl-crystal-flower-hair-pin-set'],\n    'elegant-claw-clip': ['tortoiseshell-french-hair-pin', 'geometric-hair-clips-set-of-2'],\n    'geometric-hair-clips-set-of-2': ['elegant-claw-clip', 'tortoiseshell-french-hair-pin'],\n    'pearl-crystal-flower-hair-pin-set': ['vintage-crystal-hair-pin-set-of-3', 'tortoiseshell-french-hair-pin'],\n    'vintage-crystal-hair-pin-set-of-3': ['pearl-crystal-flower-hair-pin-set', 'tortoiseshell-french-hair-pin'],\n    'heart-pearl-hair-clip': ['pearl-crystal-flower-hair-pin-set', 'vintage-crystal-hair-pin-set-of-3']\n  };\n  const HEAD = {};\n  \/\/ must match the store's automatic discounts: Buy 2 items 10%, Buy 3+ items 15%\n  const pctFor = n =\u003e n \u003e= 3 ? 15 : n \u003e= 2 ? 10 : 0;\n  const money = c =\u003e '$' + (c \/ 100).toFixed(2);\n  const info = document.querySelector('.product__info-container');\n  const form = info \u0026\u0026 info.querySelector('form[action*=\"\/cart\/add\"][data-type=\"add-to-cart-form\"]');\n  if (!info || !form) return;\n  const blockOf = el =\u003e { while (el \u0026\u0026 el.parentElement !== info) el = el.parentElement; return el; };\n  const buyBlock = blockOf(form);\n  const qtyInput = () =\u003e info.querySelector('.product-form__quantity input[name=\"quantity\"]') || document.querySelector('input[name=\"quantity\"]');\n  const mainQty = () =\u003e Math.max(1, parseInt((qtyInput() || {}).value, 10) || 1);\n  buyBlock.after(root);\n  root.hidden = false;\n  const pay = root.querySelector('.hb-pay'), footerPay = document.querySelector('.list-payment');\n  if (!pay.querySelector('svg') \u0026\u0026 footerPay) pay.innerHTML = [...footerPay.querySelectorAll('svg')].map(s =\u003e s.outerHTML).join('');\n  if (!pay.querySelector('svg')) pay.remove();\n  const icon = d =\u003e '\u003csvg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.7\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\u003e' + d + '\u003c\/svg\u003e';\n  root.insertAdjacentHTML('beforeend',\n    '\u003cdiv class=\"hb-add\" hidden\u003e\u003c\/div\u003e' +\n    '\u003cdiv class=\"hb-ship\"\u003e\u003cb\u003eFree US shipping\u003c\/b\u003e on orders $60+.\u003cbr\u003eTypical delivery: 5–11 days after dispatch.\u003c\/div\u003e' +\n    '\u003cdiv class=\"hb-trust\"\u003e' +\n    '\u003cdiv\u003e' + icon('\u003cpath d=\"M3 7h11v8H3zM14 10h4l3 3v2h-7\"\/\u003e\u003ccircle cx=\"7\" cy=\"17\" r=\"1.6\"\/\u003e\u003ccircle cx=\"17\" cy=\"17\" r=\"1.6\"\/\u003e') + 'Free Shipping $60+\u003c\/div\u003e' +\n    '\u003cdiv\u003e' + icon('\u003cpath d=\"M4 12a8 8 0 1 0 2.4-5.7\"\/\u003e\u003cpath d=\"M4 4v4h4\"\/\u003e') + '30-Day Returns\u003c\/div\u003e' +\n    '\u003cdiv\u003e' + icon('\u003crect x=\"5\" y=\"11\" width=\"14\" height=\"9\" rx=\"2\"\/\u003e\u003cpath d=\"M8 11V8a4 4 0 0 1 8 0v3\"\/\u003e') + 'Secure Checkout\u003c\/div\u003e' +\n    '\u003c\/div\u003e' +\n    '\u003cp class=\"hb-ck\"\u003e\u003ca href=\"\/blogs\/hair-guides\/how-to-use-a-french-hair-pin\"\u003eNew to French pins? Read our step-by-step guide \u0026rarr;\u003c\/a\u003e\u003c\/p\u003e');\n  const handles = PAIR[root.dataset.handle] || [];\n  let extras = [];\n  const add = root.querySelector('.hb-add');\n  const picks = () =\u003e [...add.querySelectorAll('input:checked')].map(c =\u003e extras[+c.dataset.x]);\n  const paint = () =\u003e {\n    const n = mainQty() + picks().length;\n    add.querySelectorAll('.hb-item').forEach(el =\u003e {\n      const e = extras[+el.dataset.x], on = el.querySelector('input').checked;\n      const pct = pctFor(on ? n : n + 1);\n      el.querySelector('.hb-item-p').innerHTML = (pct ? '\u003cspan\u003e-' + pct + '%\u003cs\u003e' + money(e.v.price) + '\u003c\/s\u003e\u003c\/span\u003e' : '') + money(e.v.price - Math.floor(e.v.price * pct \/ 100));\n    });\n  };\n  Promise.all(handles.map(h =\u003e fetch('\/products\/' + h + '.js').then(r =\u003e r.ok ? r.json() : null).catch(() =\u003e null))).then(list =\u003e {\n    extras = list.filter(Boolean).map(a =\u003e { const v = a.variants.find(x =\u003e x.available); return v \u0026\u0026 { a, v }; }).filter(Boolean);\n    if (!extras.length) return;\n    const img = s =\u003e s ? s + (s.includes('?') ? '\u0026' : '?') + 'width=120' : '';\n    const link = e =\u003e '\/products\/' + e.a.handle + '?variant=' + e.v.id;\n    add.innerHTML = '\u003cp class=\"hb-add-h\"\u003e' + (HEAD[root.dataset.handle] || 'Complete the look') + '\u003c\/p\u003e' +\n      '\u003cp class=\"hb-add-p\"\u003eCheck the box to add it to this order. 2 items save 10%, 3 or more save 15%, applied automatically at checkout.\u003c\/p\u003e' +\n      extras.map((e, i) =\u003e '\u003clabel class=\"hb-item\" data-x=\"' + i + '\"\u003e\u003cinput type=\"checkbox\" data-x=\"' + i + '\"\u003e' +\n        (e.a.featured_image ? '\u003ca class=\"hb-item-img\" href=\"' + link(e) + '\" tabindex=\"-1\" aria-hidden=\"true\"\u003e\u003cimg src=\"' + img(e.a.featured_image) + '\" alt=\"\" loading=\"lazy\"\u003e\u003c\/a\u003e' : '') +\n        '\u003cspan class=\"hb-item-t\"\u003e\u003ca class=\"hb-item-a\" href=\"' + link(e) + '\"\u003e' + e.a.title.split(' – ')[0] + '\u003c\/a\u003e' + (e.a.variants.length \u003e 1 ? '\u003csmall\u003e' + e.v.title.split(' \/ ')[0] + '\u003c\/small\u003e' : '') + '\u003c\/span\u003e' +\n        '\u003cspan class=\"hb-item-p\"\u003e\u003c\/span\u003e\u003c\/label\u003e').join('');\n    add.hidden = false;\n    add.addEventListener('click', ev =\u003e {\n      const a = ev.target.closest('.hb-item-a, .hb-item-img');\n      if (!a || !window.hhQV) return;\n      ev.preventDefault();\n      const i = +a.closest('.hb-item').dataset.x, e = extras[i], cb = add.querySelector('input[data-x=\"' + i + '\"]');\n      window.hhQV({ a: e.a, v: e.v, from: a, note: 'Add it to this order: 2 items save 10%, 3 or more save 15% at checkout.', addLabel: cb.checked ? 'Remove from this order' : 'Add to this order', onAdd: () =\u003e { cb.checked = !cb.checked; cb.dispatchEvent(new Event('change', { bubbles: true })); } });\n    });\n    add.addEventListener('change', paint);\n    document.addEventListener('change', e =\u003e { if (e.target.name === 'quantity') setTimeout(paint, 50); });\n    paint();\n  });\n  document.addEventListener('submit', async e =\u003e {\n    if (e.target !== form || !picks().length) return;\n    e.preventDefault(); e.stopImmediatePropagation();\n    const btn = form.querySelector('[type=\"submit\"]'); if (btn) btn.setAttribute('aria-disabled', 'true');\n    const items = [{ id: +form.querySelector('input[name=\"id\"]').value, quantity: mainQty() }, ...picks().map(x =\u003e ({ id: x.v.id, quantity: 1 }))];\n    let r = null;\n    try { r = await fetch('\/cart\/add.js', { method: 'POST', headers: { 'Content-Type': 'application\/json' }, body: JSON.stringify({ items }) }); } catch (x) {}\n    if (r \u0026\u0026 r.ok) { location.href = '\/cart'; return; }\n    if (btn) btn.removeAttribute('aria-disabled');\n    let err = root.querySelector('.hb-err'); if (!err) { err = document.createElement('p'); err.className = 'hb-err'; add.after(err); }\n    err.textContent = (r \u0026\u0026 (await r.json().catch(() =\u003e ({}))).description) || 'Could not add to cart. Please try again.';\n  }, true);\n  window.addEventListener('pageshow', e =\u003e { if (e.persisted) { const b = form.querySelector('[type=\"submit\"]'); if (b) b.removeAttribute('aria-disabled'); } });\n  };\n  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', start); else start();\n})();\n\u003c\/script\u003e\n\u003c!-- \/hv-upsell v1 --\u003e\n\u003c!-- hv-extra v1 (Havendoa, adapted from hh-downsell v2 + hh-nopantry v2): shared quick view, single\/duo switch, French Twist Kit. Remove from the hv-extra v1 start marker to the \/hv-extra v1 end marker to undo. --\u003e\n\u003cdiv class=\"hd\" data-handle=\"vintage-crystal-hair-pin-set-of-3\" hidden\u003e\u003c\/div\u003e\u003cdiv class=\"hn\" data-handle=\"vintage-crystal-hair-pin-set-of-3\" hidden\u003e\u003c\/div\u003e\n\u003cstyle\u003e\n.hd{--g:#7a5534;margin:6px 0 18px;border:1px solid #e5d6c6;border-radius:12px;padding:12px;background:#fff;font-size:15px;color:#2b2b2b}\n.hd-h{font-weight:700;font-size:17px;margin:0}\n.hd-p{font-size:14px;color:#555;margin:3px 0 8px;line-height:1.45}\n.hd-card{display:flex;gap:10px;align-items:flex-start;border-top:1px solid #eee;padding:10px 0 4px}\n.hd-card img{width:62px;height:62px;object-fit:cover;border-radius:8px;flex:0 0 62px}\n.hd-b{flex:1;min-width:0;font-size:13.5px;line-height:1.4}\n.hd-b a.hd-t{font-weight:700;color:#1d1d1d;text-decoration:underline;text-underline-offset:2px;font-size:14.5px}\n.hd-img{display:block;flex:0 0 62px}\n.hd-b .hd-in{color:#2f6b52}\n.hd-b .hd-out{color:#8a5a2b}\n.hd-btn{margin-top:6px;border:1.5px solid var(--g);background:#fff;color:var(--g);border-radius:30px;padding:7px 14px;font:inherit;font-weight:700;font-size:13.5px;cursor:pointer}\n.hd-btn:disabled{opacity:.6}\n.hn{--g:#7a5534;margin:6px 0 18px;border:2px solid var(--g);border-radius:14px;padding:14px;background:#f8f2ec;font-size:15px;color:#2b2b2b}\n.hn-k{font-size:12px;letter-spacing:.08em;text-transform:uppercase;font-weight:700;color:#c75b2a;margin:0}\n.hn-h{font-weight:700;font-size:18px;margin:2px 0 4px;color:var(--g)}\n.hn-p{font-size:14px;color:#555;margin:0 0 10px;line-height:1.45}\n.hn-list{display:grid;gap:8px;margin:0 0 10px}\n.hn-row{display:flex;gap:10px;align-items:center;background:#fff;border-radius:10px;padding:8px}\n.hn-row img{width:48px;height:48px;object-fit:cover;border-radius:6px;flex:0 0 48px}\n.hn-row span{flex:1;min-width:0;font-size:13.5px;line-height:1.35}\n.hn-row span small{display:block;color:#6b6b6b}\n.hn-row b{white-space:nowrap;font-size:14px}\n.hn-sum{display:flex;justify-content:space-between;font-size:14px;margin:2px 2px 0}\n.hn-sum.hn-you{font-weight:700;font-size:16px;color:var(--g)}\n.hn-btn{display:block;width:100%;margin-top:10px;border:0;border-radius:40px;background:var(--g);color:#fff;font:inherit;font-weight:700;font-size:16px;padding:13px;cursor:pointer}\n.hn-btn:disabled{opacity:.6}\n.hn-a{color:inherit;text-decoration:underline;text-underline-offset:2px}\n.hn-img{display:block;flex:0 0 48px}\n.hn-note{font-size:12.5px;color:#6b6b6b;margin:8px 0 0;text-align:center}\n\u003c\/style\u003e\n\u003cscript\u003e\n(() =\u003e {\n  const cs = document.currentScript;\n  if (!window.hhQV) window.hhQV = (() =\u003e {\n    const qv = document.createElement('div');\n    qv.className = 'hq'; qv.hidden = true;\n    document.body.appendChild(qv);\n    const px = (s, w) =\u003e s ? s + (s.includes('?') ? '\u0026' : '?') + 'width=' + w : '';\n    const esc = s =\u003e String(s).replace(\/[\u0026\u003c\u003e\"]\/g, c =\u003e ({ '\u0026': '\u0026amp;', '\u003c': '\u0026lt;', '\u003e': '\u0026gt;', '\"': '\u0026quot;' }[c]));\n    const cash = c =\u003e '$' + (c \/ 100).toFixed(2);\n    const fileOf = s =\u003e String(s || '').split('?')[0].split('\/').pop();\n    const bullets = html =\u003e {\n      const d = new DOMParser().parseFromString(html || '', 'text\/html');\n      d.querySelectorAll('script, style, .hb, .hd, .hn').forEach(x =\u003e x.remove());\n      let li = [...d.querySelectorAll('li')].map(x =\u003e x.textContent.replace(\/\\s+\/g, ' ').trim()).filter(Boolean);\n      if (!li.length) li = [...d.querySelectorAll('p')].map(x =\u003e x.textContent.trim()).filter(Boolean).slice(0, 1);\n      return li.slice(0, 5).map(t =\u003e t.length \u003e 95 ? t.slice(0, 92).replace(\/[\\s,.;:]+\\S*$\/, '') + '…' : t);\n    };\n    let back = null;\n    const close = () =\u003e { qv.hidden = true; document.body.classList.remove('hq-lock'); if (back) back.focus(); };\n    qv.addEventListener('click', ev =\u003e { if (ev.target === qv) close(); });\n    document.addEventListener('keydown', ev =\u003e {\n      if (qv.hidden) return;\n      if (ev.key === 'Escape') close();\n      if (ev.key === 'ArrowLeft') { const b = qv.querySelector('.hq-prev'); if (b) b.click(); }\n      if (ev.key === 'ArrowRight') { const b = qv.querySelector('.hq-next'); if (b) b.click(); }\n    });\n    return o =\u003e {\n      const a = o.a, v = o.v;\n      back = o.from || null;\n      const imgs = (a.images \u0026\u0026 a.images.length) ? a.images : [a.featured_image];\n      let k = v.featured_image ? Math.max(0, imgs.findIndex(s =\u003e fileOf(s) === fileOf(v.featured_image.src))) : 0;\n      qv.innerHTML = '\u003cdiv class=\"hq-box\" role=\"dialog\" aria-modal=\"true\" aria-label=\"' + esc(a.title) + '\"\u003e' +\n        '\u003cbutton type=\"button\" class=\"hq-x\" aria-label=\"Close\"\u003e\u0026times;\u003c\/button\u003e' +\n        '\u003cdiv\u003e\u003cdiv class=\"hq-main\"\u003e\u003cimg alt=\"\"\u003e' +\n        (imgs.length \u003e 1 ? '\u003cbutton type=\"button\" class=\"hq-nav hq-prev\" aria-label=\"Previous image\"\u003e\u0026lsaquo;\u003c\/button\u003e\u003cbutton type=\"button\" class=\"hq-nav hq-next\" aria-label=\"Next image\"\u003e\u0026rsaquo;\u003c\/button\u003e' : '') +\n        '\u003c\/div\u003e' + (imgs.length \u003e 1 ? '\u003cdiv class=\"hq-th\"\u003e' + imgs.map((s, j) =\u003e '\u003cbutton type=\"button\" data-j=\"' + j + '\" aria-label=\"Image ' + (j + 1) + '\"\u003e\u003cimg src=\"' + px(s, 120) + '\" alt=\"\" loading=\"lazy\"\u003e\u003c\/button\u003e').join('') + '\u003c\/div\u003e' : '') + '\u003c\/div\u003e' +\n        '\u003cdiv\u003e\u003ch2 class=\"hq-t\"\u003e' + esc(a.title) + '\u003c\/h2\u003e' +\n        (a.variants.length \u003e 1 ? '\u003cp class=\"hq-v\"\u003e' + esc(v.title.split(' \/ ')[0]) + '\u003c\/p\u003e' : '') +\n        '\u003cp class=\"hq-p\"\u003e' + cash(v.price) + (v.compare_at_price \u003e v.price ? '\u003cs\u003e' + cash(v.compare_at_price) + '\u003c\/s\u003e' : '') + '\u003c\/p\u003e' +\n        (o.note ? '\u003cp class=\"hq-save\"\u003e' + esc(o.note) + '\u003c\/p\u003e' : '') +\n        '\u003cul class=\"hq-ul\"\u003e' + bullets(a.description).map(t =\u003e '\u003cli\u003e' + esc(t) + '\u003c\/li\u003e').join('') + '\u003c\/ul\u003e' +\n        (o.onAdd ? '\u003cbutton type=\"button\" class=\"hq-add\"\u003e' + esc(o.addLabel || 'Add to cart') + '\u003c\/button\u003e' : '') +\n        '\u003ca class=\"hq-more\" href=\"\/products\/' + a.handle + '?variant=' + v.id + '\"\u003eView more details \u003cspan aria-hidden=\"true\"\u003e\u0026rarr;\u003c\/span\u003e\u003c\/a\u003e\u003c\/div\u003e\u003c\/div\u003e';\n      const main = qv.querySelector('.hq-main img'), th = [...qv.querySelectorAll('.hq-th button')];\n      const show = j =\u003e { k = (j + imgs.length) % imgs.length; main.src = px(imgs[k], 800); th.forEach((b, x) =\u003e b.classList.toggle('on', x === k)); };\n      th.forEach(b =\u003e b.addEventListener('click', () =\u003e show(+b.dataset.j)));\n      const prev = qv.querySelector('.hq-prev'), next = qv.querySelector('.hq-next');\n      if (prev) prev.addEventListener('click', () =\u003e show(k - 1));\n      if (next) next.addEventListener('click', () =\u003e show(k + 1));\n      qv.querySelector('.hq-x').addEventListener('click', close);\n      const addBtn = qv.querySelector('.hq-add');\n      if (addBtn) addBtn.addEventListener('click', () =\u003e { close(); o.onAdd(); });\n      show(k);\n      qv.hidden = false;\n      document.body.classList.add('hq-lock');\n      qv.querySelector('.hq-x').focus();\n    };\n  })();\n  \/\/ single \u003c-\u003e duo switch, per product page\n  const SWITCH = {\n    'duo-french-twist-set': { h: 'Just need one pin?', p: 'Start with a single pin and add a second one later.', items: [{ handle: 'tortoiseshell-french-hair-pin', name: 'French Hair Pin', inc: '1 French Hair Pin in the color you choose', out: 'the second pin (the Duo is $65, less than two single pins)' }] },\n    'tortoiseshell-french-hair-pin': { h: 'Want a spare? Get the Duo', p: 'One pin for a quick twist, two for a fuller, more secure bun. $65 for two: less than two single pins, even with the 2-item discount.', items: [{ handle: 'duo-french-twist-set', name: 'Duo French Twist Set', inc: '2 French Hair Pins in the color you choose', out: '' }] }\n  };\n  \/\/ French Twist Kit, shown on these pages\n  const KIT_ON = ['duo-french-twist-set', 'tortoiseshell-french-hair-pin', 'elegant-claw-clip'];\n  const SET = [\n    { h: 'duo-french-twist-set', name: 'Duo French Twist Set', note: 'two French pins for the twist' },\n    { h: 'elegant-claw-clip', name: 'Elegant Claw Clip', note: 'for quick half-up days' },\n    { h: 'pearl-crystal-flower-hair-pin-set', name: 'Simulated Pearl \u0026 Crystal Flower Pins', note: 'for weddings and special days' }\n  ];\n  const PCT = 15; \/\/ store's automatic discount for 3+ items\n  const money = c =\u003e '$' + (c \/ 100).toFixed(2);\n  const img = (s, w) =\u003e s ? s + (s.includes('?') ? '\u0026' : '?') + 'width=' + w : '';\n  const go = async items =\u003e { const r = await fetch('\/cart\/add.js', { method: 'POST', headers: { 'Content-Type': 'application\/json' }, body: JSON.stringify({ items }) }); return r.ok; };\n  const start = () =\u003e {\n    const d = (cs \u0026\u0026 cs.parentElement.querySelector('.hd')) || document.querySelector('.hd');\n    const n = (cs \u0026\u0026 cs.parentElement.querySelector('.hn')) || document.querySelector('.hn');\n    if (!d || d.dataset.ready) return;\n    d.dataset.ready = 1;\n    const handle = d.dataset.handle;\n    const anchor = () =\u003e document.querySelector('.hb:not([hidden])') || (document.querySelector('.product__info-container product-form') || {}).parentElement;\n    const sw = SWITCH[handle];\n    if (sw) Promise.all(sw.items.map(o =\u003e fetch('\/products\/' + o.handle + '.js').then(r =\u003e r.ok ? r.json() : null).catch(() =\u003e null))).then(list =\u003e {\n      const rows = sw.items.map((o, i) =\u003e ({ o, p: list[i] })).filter(x =\u003e x.p \u0026\u0026 x.p.available);\n      if (!rows.length) return;\n      d.innerHTML = '\u003cp class=\"hd-h\"\u003e' + sw.h + '\u003c\/p\u003e\u003cp class=\"hd-p\"\u003e' + sw.p + '\u003c\/p\u003e' + rows.map((x, i) =\u003e {\n        const v = x.p.variants.find(v =\u003e v.available), lk = '\/products\/' + x.o.handle + '?variant=' + v.id;\n        return '\u003cdiv class=\"hd-card\" data-i=\"' + i + '\"\u003e' + (x.p.featured_image ? '\u003ca class=\"hd-img\" href=\"' + lk + '\"\u003e\u003cimg src=\"' + img(x.p.featured_image, 140) + '\" alt=\"\"\u003e\u003c\/a\u003e' : '') +\n          '\u003cdiv class=\"hd-b\"\u003e\u003ca class=\"hd-t\" href=\"' + lk + '\"\u003e' + x.o.name + ' · ' + money(v.price) + (v.compare_at_price \u003e v.price ? ' \u003cs\u003e' + money(v.compare_at_price) + '\u003c\/s\u003e' : '') + '\u003c\/a\u003e\u003cbr\u003e' +\n          '\u003cspan class=\"hd-in\"\u003eIncludes: ' + x.o.inc + '.\u003c\/span\u003e' + (x.o.out ? '\u003cbr\u003e\u003cspan class=\"hd-out\"\u003eNot included: ' + x.o.out + '.\u003c\/span\u003e' : '') + '\u003cbr\u003e' +\n          '\u003cbutton type=\"button\" class=\"hd-btn\" data-v=\"' + v.id + '\"\u003eAdd to cart — ' + money(v.price) + '\u003c\/button\u003e' + (x.p.variants.length \u003e 1 ? ' \u003csmall\u003e(' + v.title.split(' \/ ')[0] + '; pick another color on its page)\u003c\/small\u003e' : '') + '\u003c\/div\u003e\u003c\/div\u003e';\n      }).join('');\n      const a = anchor(); if (a) a.after(d);\n      d.hidden = false;\n      d.addEventListener('click', ev =\u003e {\n        const l = ev.target.closest('a.hd-t, a.hd-img'); if (!l) return; ev.preventDefault();\n        const card = l.closest('.hd-card'), x = rows[+card.dataset.i], b = card.querySelector('.hd-btn');\n        window.hhQV({ a: x.p, v: x.p.variants.find(v =\u003e v.available), from: l, note: 'Includes: ' + x.o.inc + '.', addLabel: b.textContent, onAdd: () =\u003e b.click() });\n      });\n      d.querySelectorAll('.hd-btn').forEach(b =\u003e b.addEventListener('click', async () =\u003e { b.disabled = true; b.textContent = 'Adding…'; if (await go([{ id: +b.dataset.v, quantity: 1 }])) location.href = '\/cart'; else { b.disabled = false; b.textContent = 'Could not add. Try again'; } }));\n    });\n    if (n \u0026\u0026 KIT_ON.includes(handle)) Promise.all(SET.map(s =\u003e fetch('\/products\/' + s.h + '.js').then(r =\u003e r.ok ? r.json() : null).catch(() =\u003e null))).then(list =\u003e {\n      const rows = SET.map((s, i) =\u003e { const p = list[i]; if (!p) return null; const v = p.variants.find(v =\u003e v.available); return v ? { s, p, v } : null; });\n      if (rows.some(r =\u003e !r)) return;\n      const sum = rows.reduce((a, r) =\u003e a + r.v.price, 0), you = sum - Math.floor(sum * PCT \/ 100);\n      const lk = r =\u003e '\/products\/' + r.s.h + '?variant=' + r.v.id;\n      n.innerHTML = '\u003cp class=\"hn-k\"\u003eThe French Twist Kit\u003c\/p\u003e\u003cp class=\"hn-h\"\u003eEverything for an effortless updo.\u003c\/p\u003e' +\n        '\u003cp class=\"hn-p\"\u003eTwo French pins for the twist, a claw clip for quick half-up days, and simulated pearl flower pins for special occasions.\u003c\/p\u003e' +\n        '\u003cdiv class=\"hn-list\"\u003e' + rows.map((r, i) =\u003e '\u003cdiv class=\"hn-row\" data-i=\"' + i + '\"\u003e' + (r.p.featured_image ? '\u003ca class=\"hn-img\" href=\"' + lk(r) + '\"\u003e\u003cimg src=\"' + img(r.p.featured_image, 100) + '\" alt=\"\"\u003e\u003c\/a\u003e' : '') +\n          '\u003cspan\u003e\u003ca class=\"hn-a\" href=\"' + lk(r) + '\"\u003e' + r.s.name + '\u003c\/a\u003e\u003csmall\u003e' + r.s.note + (r.p.variants.length \u003e 1 ? ' · ' + r.v.title.split(' \/ ')[0] : '') + '\u003c\/small\u003e\u003c\/span\u003e\u003cb\u003e' + money(r.v.price) + '\u003c\/b\u003e\u003c\/div\u003e').join('') + '\u003c\/div\u003e' +\n        '\u003cdiv class=\"hn-sum\"\u003e\u003cspan\u003eBought separately\u003c\/span\u003e\u003cspan\u003e' + money(sum) + '\u003c\/span\u003e\u003c\/div\u003e' +\n        '\u003cdiv class=\"hn-sum hn-you\"\u003e\u003cspan\u003eWith ' + PCT + '% off 3+ items\u003c\/span\u003e\u003cspan\u003e' + money(you) + '\u003c\/span\u003e\u003c\/div\u003e' +\n        '\u003cbutton type=\"button\" class=\"hn-btn\"\u003eAdd all ' + rows.length + ' to cart — ' + money(you) + ' at checkout\u003c\/button\u003e' +\n        '\u003cp class=\"hn-note\"\u003eThe ' + PCT + '% applies automatically at checkout and can’t be combined with other discount codes. Items may arrive in separate parcels, each with its own tracking number.\u003c\/p\u003e';\n      const a = (d.hidden ? null : d) || anchor(); if (a) a.after(n);\n      n.hidden = false;\n      const btn = n.querySelector('.hn-btn');\n      const pickColor = () =\u003e { const i = document.querySelector('variant-picker input:checked, variant-selects input:checked, variant-radios input:checked'); return i ? i.value : null; };\n      const pickDuo = r =\u003e { const c = pickColor(); return (c \u0026\u0026 r.p.variants.find(v =\u003e v.available \u0026\u0026 v.title.split(' \/ ')[0] === c)) || r.v; };\n      const relabel = () =\u003e { rows.forEach((r, i) =\u003e { if (r.s.h !== 'duo-french-twist-set' || r.p.variants.length \u003c 2) return; const el = n.querySelector('.hn-row[data-i=\"' + i + '\"] small'); if (el) el.textContent = r.s.note + ' · ' + pickDuo(r).title.split(' \/ ')[0]; }); };\n      document.addEventListener('change', () =\u003e setTimeout(relabel, 200)); relabel();\n      btn.addEventListener('click', async () =\u003e { btn.disabled = true; btn.textContent = 'Adding…'; if (await go(rows.map(x =\u003e ({ id: (x.s.h === 'duo-french-twist-set' ? pickDuo(x) : x.v).id, quantity: 1 })))) location.href = '\/cart'; else { btn.disabled = false; btn.textContent = 'Could not add. Try again'; } });\n      n.addEventListener('click', ev =\u003e {\n        const l = ev.target.closest('a.hn-a, a.hn-img'); if (!l) return; ev.preventDefault();\n        const r = rows[+l.closest('.hn-row').dataset.i];\n        window.hhQV({ a: r.p, v: r.v, from: l, note: 'Part of the French Twist Kit: ' + r.s.note + '.', addLabel: btn.textContent, onAdd: () =\u003e btn.click() });\n      });\n    });\n  };\n  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', () =\u003e setTimeout(start, 50)); else setTimeout(start, 50);\n})();\n\u003c\/script\u003e\n\u003c!-- \/hv-extra v1 --\u003e\n\u003c!-- hv-tiers v1 (Havendoa): \"Buy more, save more\" 1\/2\/3 items, replaces the quantity box. Must match automatic discounts (2 items 10%, 3+ items 15%). Remove from the hv-tiers v1 start marker to the \/hv-tiers v1 end marker to undo. --\u003e\n\u003cdiv class=\"hv-tiers\" data-handle=\"vintage-crystal-hair-pin-set-of-3\" hidden\u003e\u003c\/div\u003e\n\u003cstyle\u003e\n.hv-tiers{margin:4px 0 16px;background:#f5efe8;border:1px solid #e5d6c6;border-radius:14px;padding:12px 12px 6px;font-size:15px;color:#2b2b2b}\n.hv-tiers__h{font-weight:700;font-size:16px;margin:0 0 8px;color:#7a5534}\n.hv-tier{display:flex;align-items:center;gap:10px;background:#fff;border:1px solid #eadfd3;border-radius:10px;padding:10px 12px;margin:0 0 8px;cursor:pointer}\n.hv-tier.is-on{box-shadow:0 0 0 2px #7a5534;border-color:#7a5534}\n.hv-tier input{width:20px;height:20px;accent-color:#7a5534;margin:0;flex:0 0 20px}\n.hv-tier__t{flex:1;min-width:0;line-height:1.3}\n.hv-tier__t small{display:block;color:#6b6b6b;font-size:12.5px}\n.hv-tier__b{display:inline-block;margin-left:6px;background:#7a5534;color:#fff;border-radius:20px;font-size:11.5px;font-weight:700;padding:2px 8px;vertical-align:middle}\n.hv-tier__p{text-align:right;font-weight:700;white-space:nowrap}\n.hv-tier__p s{display:block;font-weight:400;font-size:12.5px;color:#8a8a8a}\n.hv-tiers__note{font-size:12.5px;color:#6b6b6b;margin:0 2px 6px}\n\u003c\/style\u003e\n\u003cscript\u003e\n(() =\u003e {\n  const cs = document.currentScript;\n  const TIERS = [[1, 0, ''], [2, 10, 'Save 10%'], [3, 15, 'Save 15%']];\n  const money = c =\u003e '$' + (c \/ 100).toFixed(2);\n  const start = () =\u003e {\n    const box = (cs \u0026\u0026 cs.parentElement.querySelector('.hv-tiers')) || document.querySelector('.hv-tiers');\n    if (!box || box.dataset.ready) return;\n    box.dataset.ready = 1;\n    const info = document.querySelector('.product__info-container');\n    const form = info \u0026\u0026 info.querySelector('form[action*=\"\/cart\/add\"][data-type=\"add-to-cart-form\"]');\n    if (!info || !form) return;\n    const blockOf = el =\u003e { while (el \u0026\u0026 el.parentElement !== info) el = el.parentElement; return el; };\n    const qtyBox = info.querySelector('.product-form__quantity');\n    const anchor = qtyBox ? blockOf(qtyBox) : blockOf(form);\n    const qty = () =\u003e info.querySelector('input[name=\"quantity\"]') || document.querySelector('input[name=\"quantity\"]');\n    fetch('\/products\/' + box.dataset.handle + '.js').then(r =\u003e r.ok ? r.json() : null).then(p =\u003e {\n      if (!p) return;\n      const cur = () =\u003e { const id = +(form.querySelector('input[name=\"id\"]') || {}).value; return p.variants.find(v =\u003e v.id === id) || p.variants.find(v =\u003e v.available) || p.variants[0]; };\n      const render = () =\u003e {\n        const v = cur(), on = box.querySelector('input:checked'), pick = on ? +on.value : Math.max(1, Math.min(3, parseInt((qty() || {}).value, 10) || 1));\n        box.innerHTML = '\u003cp class=\"hv-tiers__h\"\u003eBuy more, save more\u003c\/p\u003e' + TIERS.map(([n, pct, badge]) =\u003e {\n          const full = v.price * n, you = full - Math.floor(full * pct \/ 100);\n          return '\u003clabel class=\"hv-tier' + (n === pick ? ' is-on' : '') + '\"\u003e\u003cinput type=\"radio\" name=\"hv-tier\" value=\"' + n + '\"' + (n === pick ? ' checked' : '') + '\u003e' +\n            '\u003cspan class=\"hv-tier__t\"\u003e\u003cb\u003e' + n + (n === 1 ? ' item' : ' items') + '\u003c\/b\u003e' + (badge ? '\u003cspan class=\"hv-tier__b\"\u003e' + badge + '\u003c\/span\u003e' : '') + (p.variants.length \u003e 1 ? '\u003csmall\u003e' + v.title.split(' \/ ')[0] + (n \u003e 1 ? ' x ' + n : '') + '\u003c\/small\u003e' : '') + '\u003c\/span\u003e' +\n            '\u003cspan class=\"hv-tier__p\"\u003e' + money(you) + (pct ? '\u003cs\u003e' + money(full) + '\u003c\/s\u003e' : '') + '\u003c\/span\u003e\u003c\/label\u003e';\n        }).join('') + '\u003cp class=\"hv-tiers__note\"\u003eWant different colors? Add each one to your cart: the discount counts every item in your order.\u003c\/p\u003e';\n      };\n      const setQty = n =\u003e { const q = qty(); if (q \u0026\u0026 q.value !== String(n)) { q.value = n; q.dispatchEvent(new Event('change', { bubbles: true })); } };\n      anchor.before(box);\n      if (qtyBox) anchor.style.display = 'none';\n      render(); box.hidden = false;\n      box.addEventListener('change', e =\u003e { if (e.target.name !== 'hv-tier') return; setQty(+e.target.value); render(); });\n      \/\/ the theme resets quantity to 1 on every variant change; put the tier back and refresh prices\n      document.addEventListener('change', e =\u003e { if (box.contains(e.target)) return; if (e.target \u0026\u0026 e.target.name === 'id') setTimeout(() =\u003e { const t = box.querySelector('input:checked'); if (t) setQty(+t.value); render(); }, 60); });\n      window.addEventListener('pageshow', () =\u003e setTimeout(() =\u003e { const t = box.querySelector('input:checked'); if (t) setQty(+t.value); }, 0));\n    });\n  };\n  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', start); else start();\n})();\n\u003c\/script\u003e\n\u003c!-- \/hv-tiers v1 --\u003e","brand":"Havendoa","offers":[{"title":"Gold-tone","offer_id":49283867934903,"sku":"HV-VCS-GLD","price":44.0,"currency_code":"USD","in_stock":true},{"title":"Silver-tone","offer_id":49284519985335,"sku":"HV-VCS-SLV","price":44.0,"currency_code":"USD","in_stock":true},{"title":"Rose Gold-tone","offer_id":49284520018103,"sku":"HV-VCS-RSG","price":44.0,"currency_code":"USD","in_stock":true},{"title":"Vintage Gold-tone","offer_id":49284520050871,"sku":"HV-VCS-VGD","price":44.0,"currency_code":"USD","in_stock":true},{"title":"Vintage Silver-tone","offer_id":49284520083639,"sku":"HV-VCS-VSV","price":44.0,"currency_code":"USD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0761\/4998\/1367\/files\/Sfab1d796bb904d378aa80fd245c85b64i.webp?v=1790938313"},{"product_id":"duo-french-twist-set","title":"Duo French Twist Set – 2 Matching French Hair Pins","description":"\u003ch2\u003eTwo pins, two ways to wear them\u003c\/h2\u003e\n\u003cp\u003eOne French pin is designed for a simple twist. On long or thick hair, cross in the second pin from the other side for extra hold. On other days, keep the spare in your work bag, so you’re never hunting for a hair tie.\u003c\/p\u003e\n\u003cp\u003e\u003cstrong\u003eTwo pins, one price.\u003c\/strong\u003e The Duo is $65. Two single French Hair Pins are $76 if bought separately, or $68.40 with our automatic 2-item discount. Want two different colors? Choose two \u003ca href=\"\/products\/tortoiseshell-french-hair-pin\"\u003esingle French Hair Pins\u003c\/a\u003e instead.\u003c\/p\u003e\n\u003c!-- hv-upsell v1 (Havendoa, adapted from hh-galixo v3): add-ons with quick view, delivery, trust. Remove from the hv-upsell v1 start marker to the \/hv-upsell v1 end marker to undo. --\u003e\n\u003cdiv class=\"hb\" data-handle=\"duo-french-twist-set\" hidden\u003e\u003cdiv class=\"hb-pay\"\u003e\u003c\/div\u003e\u003c\/div\u003e\n\u003cstyle\u003e\n.hb{--g:#7a5534;--line:#e3e3e3;font-size:15px;color:#2b2b2b}\n.hb-pay{display:flex;flex-wrap:wrap;justify-content:center;gap:6px;margin:12px 0 0}\n.hb-pay svg{width:38px;height:24px}\n.hb-add{margin:16px 0 0;border-radius:12px;background:#f5efe8;padding:12px}\n.hb-add-h{font-weight:700;font-size:17px;color:#1d1d1d;margin:0}\n.hb-add-p{font-size:14px;color:#555;margin:3px 0 6px;line-height:1.45}\n.hb-item{display:flex;align-items:center;gap:10px;background:#fff;border-radius:8px;padding:9px 10px;margin-top:7px;cursor:pointer}\n.hb-item input{width:20px;height:20px;accent-color:var(--g);flex:0 0 20px;margin:0}\n.hb-item img{width:54px;height:54px;object-fit:cover;border-radius:6px;flex:0 0 54px}\n.hb-item-t{flex:1;min-width:0;font-size:14px;line-height:1.35}\n.hb-item-t small{display:block;color:#6b6b6b;font-size:12.5px}\n.hb-item-p{text-align:right;white-space:nowrap;font-weight:700}\n.hb-item-p span{display:block;font-weight:400;font-size:12.5px;color:#c0392b}\n.hb-item-p s{color:#8a8a8a;margin-left:4px}\n.hb-ship{text-align:center;margin:16px 0 0;font-size:15px;line-height:1.5}\n.hb-ship b{color:var(--g)}\n.hb-trust{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:14px 0 18px;text-align:center;font-weight:700;font-size:13.5px;color:var(--g)}\n.hb-trust svg{display:block;margin:0 auto 5px;width:32px;height:32px}\n.hb-err{color:#c0392b;text-align:center;font-size:14px;margin-top:6px}\n.hb-item-a{color:inherit;text-decoration:underline;text-underline-offset:2px}\n.hb-item-img{display:block;flex:0 0 54px}\n.hb-ck{text-align:center;margin:0 0 16px;font-size:14px}\n.hb-ck a{color:var(--g);font-weight:600}\n.hq{position:fixed;inset:0;z-index:2147483000;background:rgba(0,0,0,.45);display:flex;align-items:center;justify-content:center;padding:16px}\n.hq[hidden]{display:none}\n.hq-box{background:#fff;border-radius:14px;max-width:780px;width:100%;max-height:90vh;overflow:auto;position:relative;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:28px;padding:30px 26px 24px;color:#1d1d1d;font-size:15px}\n.hq-box\u003ediv{min-width:0}\n.hq-x{position:absolute;top:8px;right:10px;background:none;border:0;font-size:28px;line-height:1;cursor:pointer;color:#444;padding:4px 8px}\n.hq-main{position:relative;aspect-ratio:1\/1;display:flex;align-items:center;justify-content:center}\n.hq-main img{max-width:100%;max-height:100%;object-fit:contain}\n.hq-nav{position:absolute;top:50%;transform:translateY(-50%);background:rgba(255,255,255,.9);border:0;border-radius:50%;width:36px;height:36px;font-size:24px;line-height:1;cursor:pointer;color:#333}\n.hq-prev{left:0}.hq-next{right:0}\n.hq-th{display:flex;gap:10px;overflow-x:auto;margin-top:14px;padding-bottom:4px}\n.hq-th button{flex:0 0 58px;padding:0 0 6px;border:0;border-bottom:2px solid transparent;background:none;cursor:pointer}\n.hq-th button.on{border-bottom-color:#1d1d1d}\n.hq-th img{width:58px;height:52px;object-fit:cover;border-radius:4px;display:block}\n.hq-t{font-size:21px;line-height:1.35;margin:0 30px 8px 0;font-weight:500}\n.hq-v{font-size:13.5px;color:#6b6b6b;margin:0 0 8px}\n.hq-p{font-size:20px;font-weight:700;margin:0 0 4px}\n.hq-p s{font-size:15px;color:#8a8a8a;font-weight:400;margin-left:6px}\n.hq-save{font-size:13.5px;color:#7a5534;margin:0 0 14px}\n.hq-ul{list-style:none;padding:0;margin:0 0 18px;font-size:14.5px;line-height:1.5}\n.hq-ul li{position:relative;padding-left:27px;margin:0 0 6px}\n.hq-ul li:before{content:\"\\2713\";position:absolute;left:0;top:2px;width:19px;height:19px;border-radius:4px;background:#a57549;color:#fff;font-size:13px;font-weight:700;line-height:19px;text-align:center}\n.hq-add{display:block;width:100%;border:0;border-radius:40px;background:#7a5534;color:#fff;font:inherit;font-weight:700;padding:12px;cursor:pointer;margin:0 0 14px}\n.hq-more{display:inline-block;color:#1d1d1d;font-weight:600;text-decoration:none;font-size:15.5px}\nbody.hq-lock{overflow:hidden}\n@media (max-width:640px){.hq-box{grid-template-columns:minmax(0,1fr);gap:14px;padding:42px 16px 18px}.hq-t{font-size:18px;margin-right:0}}\n\u003c\/style\u003e\n\u003cscript\u003e\n(() =\u003e {\n  const cs = document.currentScript;\n  const start = () =\u003e {\n  const root = (cs \u0026\u0026 cs.parentElement.querySelector('.hb')) || document.querySelector('.hb');\n  if (!root || root.dataset.ready) return;\n  root.dataset.ready = 1;\n  \/\/ what to offer under each product (handle -\u003e handles)\n  const PAIR = {\n    'duo-french-twist-set': ['elegant-claw-clip', 'pearl-crystal-flower-hair-pin-set', 'geometric-hair-clips-set-of-2'],\n    'tortoiseshell-french-hair-pin': ['elegant-claw-clip', 'pearl-crystal-flower-hair-pin-set'],\n    'elegant-claw-clip': ['tortoiseshell-french-hair-pin', 'geometric-hair-clips-set-of-2'],\n    'geometric-hair-clips-set-of-2': ['elegant-claw-clip', 'tortoiseshell-french-hair-pin'],\n    'pearl-crystal-flower-hair-pin-set': ['vintage-crystal-hair-pin-set-of-3', 'tortoiseshell-french-hair-pin'],\n    'vintage-crystal-hair-pin-set-of-3': ['pearl-crystal-flower-hair-pin-set', 'tortoiseshell-french-hair-pin'],\n    'heart-pearl-hair-clip': ['pearl-crystal-flower-hair-pin-set', 'vintage-crystal-hair-pin-set-of-3']\n  };\n  const HEAD = {};\n  \/\/ must match the store's automatic discounts: Buy 2 items 10%, Buy 3+ items 15%\n  const pctFor = n =\u003e n \u003e= 3 ? 15 : n \u003e= 2 ? 10 : 0;\n  const money = c =\u003e '$' + (c \/ 100).toFixed(2);\n  const info = document.querySelector('.product__info-container');\n  const form = info \u0026\u0026 info.querySelector('form[action*=\"\/cart\/add\"][data-type=\"add-to-cart-form\"]');\n  if (!info || !form) return;\n  const blockOf = el =\u003e { while (el \u0026\u0026 el.parentElement !== info) el = el.parentElement; return el; };\n  const buyBlock = blockOf(form);\n  const qtyInput = () =\u003e info.querySelector('.product-form__quantity input[name=\"quantity\"]') || document.querySelector('input[name=\"quantity\"]');\n  const mainQty = () =\u003e Math.max(1, parseInt((qtyInput() || {}).value, 10) || 1);\n  buyBlock.after(root);\n  root.hidden = false;\n  const pay = root.querySelector('.hb-pay'), footerPay = document.querySelector('.list-payment');\n  if (!pay.querySelector('svg') \u0026\u0026 footerPay) pay.innerHTML = [...footerPay.querySelectorAll('svg')].map(s =\u003e s.outerHTML).join('');\n  if (!pay.querySelector('svg')) pay.remove();\n  const icon = d =\u003e '\u003csvg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.7\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\u003e' + d + '\u003c\/svg\u003e';\n  root.insertAdjacentHTML('beforeend',\n    '\u003cdiv class=\"hb-add\" hidden\u003e\u003c\/div\u003e' +\n    '\u003cdiv class=\"hb-ship\"\u003e\u003cb\u003eFree US shipping\u003c\/b\u003e on orders $60+.\u003cbr\u003eTypical delivery: 5–11 days after dispatch.\u003c\/div\u003e' +\n    '\u003cdiv class=\"hb-trust\"\u003e' +\n    '\u003cdiv\u003e' + icon('\u003cpath d=\"M3 7h11v8H3zM14 10h4l3 3v2h-7\"\/\u003e\u003ccircle cx=\"7\" cy=\"17\" r=\"1.6\"\/\u003e\u003ccircle cx=\"17\" cy=\"17\" r=\"1.6\"\/\u003e') + 'Free Shipping $60+\u003c\/div\u003e' +\n    '\u003cdiv\u003e' + icon('\u003cpath d=\"M4 12a8 8 0 1 0 2.4-5.7\"\/\u003e\u003cpath d=\"M4 4v4h4\"\/\u003e') + '30-Day Returns\u003c\/div\u003e' +\n    '\u003cdiv\u003e' + icon('\u003crect x=\"5\" y=\"11\" width=\"14\" height=\"9\" rx=\"2\"\/\u003e\u003cpath d=\"M8 11V8a4 4 0 0 1 8 0v3\"\/\u003e') + 'Secure Checkout\u003c\/div\u003e' +\n    '\u003c\/div\u003e' +\n    '\u003cp class=\"hb-ck\"\u003e\u003ca href=\"\/blogs\/hair-guides\/how-to-use-a-french-hair-pin\"\u003eNew to French pins? Read our step-by-step guide \u0026rarr;\u003c\/a\u003e\u003c\/p\u003e');\n  const handles = PAIR[root.dataset.handle] || [];\n  let extras = [];\n  const add = root.querySelector('.hb-add');\n  const picks = () =\u003e [...add.querySelectorAll('input:checked')].map(c =\u003e extras[+c.dataset.x]);\n  const paint = () =\u003e {\n    const n = mainQty() + picks().length;\n    add.querySelectorAll('.hb-item').forEach(el =\u003e {\n      const e = extras[+el.dataset.x], on = el.querySelector('input').checked;\n      const pct = pctFor(on ? n : n + 1);\n      el.querySelector('.hb-item-p').innerHTML = (pct ? '\u003cspan\u003e-' + pct + '%\u003cs\u003e' + money(e.v.price) + '\u003c\/s\u003e\u003c\/span\u003e' : '') + money(e.v.price - Math.floor(e.v.price * pct \/ 100));\n    });\n  };\n  Promise.all(handles.map(h =\u003e fetch('\/products\/' + h + '.js').then(r =\u003e r.ok ? r.json() : null).catch(() =\u003e null))).then(list =\u003e {\n    extras = list.filter(Boolean).map(a =\u003e { const v = a.variants.find(x =\u003e x.available); return v \u0026\u0026 { a, v }; }).filter(Boolean);\n    if (!extras.length) return;\n    const img = s =\u003e s ? s + (s.includes('?') ? '\u0026' : '?') + 'width=120' : '';\n    const link = e =\u003e '\/products\/' + e.a.handle + '?variant=' + e.v.id;\n    add.innerHTML = '\u003cp class=\"hb-add-h\"\u003e' + (HEAD[root.dataset.handle] || 'Complete the look') + '\u003c\/p\u003e' +\n      '\u003cp class=\"hb-add-p\"\u003eCheck the box to add it to this order. 2 items save 10%, 3 or more save 15%, applied automatically at checkout.\u003c\/p\u003e' +\n      extras.map((e, i) =\u003e '\u003clabel class=\"hb-item\" data-x=\"' + i + '\"\u003e\u003cinput type=\"checkbox\" data-x=\"' + i + '\"\u003e' +\n        (e.a.featured_image ? '\u003ca class=\"hb-item-img\" href=\"' + link(e) + '\" tabindex=\"-1\" aria-hidden=\"true\"\u003e\u003cimg src=\"' + img(e.a.featured_image) + '\" alt=\"\" loading=\"lazy\"\u003e\u003c\/a\u003e' : '') +\n        '\u003cspan class=\"hb-item-t\"\u003e\u003ca class=\"hb-item-a\" href=\"' + link(e) + '\"\u003e' + e.a.title.split(' – ')[0] + '\u003c\/a\u003e' + (e.a.variants.length \u003e 1 ? '\u003csmall\u003e' + e.v.title.split(' \/ ')[0] + '\u003c\/small\u003e' : '') + '\u003c\/span\u003e' +\n        '\u003cspan class=\"hb-item-p\"\u003e\u003c\/span\u003e\u003c\/label\u003e').join('');\n    add.hidden = false;\n    add.addEventListener('click', ev =\u003e {\n      const a = ev.target.closest('.hb-item-a, .hb-item-img');\n      if (!a || !window.hhQV) return;\n      ev.preventDefault();\n      const i = +a.closest('.hb-item').dataset.x, e = extras[i], cb = add.querySelector('input[data-x=\"' + i + '\"]');\n      window.hhQV({ a: e.a, v: e.v, from: a, note: 'Add it to this order: 2 items save 10%, 3 or more save 15% at checkout.', addLabel: cb.checked ? 'Remove from this order' : 'Add to this order', onAdd: () =\u003e { cb.checked = !cb.checked; cb.dispatchEvent(new Event('change', { bubbles: true })); } });\n    });\n    add.addEventListener('change', paint);\n    document.addEventListener('change', e =\u003e { if (e.target.name === 'quantity') setTimeout(paint, 50); });\n    paint();\n  });\n  document.addEventListener('submit', async e =\u003e {\n    if (e.target !== form || !picks().length) return;\n    e.preventDefault(); e.stopImmediatePropagation();\n    const btn = form.querySelector('[type=\"submit\"]'); if (btn) btn.setAttribute('aria-disabled', 'true');\n    const items = [{ id: +form.querySelector('input[name=\"id\"]').value, quantity: mainQty() }, ...picks().map(x =\u003e ({ id: x.v.id, quantity: 1 }))];\n    let r = null;\n    try { r = await fetch('\/cart\/add.js', { method: 'POST', headers: { 'Content-Type': 'application\/json' }, body: JSON.stringify({ items }) }); } catch (x) {}\n    if (r \u0026\u0026 r.ok) { location.href = '\/cart'; return; }\n    if (btn) btn.removeAttribute('aria-disabled');\n    let err = root.querySelector('.hb-err'); if (!err) { err = document.createElement('p'); err.className = 'hb-err'; add.after(err); }\n    err.textContent = (r \u0026\u0026 (await r.json().catch(() =\u003e ({}))).description) || 'Could not add to cart. Please try again.';\n  }, true);\n  window.addEventListener('pageshow', e =\u003e { if (e.persisted) { const b = form.querySelector('[type=\"submit\"]'); if (b) b.removeAttribute('aria-disabled'); } });\n  };\n  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', start); else start();\n})();\n\u003c\/script\u003e\n\u003c!-- \/hv-upsell v1 --\u003e\n\u003c!-- hv-extra v1 (Havendoa, adapted from hh-downsell v2 + hh-nopantry v2): shared quick view, single\/duo switch, French Twist Kit. Remove from the hv-extra v1 start marker to the \/hv-extra v1 end marker to undo. --\u003e\n\u003cdiv class=\"hd\" data-handle=\"duo-french-twist-set\" hidden\u003e\u003c\/div\u003e\u003cdiv class=\"hn\" data-handle=\"duo-french-twist-set\" hidden\u003e\u003c\/div\u003e\n\u003cstyle\u003e\n.hd{--g:#7a5534;margin:6px 0 18px;border:1px solid #e5d6c6;border-radius:12px;padding:12px;background:#fff;font-size:15px;color:#2b2b2b}\n.hd-h{font-weight:700;font-size:17px;margin:0}\n.hd-p{font-size:14px;color:#555;margin:3px 0 8px;line-height:1.45}\n.hd-card{display:flex;gap:10px;align-items:flex-start;border-top:1px solid #eee;padding:10px 0 4px}\n.hd-card img{width:62px;height:62px;object-fit:cover;border-radius:8px;flex:0 0 62px}\n.hd-b{flex:1;min-width:0;font-size:13.5px;line-height:1.4}\n.hd-b a.hd-t{font-weight:700;color:#1d1d1d;text-decoration:underline;text-underline-offset:2px;font-size:14.5px}\n.hd-img{display:block;flex:0 0 62px}\n.hd-b .hd-in{color:#2f6b52}\n.hd-b .hd-out{color:#8a5a2b}\n.hd-btn{margin-top:6px;border:1.5px solid var(--g);background:#fff;color:var(--g);border-radius:30px;padding:7px 14px;font:inherit;font-weight:700;font-size:13.5px;cursor:pointer}\n.hd-btn:disabled{opacity:.6}\n.hn{--g:#7a5534;margin:6px 0 18px;border:2px solid var(--g);border-radius:14px;padding:14px;background:#f8f2ec;font-size:15px;color:#2b2b2b}\n.hn-k{font-size:12px;letter-spacing:.08em;text-transform:uppercase;font-weight:700;color:#c75b2a;margin:0}\n.hn-h{font-weight:700;font-size:18px;margin:2px 0 4px;color:var(--g)}\n.hn-p{font-size:14px;color:#555;margin:0 0 10px;line-height:1.45}\n.hn-list{display:grid;gap:8px;margin:0 0 10px}\n.hn-row{display:flex;gap:10px;align-items:center;background:#fff;border-radius:10px;padding:8px}\n.hn-row img{width:48px;height:48px;object-fit:cover;border-radius:6px;flex:0 0 48px}\n.hn-row span{flex:1;min-width:0;font-size:13.5px;line-height:1.35}\n.hn-row span small{display:block;color:#6b6b6b}\n.hn-row b{white-space:nowrap;font-size:14px}\n.hn-sum{display:flex;justify-content:space-between;font-size:14px;margin:2px 2px 0}\n.hn-sum.hn-you{font-weight:700;font-size:16px;color:var(--g)}\n.hn-btn{display:block;width:100%;margin-top:10px;border:0;border-radius:40px;background:var(--g);color:#fff;font:inherit;font-weight:700;font-size:16px;padding:13px;cursor:pointer}\n.hn-btn:disabled{opacity:.6}\n.hn-a{color:inherit;text-decoration:underline;text-underline-offset:2px}\n.hn-img{display:block;flex:0 0 48px}\n.hn-note{font-size:12.5px;color:#6b6b6b;margin:8px 0 0;text-align:center}\n\u003c\/style\u003e\n\u003cscript\u003e\n(() =\u003e {\n  const cs = document.currentScript;\n  if (!window.hhQV) window.hhQV = (() =\u003e {\n    const qv = document.createElement('div');\n    qv.className = 'hq'; qv.hidden = true;\n    document.body.appendChild(qv);\n    const px = (s, w) =\u003e s ? s + (s.includes('?') ? '\u0026' : '?') + 'width=' + w : '';\n    const esc = s =\u003e String(s).replace(\/[\u0026\u003c\u003e\"]\/g, c =\u003e ({ '\u0026': '\u0026amp;', '\u003c': '\u0026lt;', '\u003e': '\u0026gt;', '\"': '\u0026quot;' }[c]));\n    const cash = c =\u003e '$' + (c \/ 100).toFixed(2);\n    const fileOf = s =\u003e String(s || '').split('?')[0].split('\/').pop();\n    const bullets = html =\u003e {\n      const d = new DOMParser().parseFromString(html || '', 'text\/html');\n      d.querySelectorAll('script, style, .hb, .hd, .hn').forEach(x =\u003e x.remove());\n      let li = [...d.querySelectorAll('li')].map(x =\u003e x.textContent.replace(\/\\s+\/g, ' ').trim()).filter(Boolean);\n      if (!li.length) li = [...d.querySelectorAll('p')].map(x =\u003e x.textContent.trim()).filter(Boolean).slice(0, 1);\n      return li.slice(0, 5).map(t =\u003e t.length \u003e 95 ? t.slice(0, 92).replace(\/[\\s,.;:]+\\S*$\/, '') + '…' : t);\n    };\n    let back = null;\n    const close = () =\u003e { qv.hidden = true; document.body.classList.remove('hq-lock'); if (back) back.focus(); };\n    qv.addEventListener('click', ev =\u003e { if (ev.target === qv) close(); });\n    document.addEventListener('keydown', ev =\u003e {\n      if (qv.hidden) return;\n      if (ev.key === 'Escape') close();\n      if (ev.key === 'ArrowLeft') { const b = qv.querySelector('.hq-prev'); if (b) b.click(); }\n      if (ev.key === 'ArrowRight') { const b = qv.querySelector('.hq-next'); if (b) b.click(); }\n    });\n    return o =\u003e {\n      const a = o.a, v = o.v;\n      back = o.from || null;\n      const imgs = (a.images \u0026\u0026 a.images.length) ? a.images : [a.featured_image];\n      let k = v.featured_image ? Math.max(0, imgs.findIndex(s =\u003e fileOf(s) === fileOf(v.featured_image.src))) : 0;\n      qv.innerHTML = '\u003cdiv class=\"hq-box\" role=\"dialog\" aria-modal=\"true\" aria-label=\"' + esc(a.title) + '\"\u003e' +\n        '\u003cbutton type=\"button\" class=\"hq-x\" aria-label=\"Close\"\u003e\u0026times;\u003c\/button\u003e' +\n        '\u003cdiv\u003e\u003cdiv class=\"hq-main\"\u003e\u003cimg alt=\"\"\u003e' +\n        (imgs.length \u003e 1 ? '\u003cbutton type=\"button\" class=\"hq-nav hq-prev\" aria-label=\"Previous image\"\u003e\u0026lsaquo;\u003c\/button\u003e\u003cbutton type=\"button\" class=\"hq-nav hq-next\" aria-label=\"Next image\"\u003e\u0026rsaquo;\u003c\/button\u003e' : '') +\n        '\u003c\/div\u003e' + (imgs.length \u003e 1 ? '\u003cdiv class=\"hq-th\"\u003e' + imgs.map((s, j) =\u003e '\u003cbutton type=\"button\" data-j=\"' + j + '\" aria-label=\"Image ' + (j + 1) + '\"\u003e\u003cimg src=\"' + px(s, 120) + '\" alt=\"\" loading=\"lazy\"\u003e\u003c\/button\u003e').join('') + '\u003c\/div\u003e' : '') + '\u003c\/div\u003e' +\n        '\u003cdiv\u003e\u003ch2 class=\"hq-t\"\u003e' + esc(a.title) + '\u003c\/h2\u003e' +\n        (a.variants.length \u003e 1 ? '\u003cp class=\"hq-v\"\u003e' + esc(v.title.split(' \/ ')[0]) + '\u003c\/p\u003e' : '') +\n        '\u003cp class=\"hq-p\"\u003e' + cash(v.price) + (v.compare_at_price \u003e v.price ? '\u003cs\u003e' + cash(v.compare_at_price) + '\u003c\/s\u003e' : '') + '\u003c\/p\u003e' +\n        (o.note ? '\u003cp class=\"hq-save\"\u003e' + esc(o.note) + '\u003c\/p\u003e' : '') +\n        '\u003cul class=\"hq-ul\"\u003e' + bullets(a.description).map(t =\u003e '\u003cli\u003e' + esc(t) + '\u003c\/li\u003e').join('') + '\u003c\/ul\u003e' +\n        (o.onAdd ? '\u003cbutton type=\"button\" class=\"hq-add\"\u003e' + esc(o.addLabel || 'Add to cart') + '\u003c\/button\u003e' : '') +\n        '\u003ca class=\"hq-more\" href=\"\/products\/' + a.handle + '?variant=' + v.id + '\"\u003eView more details \u003cspan aria-hidden=\"true\"\u003e\u0026rarr;\u003c\/span\u003e\u003c\/a\u003e\u003c\/div\u003e\u003c\/div\u003e';\n      const main = qv.querySelector('.hq-main img'), th = [...qv.querySelectorAll('.hq-th button')];\n      const show = j =\u003e { k = (j + imgs.length) % imgs.length; main.src = px(imgs[k], 800); th.forEach((b, x) =\u003e b.classList.toggle('on', x === k)); };\n      th.forEach(b =\u003e b.addEventListener('click', () =\u003e show(+b.dataset.j)));\n      const prev = qv.querySelector('.hq-prev'), next = qv.querySelector('.hq-next');\n      if (prev) prev.addEventListener('click', () =\u003e show(k - 1));\n      if (next) next.addEventListener('click', () =\u003e show(k + 1));\n      qv.querySelector('.hq-x').addEventListener('click', close);\n      const addBtn = qv.querySelector('.hq-add');\n      if (addBtn) addBtn.addEventListener('click', () =\u003e { close(); o.onAdd(); });\n      show(k);\n      qv.hidden = false;\n      document.body.classList.add('hq-lock');\n      qv.querySelector('.hq-x').focus();\n    };\n  })();\n  \/\/ single \u003c-\u003e duo switch, per product page\n  const SWITCH = {\n    'duo-french-twist-set': { h: 'Just need one pin?', p: 'Start with a single pin and add a second one later.', items: [{ handle: 'tortoiseshell-french-hair-pin', name: 'French Hair Pin', inc: '1 French Hair Pin in the color you choose', out: 'the second pin (the Duo is $65, less than two single pins)' }] },\n    'tortoiseshell-french-hair-pin': { h: 'Want a spare? Get the Duo', p: 'One pin for a quick twist, two for a fuller, more secure bun. $65 for two: less than two single pins, even with the 2-item discount.', items: [{ handle: 'duo-french-twist-set', name: 'Duo French Twist Set', inc: '2 French Hair Pins in the color you choose', out: '' }] }\n  };\n  \/\/ French Twist Kit, shown on these pages\n  const KIT_ON = ['duo-french-twist-set', 'tortoiseshell-french-hair-pin', 'elegant-claw-clip'];\n  const SET = [\n    { h: 'duo-french-twist-set', name: 'Duo French Twist Set', note: 'two French pins for the twist' },\n    { h: 'elegant-claw-clip', name: 'Elegant Claw Clip', note: 'for quick half-up days' },\n    { h: 'pearl-crystal-flower-hair-pin-set', name: 'Simulated Pearl \u0026 Crystal Flower Pins', note: 'for weddings and special days' }\n  ];\n  const PCT = 15; \/\/ store's automatic discount for 3+ items\n  const money = c =\u003e '$' + (c \/ 100).toFixed(2);\n  const img = (s, w) =\u003e s ? s + (s.includes('?') ? '\u0026' : '?') + 'width=' + w : '';\n  const go = async items =\u003e { const r = await fetch('\/cart\/add.js', { method: 'POST', headers: { 'Content-Type': 'application\/json' }, body: JSON.stringify({ items }) }); return r.ok; };\n  const start = () =\u003e {\n    const d = (cs \u0026\u0026 cs.parentElement.querySelector('.hd')) || document.querySelector('.hd');\n    const n = (cs \u0026\u0026 cs.parentElement.querySelector('.hn')) || document.querySelector('.hn');\n    if (!d || d.dataset.ready) return;\n    d.dataset.ready = 1;\n    const handle = d.dataset.handle;\n    const anchor = () =\u003e document.querySelector('.hb:not([hidden])') || (document.querySelector('.product__info-container product-form') || {}).parentElement;\n    const sw = SWITCH[handle];\n    if (sw) Promise.all(sw.items.map(o =\u003e fetch('\/products\/' + o.handle + '.js').then(r =\u003e r.ok ? r.json() : null).catch(() =\u003e null))).then(list =\u003e {\n      const rows = sw.items.map((o, i) =\u003e ({ o, p: list[i] })).filter(x =\u003e x.p \u0026\u0026 x.p.available);\n      if (!rows.length) return;\n      d.innerHTML = '\u003cp class=\"hd-h\"\u003e' + sw.h + '\u003c\/p\u003e\u003cp class=\"hd-p\"\u003e' + sw.p + '\u003c\/p\u003e' + rows.map((x, i) =\u003e {\n        const v = x.p.variants.find(v =\u003e v.available), lk = '\/products\/' + x.o.handle + '?variant=' + v.id;\n        return '\u003cdiv class=\"hd-card\" data-i=\"' + i + '\"\u003e' + (x.p.featured_image ? '\u003ca class=\"hd-img\" href=\"' + lk + '\"\u003e\u003cimg src=\"' + img(x.p.featured_image, 140) + '\" alt=\"\"\u003e\u003c\/a\u003e' : '') +\n          '\u003cdiv class=\"hd-b\"\u003e\u003ca class=\"hd-t\" href=\"' + lk + '\"\u003e' + x.o.name + ' · ' + money(v.price) + (v.compare_at_price \u003e v.price ? ' \u003cs\u003e' + money(v.compare_at_price) + '\u003c\/s\u003e' : '') + '\u003c\/a\u003e\u003cbr\u003e' +\n          '\u003cspan class=\"hd-in\"\u003eIncludes: ' + x.o.inc + '.\u003c\/span\u003e' + (x.o.out ? '\u003cbr\u003e\u003cspan class=\"hd-out\"\u003eNot included: ' + x.o.out + '.\u003c\/span\u003e' : '') + '\u003cbr\u003e' +\n          '\u003cbutton type=\"button\" class=\"hd-btn\" data-v=\"' + v.id + '\"\u003eAdd to cart — ' + money(v.price) + '\u003c\/button\u003e' + (x.p.variants.length \u003e 1 ? ' \u003csmall\u003e(' + v.title.split(' \/ ')[0] + '; pick another color on its page)\u003c\/small\u003e' : '') + '\u003c\/div\u003e\u003c\/div\u003e';\n      }).join('');\n      const a = anchor(); if (a) a.after(d);\n      d.hidden = false;\n      d.addEventListener('click', ev =\u003e {\n        const l = ev.target.closest('a.hd-t, a.hd-img'); if (!l) return; ev.preventDefault();\n        const card = l.closest('.hd-card'), x = rows[+card.dataset.i], b = card.querySelector('.hd-btn');\n        window.hhQV({ a: x.p, v: x.p.variants.find(v =\u003e v.available), from: l, note: 'Includes: ' + x.o.inc + '.', addLabel: b.textContent, onAdd: () =\u003e b.click() });\n      });\n      d.querySelectorAll('.hd-btn').forEach(b =\u003e b.addEventListener('click', async () =\u003e { b.disabled = true; b.textContent = 'Adding…'; if (await go([{ id: +b.dataset.v, quantity: 1 }])) location.href = '\/cart'; else { b.disabled = false; b.textContent = 'Could not add. Try again'; } }));\n    });\n    if (n \u0026\u0026 KIT_ON.includes(handle)) Promise.all(SET.map(s =\u003e fetch('\/products\/' + s.h + '.js').then(r =\u003e r.ok ? r.json() : null).catch(() =\u003e null))).then(list =\u003e {\n      const rows = SET.map((s, i) =\u003e { const p = list[i]; if (!p) return null; const v = p.variants.find(v =\u003e v.available); return v ? { s, p, v } : null; });\n      if (rows.some(r =\u003e !r)) return;\n      const sum = rows.reduce((a, r) =\u003e a + r.v.price, 0), you = sum - Math.floor(sum * PCT \/ 100);\n      const lk = r =\u003e '\/products\/' + r.s.h + '?variant=' + r.v.id;\n      n.innerHTML = '\u003cp class=\"hn-k\"\u003eThe French Twist Kit\u003c\/p\u003e\u003cp class=\"hn-h\"\u003eEverything for an effortless updo.\u003c\/p\u003e' +\n        '\u003cp class=\"hn-p\"\u003eTwo French pins for the twist, a claw clip for quick half-up days, and simulated pearl flower pins for special occasions.\u003c\/p\u003e' +\n        '\u003cdiv class=\"hn-list\"\u003e' + rows.map((r, i) =\u003e '\u003cdiv class=\"hn-row\" data-i=\"' + i + '\"\u003e' + (r.p.featured_image ? '\u003ca class=\"hn-img\" href=\"' + lk(r) + '\"\u003e\u003cimg src=\"' + img(r.p.featured_image, 100) + '\" alt=\"\"\u003e\u003c\/a\u003e' : '') +\n          '\u003cspan\u003e\u003ca class=\"hn-a\" href=\"' + lk(r) + '\"\u003e' + r.s.name + '\u003c\/a\u003e\u003csmall\u003e' + r.s.note + (r.p.variants.length \u003e 1 ? ' · ' + r.v.title.split(' \/ ')[0] : '') + '\u003c\/small\u003e\u003c\/span\u003e\u003cb\u003e' + money(r.v.price) + '\u003c\/b\u003e\u003c\/div\u003e').join('') + '\u003c\/div\u003e' +\n        '\u003cdiv class=\"hn-sum\"\u003e\u003cspan\u003eBought separately\u003c\/span\u003e\u003cspan\u003e' + money(sum) + '\u003c\/span\u003e\u003c\/div\u003e' +\n        '\u003cdiv class=\"hn-sum hn-you\"\u003e\u003cspan\u003eWith ' + PCT + '% off 3+ items\u003c\/span\u003e\u003cspan\u003e' + money(you) + '\u003c\/span\u003e\u003c\/div\u003e' +\n        '\u003cbutton type=\"button\" class=\"hn-btn\"\u003eAdd all ' + rows.length + ' to cart — ' + money(you) + ' at checkout\u003c\/button\u003e' +\n        '\u003cp class=\"hn-note\"\u003eThe ' + PCT + '% applies automatically at checkout and can’t be combined with other discount codes. Items may arrive in separate parcels, each with its own tracking number.\u003c\/p\u003e';\n      const a = (d.hidden ? null : d) || anchor(); if (a) a.after(n);\n      n.hidden = false;\n      const btn = n.querySelector('.hn-btn');\n      const pickColor = () =\u003e { const i = document.querySelector('variant-picker input:checked, variant-selects input:checked, variant-radios input:checked'); return i ? i.value : null; };\n      const pickDuo = r =\u003e { const c = pickColor(); return (c \u0026\u0026 r.p.variants.find(v =\u003e v.available \u0026\u0026 v.title.split(' \/ ')[0] === c)) || r.v; };\n      const relabel = () =\u003e { rows.forEach((r, i) =\u003e { if (r.s.h !== 'duo-french-twist-set' || r.p.variants.length \u003c 2) return; const el = n.querySelector('.hn-row[data-i=\"' + i + '\"] small'); if (el) el.textContent = r.s.note + ' · ' + pickDuo(r).title.split(' \/ ')[0]; }); };\n      document.addEventListener('change', () =\u003e setTimeout(relabel, 200)); relabel();\n      btn.addEventListener('click', async () =\u003e { btn.disabled = true; btn.textContent = 'Adding…'; if (await go(rows.map(x =\u003e ({ id: (x.s.h === 'duo-french-twist-set' ? pickDuo(x) : x.v).id, quantity: 1 })))) location.href = '\/cart'; else { btn.disabled = false; btn.textContent = 'Could not add. Try again'; } });\n      n.addEventListener('click', ev =\u003e {\n        const l = ev.target.closest('a.hn-a, a.hn-img'); if (!l) return; ev.preventDefault();\n        const r = rows[+l.closest('.hn-row').dataset.i];\n        window.hhQV({ a: r.p, v: r.v, from: l, note: 'Part of the French Twist Kit: ' + r.s.note + '.', addLabel: btn.textContent, onAdd: () =\u003e btn.click() });\n      });\n    });\n  };\n  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', () =\u003e setTimeout(start, 50)); else setTimeout(start, 50);\n})();\n\u003c\/script\u003e\n\u003c!-- \/hv-extra v1 --\u003e\n\u003c!-- hv-tiers v1 (Havendoa): \"Buy more, save more\" 1\/2\/3 items, replaces the quantity box. Must match automatic discounts (2 items 10%, 3+ items 15%). Remove from the hv-tiers v1 start marker to the \/hv-tiers v1 end marker to undo. --\u003e\n\u003cdiv class=\"hv-tiers\" data-handle=\"duo-french-twist-set\" hidden\u003e\u003c\/div\u003e\n\u003cstyle\u003e\n.hv-tiers{margin:4px 0 16px;background:#f5efe8;border:1px solid #e5d6c6;border-radius:14px;padding:12px 12px 6px;font-size:15px;color:#2b2b2b}\n.hv-tiers__h{font-weight:700;font-size:16px;margin:0 0 8px;color:#7a5534}\n.hv-tier{display:flex;align-items:center;gap:10px;background:#fff;border:1px solid #eadfd3;border-radius:10px;padding:10px 12px;margin:0 0 8px;cursor:pointer}\n.hv-tier.is-on{box-shadow:0 0 0 2px #7a5534;border-color:#7a5534}\n.hv-tier input{width:20px;height:20px;accent-color:#7a5534;margin:0;flex:0 0 20px}\n.hv-tier__t{flex:1;min-width:0;line-height:1.3}\n.hv-tier__t small{display:block;color:#6b6b6b;font-size:12.5px}\n.hv-tier__b{display:inline-block;margin-left:6px;background:#7a5534;color:#fff;border-radius:20px;font-size:11.5px;font-weight:700;padding:2px 8px;vertical-align:middle}\n.hv-tier__p{text-align:right;font-weight:700;white-space:nowrap}\n.hv-tier__p s{display:block;font-weight:400;font-size:12.5px;color:#8a8a8a}\n.hv-tiers__note{font-size:12.5px;color:#6b6b6b;margin:0 2px 6px}\n\u003c\/style\u003e\n\u003cscript\u003e\n(() =\u003e {\n  const cs = document.currentScript;\n  const TIERS = [[1, 0, ''], [2, 10, 'Save 10%'], [3, 15, 'Save 15%']];\n  const money = c =\u003e '$' + (c \/ 100).toFixed(2);\n  const start = () =\u003e {\n    const box = (cs \u0026\u0026 cs.parentElement.querySelector('.hv-tiers')) || document.querySelector('.hv-tiers');\n    if (!box || box.dataset.ready) return;\n    box.dataset.ready = 1;\n    const info = document.querySelector('.product__info-container');\n    const form = info \u0026\u0026 info.querySelector('form[action*=\"\/cart\/add\"][data-type=\"add-to-cart-form\"]');\n    if (!info || !form) return;\n    const blockOf = el =\u003e { while (el \u0026\u0026 el.parentElement !== info) el = el.parentElement; return el; };\n    const qtyBox = info.querySelector('.product-form__quantity');\n    const anchor = qtyBox ? blockOf(qtyBox) : blockOf(form);\n    const qty = () =\u003e info.querySelector('input[name=\"quantity\"]') || document.querySelector('input[name=\"quantity\"]');\n    fetch('\/products\/' + box.dataset.handle + '.js').then(r =\u003e r.ok ? r.json() : null).then(p =\u003e {\n      if (!p) return;\n      const cur = () =\u003e { const id = +(form.querySelector('input[name=\"id\"]') || {}).value; return p.variants.find(v =\u003e v.id === id) || p.variants.find(v =\u003e v.available) || p.variants[0]; };\n      const render = () =\u003e {\n        const v = cur(), on = box.querySelector('input:checked'), pick = on ? +on.value : Math.max(1, Math.min(3, parseInt((qty() || {}).value, 10) || 1));\n        box.innerHTML = '\u003cp class=\"hv-tiers__h\"\u003eBuy more, save more\u003c\/p\u003e' + TIERS.map(([n, pct, badge]) =\u003e {\n          const full = v.price * n, you = full - Math.floor(full * pct \/ 100);\n          return '\u003clabel class=\"hv-tier' + (n === pick ? ' is-on' : '') + '\"\u003e\u003cinput type=\"radio\" name=\"hv-tier\" value=\"' + n + '\"' + (n === pick ? ' checked' : '') + '\u003e' +\n            '\u003cspan class=\"hv-tier__t\"\u003e\u003cb\u003e' + n + (n === 1 ? ' item' : ' items') + '\u003c\/b\u003e' + (badge ? '\u003cspan class=\"hv-tier__b\"\u003e' + badge + '\u003c\/span\u003e' : '') + (p.variants.length \u003e 1 ? '\u003csmall\u003e' + v.title.split(' \/ ')[0] + (n \u003e 1 ? ' x ' + n : '') + '\u003c\/small\u003e' : '') + '\u003c\/span\u003e' +\n            '\u003cspan class=\"hv-tier__p\"\u003e' + money(you) + (pct ? '\u003cs\u003e' + money(full) + '\u003c\/s\u003e' : '') + '\u003c\/span\u003e\u003c\/label\u003e';\n        }).join('') + '\u003cp class=\"hv-tiers__note\"\u003eWant different colors? Add each one to your cart: the discount counts every item in your order.\u003c\/p\u003e';\n      };\n      const setQty = n =\u003e { const q = qty(); if (q \u0026\u0026 q.value !== String(n)) { q.value = n; q.dispatchEvent(new Event('change', { bubbles: true })); } };\n      anchor.before(box);\n      if (qtyBox) anchor.style.display = 'none';\n      render(); box.hidden = false;\n      box.addEventListener('change', e =\u003e { if (e.target.name !== 'hv-tier') return; setQty(+e.target.value); render(); });\n      \/\/ the theme resets quantity to 1 on every variant change; put the tier back and refresh prices\n      document.addEventListener('change', e =\u003e { if (box.contains(e.target)) return; if (e.target \u0026\u0026 e.target.name === 'id') setTimeout(() =\u003e { const t = box.querySelector('input:checked'); if (t) setQty(+t.value); render(); }, 60); });\n      window.addEventListener('pageshow', () =\u003e setTimeout(() =\u003e { const t = box.querySelector('input:checked'); if (t) setQty(+t.value); }, 0));\n    });\n  };\n  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', start); else start();\n})();\n\u003c\/script\u003e\n\u003c!-- \/hv-tiers v1 --\u003e","brand":"Havendoa","offers":[{"title":"Tortoiseshell","offer_id":49284150001847,"sku":"HV-DUO-TOR","price":65.0,"currency_code":"USD","in_stock":true},{"title":"Black","offer_id":49284260167863,"sku":"HV-DUO-BLK","price":65.0,"currency_code":"USD","in_stock":true},{"title":"Olive Green","offer_id":49284260200631,"sku":"HV-DUO-OLV","price":65.0,"currency_code":"USD","in_stock":true},{"title":"Burgundy","offer_id":49284260233399,"sku":"HV-DUO-BUR","price":65.0,"currency_code":"USD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0761\/4998\/1367\/files\/Se72d2fbac55c4b74b7e0bbebb54efd2cp_46cabe3a-39b1-4d7a-9f99-aaf9ef3238e7.webp?v=1790943910"}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0761\/4998\/1367\/collections\/S7dc7f3d471744332abc0d1c8c0825f65X_39d94225-cadd-4239-a941-f96c1d987167.webp?v=1790955791","url":"https:\/\/havendoa.com\/collections\/gift-sets.oembed","provider":"Havendoa","version":"1.0","type":"link"}