{"title":"Hair Accessory Gifts Under $50","description":"\u003cp\u003eHair accessory gifts under $50 that feel thoughtful, not last-minute: French hair pins, a claw clip, colorful side clips and sparkly simulated pearl and rhinestone pin sets.\u003c\/p\u003e\u003cp\u003eNo sizing and no shade-matching, so they’re easy to choose even if you’re not sure how she wears her hair. Mix any 2 items to save 10%, 3 or more to save 15%, applied automatically at checkout. Two items take you past our free US shipping threshold of $60.\u003c\/p\u003e\u003cp\u003eBuying for a date? Each product page shows an estimated delivery window before you order, and our \u003ca href=\"\/blogs\/hair-guides\/christmas-gifts-for-her-under-50\"\u003eChristmas gift guide\u003c\/a\u003e has the order-by date. Unworn items can be returned within 30 days of delivery.\u003c\/p\u003e","products":[{"product_id":"tortoiseshell-french-hair-pin","title":"French Hair Pin – U-Shaped Pin for French Twists \u0026 Buns","description":"\u003ch2\u003eOne pin, no hair tie: an easy French twist\u003c\/h2\u003e\n\u003cp\u003eIf a hair tie leaves a dent by lunch, or a claw clip feels like too much for the office, try a French pin. Twist your hair up, slide in one slim U-shaped pin, and you have a French twist or low bun that looks finished, not thrown together.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cstrong\u003eNothing squeezing your hair.\u003c\/strong\u003e No elastic band, so no elastic dent when you take your hair down.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eLooks like an accessory, not a hair tool.\u003c\/strong\u003e A softly waved U shape in Tortoiseshell pattern, Black, Olive Green or Burgundy.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eSmall enough to carry.\u003c\/strong\u003e About 13 cm (5.1 in) long, so it fits in a pocket, desk drawer or makeup bag.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eExtra hold when you need it.\u003c\/strong\u003e Long or thick hair? Add a second pin from the opposite side, or get two in one color with our \u003ca href=\"\/products\/duo-french-twist-set\"\u003eFrench hair pin set\u003c\/a\u003e.\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003cp\u003eNew to French pins? Open \u003cem\u003eHow to use\u003c\/em\u003e below for the 4-step twist, or read our \u003ca href=\"\/blogs\/hair-guides\/how-to-use-a-french-hair-pin\"\u003estep-by-step guide\u003c\/a\u003e. It can take a few tries the first time.\u003c\/p\u003e\n\u003cp\u003e\u003cstrong\u003eWhat you get:\u003c\/strong\u003e 1 French Hair Pin in the color you choose.\u003c\/p\u003e\n\u003cp\u003e\u003cstrong\u003eSize:\u003c\/strong\u003e about 13 cm (5.1 in) long, as listed by our supplier.\u003c\/p\u003e\n\u003cp\u003e\u003cstrong\u003eShipping \u0026amp; returns:\u003c\/strong\u003e free US shipping on orders $60+ ($8 under $60), and 30-day returns on unworn items in original packaging.\u003c\/p\u003e\n\u003cp\u003eShips from our fulfillment partner overseas: orders are processed in 1–3 business days, then typically arrive 5–11 days after dispatch.\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=\"tortoiseshell-french-hair-pin\" 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=\"tortoiseshell-french-hair-pin\" hidden\u003e\u003c\/div\u003e\u003cdiv class=\"hn\" data-handle=\"tortoiseshell-french-hair-pin\" 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=\"tortoiseshell-french-hair-pin\" 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":49283867443383,"sku":"HV-FP-TOR","price":38.0,"currency_code":"USD","in_stock":true},{"title":"Black","offer_id":49284260069559,"sku":"HV-FP-BLK","price":38.0,"currency_code":"USD","in_stock":true},{"title":"Olive Green","offer_id":49284260102327,"sku":"HV-FP-OLV","price":38.0,"currency_code":"USD","in_stock":true},{"title":"Burgundy","offer_id":49284260135095,"sku":"HV-FP-BUR","price":38.0,"currency_code":"USD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0761\/4998\/1367\/files\/Sec553b7afeb044b2be4f15f42cbf2177A.webp?v=1790938300"},{"product_id":"elegant-claw-clip","title":"Elegant Claw Clip – Tortoiseshell Pattern Hair Claw for Updos","description":"\u003ch3\u003eA polished twist, no hair tie needed\u003c\/h3\u003e\n\u003cp\u003eFor the days your hair needs to be up and out of the way but should still look put-together. Twist, clip, and you’re ready for the office, errands or dinner.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cstrong\u003eUp in a few simple moves.\u003c\/strong\u003e Twist your hair, clip it over the twist, done. No elastic, so no elastic dent when you take it down.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eTwo ways to wear it.\u003c\/strong\u003e Rounded teeth, designed for a full twist or a half-up style.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eLooks like an accessory, not a hair tool.\u003c\/strong\u003e A classic tortoiseshell pattern that goes with work clothes and weekend jeans alike.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003ePairs well with a French pin.\u003c\/strong\u003e Keep the clip for half-up days and a \u003ca href=\"\/products\/tortoiseshell-french-hair-pin\"\u003eFrench Hair Pin\u003c\/a\u003e for a sleek twist. Buy any 2 items and 10% comes off automatically at checkout.\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003cp\u003e\u003cstrong\u003eWhat you get:\u003c\/strong\u003e 1 claw clip in a tortoiseshell pattern.\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\u003eNot sure whether a claw clip or a French pin suits you? Read \u003ca href=\"\/blogs\/hair-guides\/french-pin-vs-claw-clip\"\u003eFrench Pin vs Claw Clip\u003c\/a\u003e.\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=\"elegant-claw-clip\" 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=\"elegant-claw-clip\" hidden\u003e\u003c\/div\u003e\u003cdiv class=\"hn\" data-handle=\"elegant-claw-clip\" 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=\"elegant-claw-clip\" 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":"Default Title","offer_id":49283867541687,"sku":null,"price":42.0,"currency_code":"USD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0761\/4998\/1367\/files\/S8b191e3517424d0b92340f32754cf5adO.webp?v=1790938303"},{"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":"pearl-crystal-flower-hair-pin-set","title":"Simulated Pearl \u0026 Crystal Flower Hair Pin Set for Buns \u0026 Braids","description":"\u003ch3\u003eA little sparkle for buns, braids and big days\u003c\/h3\u003e\n\u003cp\u003eSimulated pearl and rhinestone flower pins that bring a soft, romantic sparkle to braids, buns and half-up styles. Wear one as a single accent, or tuck in a few for a fuller look.\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cstrong\u003eSix styles to choose from.\u003c\/strong\u003e From classic simulated pearl to champagne or black rhinestones, plus a starfish-and-moon set.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eDetails that catch the light.\u003c\/strong\u003e Simulated pearl and rhinestone flower details for a wedding, a party or dinner out.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eEasy to style.\u003c\/strong\u003e Slide each pin in at a slight angle, catching a little hair underneath.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eMake it a pair.\u003c\/strong\u003e Wear them with our \u003ca href=\"\/products\/vintage-crystal-hair-pin-set-of-3\"\u003eVintage Crystal Hair Pin Set of 3\u003c\/a\u003e. Buy any 2 items and 10% comes off automatically at checkout.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eAn easy gift\u003c\/strong\u003e for a bride, bridesmaid or friend: no sizing, no shade-matching.\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003cp\u003e\u003cstrong\u003eWhat you get:\u003c\/strong\u003e 1 set of flower hair pins in the style you choose, as shown in the photo for that style.\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=\"pearl-crystal-flower-hair-pin-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=\"pearl-crystal-flower-hair-pin-set\" hidden\u003e\u003c\/div\u003e\u003cdiv class=\"hn\" data-handle=\"pearl-crystal-flower-hair-pin-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=\"pearl-crystal-flower-hair-pin-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":"Classic Simulated Pearl","offer_id":49283867803831,"sku":"HV-PCS-PRL","price":36.0,"currency_code":"USD","in_stock":true},{"title":"Starfish \u0026 Moon","offer_id":49284519821495,"sku":"HV-PCS-SEA","price":36.0,"currency_code":"USD","in_stock":true},{"title":"Simulated Pearl Bow \u0026 Flower","offer_id":49284519854263,"sku":"HV-PCS-PBF","price":36.0,"currency_code":"USD","in_stock":true},{"title":"Crystal Bow \u0026 Flower","offer_id":49284519887031,"sku":"HV-PCS-CBF","price":36.0,"currency_code":"USD","in_stock":true},{"title":"Champagne Crystal","offer_id":49284519919799,"sku":"HV-PCS-CHP","price":36.0,"currency_code":"USD","in_stock":true},{"title":"Black Crystal","offer_id":49284519952567,"sku":"HV-PCS-BLK","price":36.0,"currency_code":"USD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0761\/4998\/1367\/files\/Sa2a50982cb804b469cd60cd2e00b9a4d0.webp?v=1790949998"},{"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"}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0761\/4998\/1367\/collections\/Sa2a50982cb804b469cd60cd2e00b9a4d0.webp?v=1790965378","url":"https:\/\/havendoa.com\/collections\/gifts-under-50.oembed","provider":"Havendoa","version":"1.0","type":"link"}