{"product_id":"steel-spinner-ring","title":"Spinner Ring","description":"\u003cp\u003eA band that turns. The outer ring spins on the inner one — quietly, under the thumb — so restless hands have somewhere to go that isn't your nails.\u003c\/p\u003e\n\n\u003cp\u003eTitanium steel with a channel of square-cut cubic zirconia, in silver, gold or rose gold. Polished, hypoallergenic, and made to be worn every day. Sizes 5 to 12.\u003c\/p\u003e\n\n\u003cstyle\u003e\n#cl-sets{margin:6px 0 18px}\n#cl-sets .clb-head{display:flex;align-items:center;gap:12px;margin:0 0 14px}\n#cl-sets .clb-line{flex:1;height:1px;background:currentColor;opacity:.35}\n#cl-sets .clb-title{font-size:1.2rem;letter-spacing:.22em;text-transform:uppercase;font-weight:700}\n#cl-sets .clb-card{position:relative;border:2px solid rgba(244,241,234,.28);border-radius:10px;padding:1.5rem 1.6rem;margin:0 0 1.1rem;display:flex;align-items:center;gap:1.2rem;cursor:pointer}\n#cl-sets .clb-card.sel{border-color:#c81e2d}\n#cl-sets .clb-radio{width:2rem;height:2rem;border:2px solid rgba(244,241,234,.4);border-radius:50%;flex:none;position:relative}\n#cl-sets .clb-card.sel .clb-radio{border-color:#c81e2d}\n#cl-sets .clb-card.sel .clb-radio:after{content:\"\";position:absolute;inset:4px;background:#c81e2d;border-radius:50%}\n#cl-sets .clb-main{flex:1;min-width:0}\n#cl-sets .clb-t{font-weight:700;font-size:1.5rem;line-height:1.25;display:flex;align-items:center;gap:.8rem;flex-wrap:wrap}\n#cl-sets .clb-pill{background:#c81e2d;color:#fff;font-size:1.02rem;font-weight:700;letter-spacing:.08em;padding:.25rem .7rem;border-radius:4px;white-space:nowrap}\n#cl-sets .clb-c{font-size:1.25rem;opacity:.7;margin-top:.35rem}\n#cl-sets .clb-price{text-align:right;flex:none}\n#cl-sets .clb-p{font-size:1.6rem;font-weight:700}\n#cl-sets .clb-was{font-size:1.2rem;opacity:.55;text-decoration:line-through}\n#cl-sets .clb-badge{position:absolute;top:-1.05rem;right:1.2rem;background:#c81e2d;color:#fff;font-size:1.02rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;padding:.35rem .9rem}\n#cl-sets .clb-extra{border:1px solid rgba(23,23,27,.18);border-radius:10px;padding:1.2rem 1.4rem;margin:0 0 1.1rem;background:#fff}\n#cl-sets .clb-extra h4{margin:0 0 .8rem;font-size:1.1rem;letter-spacing:.18em;text-transform:uppercase;font-weight:700;color:#17171b}\n#cl-sets .clb-lab{font-size:1.05rem;letter-spacing:.1em;text-transform:uppercase;opacity:.6;margin:.6rem 0 .4rem}\n#cl-sets .clb-opts{display:flex;flex-wrap:wrap;gap:.5rem}\n#cl-sets .clb-opt{display:inline-block;user-select:none;border:1px solid rgba(23,23,27,.35);border-radius:4px;padding:.55rem .9rem;font-size:1.25rem;cursor:pointer;background:#fff;color:#17171b;font-family:inherit;line-height:1}\n#cl-sets .clb-opt.on{background:#b3182a !important;color:#fff !important;border-color:#b3182a !important}\n#cl-sets .clb-note{font-size:1.15rem;opacity:.65;margin:.2rem 0 1rem}\n\u003c\/style\u003e\n\n\u003cscript id=\"cl-sets-js\"\u003e\n(function () {\n  var HANDLE = 'steel-spinner-ring';\n  function boot() {\n    if (document.getElementById('cl-sets')) return;\n    var form = document.querySelector('form[action*=\"\/cart\/add\"]');\n    if (!form || !form.querySelector('input[name=\"id\"], [name=\"id\"]')) { setTimeout(boot, 300); return; }\n    fetch('\/products\/' + HANDLE + '.js', { credentials: 'same-origin' })\n      .then(function (r) { return r.json(); })\n      .then(function (p) { build(p, form); })\n      .catch(function () {});\n  }\n  function build(p, form) {\n    if (document.getElementById('cl-sets')) return;\n    var cur = (window.Shopify \u0026\u0026 Shopify.currency \u0026\u0026 Shopify.currency.active) || 'USD';\n    function money(cents) {\n      try { return new Intl.NumberFormat(undefined, { style: 'currency', currency: cur }).format(cents \/ 100); }\n      catch (e) { return (cents \/ 100).toFixed(2) + ' ' + cur; }\n    }\n    var finishes = [], sizes = [];\n    p.variants.forEach(function (v) {\n      if (finishes.indexOf(v.option1) \u003c 0) finishes.push(v.option1);\n      if (sizes.indexOf(v.option2) \u003c 0) sizes.push(v.option2);\n    });\n    function tiersFor(unit) {\n      return [\n        { qty: 1, title: 'One ring', total: unit, was: 0 },\n        { qty: 2, title: 'Two rings — second one 50% off', total: unit * 2 - Math.floor(unit * 0.5), was: unit * 2 },\n        { qty: 3, title: 'Three rings — one of them free', total: unit * 2, was: unit * 3 }\n      ];\n    }\n    var chosen = 1;\n    var tiers = tiersFor(p.variants[0].price);\n    var extra = [null, null];\n    function selected() {\n      var out = {};\n      var radios = document.querySelectorAll('.product__info-container input[type=\"radio\"]:checked, variant-selects input[type=\"radio\"]:checked, variant-radios input[type=\"radio\"]:checked');\n      Array.prototype.forEach.call(radios, function (r) { if (!r.closest('#cl-sets')) out[r.name] = r.value; });\n      var sels = document.querySelectorAll('variant-selects select, variant-picker select, .product__info-container select');\n      Array.prototype.forEach.call(sels, function (s) { out[s.name || s.id] = s.value; });\n      return out;\n    }\n    function mainVariant() {\n      var chosenVals = [];\n      var sel = selected();\n      Object.keys(sel).forEach(function (k) { chosenVals.push(sel[k]); });\n      var best = null, bestScore = -1;\n      p.variants.forEach(function (v) {\n        var score = 0;\n        [v.option1, v.option2].forEach(function (o) { if (o \u0026\u0026 chosenVals.indexOf(o) \u003e -1) score++; });\n        if (score \u003e bestScore) { bestScore = score; best = v; }\n      });\n      var idInput = form.querySelector('input[name=\"id\"], [name=\"id\"]');\n      if (idInput \u0026\u0026 bestScore \u003c 2) {\n        var byId = p.variants.filter(function (v) { return String(v.id) === String(idInput.value); })[0];\n        if (byId) best = byId;\n      }\n      return best || p.variants[0];\n    }\n    function variantFor(fin, size) {\n      return p.variants.filter(function (v) { return v.option1 === fin \u0026\u0026 v.option2 === size; })[0] || null;\n    }\n    function ensureExtra() {\n      var m = mainVariant();\n      for (var i = 0; i \u003c 2; i++) { if (!extra[i]) extra[i] = { fin: m.option1, size: m.option2 }; }\n    }\n    function setQty(n) {\n      var forms = document.querySelectorAll('form[action*=\"\/cart\/add\"]');\n      Array.prototype.forEach.call(forms, function (f) {\n        var inputs = f.querySelectorAll('input[name=\"quantity\"], [name=\"quantity\"]');\n        if (!inputs.length) {\n          var qi = document.createElement('input');\n          qi.type = 'hidden';\n          qi.name = 'quantity';\n          f.appendChild(qi);\n          inputs = [qi];\n        }\n        Array.prototype.forEach.call(inputs, function (i) {\n          i.value = String(n);\n          try { i.dispatchEvent(new Event('change', { bubbles: true })); } catch (e) {}\n        });\n      });\n    }\n    var box = document.createElement('div');\n    box.id = 'cl-sets';\n    function optRow(label, list, ring, key) {\n      var h = '\u003cdiv class=\"clb-lab\"\u003e' + label + '\u003c\/div\u003e\u003cdiv class=\"clb-opts\"\u003e';\n      list.forEach(function (val) {\n        var on = extra[ring][key] === val;\n        h += '\u003cspan role=\"button\" tabindex=\"0\" class=\"clb-opt' + (on ? ' on' : '') + '\" data-ring=\"' + ring + '\" data-key=\"' + key + '\" data-val=\"' + val + '\"\u003e' + val + '\u003c\/span\u003e';\n      });\n      return h + '\u003c\/div\u003e';\n    }\n    function render() {\n      ensureExtra();\n      var html = '';\n      if (chosen \u003e 1) {\n        html += '\u003cdiv class=\"clb-note\"\u003eRing 1 is the finish and size chosen above. Pick the others here — mix them however you like.\u003c\/div\u003e';\n        for (var r0 = 0; r0 \u003c chosen - 1; r0++) {\n          html += '\u003cdiv class=\"clb-extra\"\u003e\u003ch4\u003eRing ' + (r0 + 2) + '\u003c\/h4\u003e' + optRow('Finish', finishes, r0, 'fin') + optRow('Size', sizes, r0, 'size') + '\u003c\/div\u003e';\n        }\n      }\n      html += '\u003cdiv class=\"clb-head\"\u003e\u003cspan class=\"clb-line\"\u003e\u003c\/span\u003e\u003cspan class=\"clb-title\"\u003eHow many\u003c\/span\u003e\u003cspan class=\"clb-line\"\u003e\u003c\/span\u003e\u003c\/div\u003e';\n      tiers.forEach(function (t, i) {\n        var save = t.was ? t.was - t.total : 0;\n        var pill = save ? '\u003cspan class=\"clb-pill\"\u003eSAVE ' + money(save) + '\u003c\/span\u003e' : '';\n        var was = save ? '\u003cdiv class=\"clb-was\"\u003e' + money(t.was) + '\u003c\/div\u003e' : '';\n        var badge = i === 1 ? '\u003cspan class=\"clb-badge\"\u003eMost popular\u003c\/span\u003e' : '';\n        var sub = i === 0 ? 'Standard price' : 'Any finish, any size · Ships free · Applied in cart';\n        html += '\u003cdiv class=\"clb-card' + (t.qty === chosen ? ' sel' : '') + '\" data-qty=\"' + t.qty + '\"\u003e' + badge +\n          '\u003cspan class=\"clb-radio\"\u003e\u003c\/span\u003e' +\n          '\u003cspan class=\"clb-main\"\u003e\u003cspan class=\"clb-t\"\u003e' + t.title + ' ' + pill + '\u003c\/span\u003e\u003cdiv class=\"clb-c\"\u003e' + sub + '\u003c\/div\u003e\u003c\/span\u003e' +\n          '\u003cspan class=\"clb-price\"\u003e\u003cdiv class=\"clb-p\"\u003e' + money(t.total) + '\u003c\/div\u003e' + was + '\u003c\/span\u003e' +\n          '\u003c\/div\u003e';\n      });\n      box.innerHTML = html;\n    }\n    render();\n    form.parentNode.insertBefore(box, form);\n    function apply() {\n      var v = mainVariant();\n      tiers = tiersFor(v.price);\n      render();\n      setQty(1);\n      var t = tiers.filter(function (x) { return x.qty === chosen; })[0] || tiers[0];\n      var was = chosen === 1 ? (v.compare_at_price \u0026\u0026 v.compare_at_price \u003e v.price ? v.compare_at_price : 0) : v.price * chosen;\n      document.querySelectorAll('.product__info-container .price-item--sale, .product__info-container .price__regular .price-item--regular').forEach(function (el) { el.textContent = money(t.total); });\n      document.querySelectorAll('.product__info-container s.price-item--regular').forEach(function (el) { el.textContent = was ? money(was) : ''; el.style.display = was ? '' : 'none'; });\n    }\n    function items() {\n      var v = mainVariant();\n      var list = [{ id: v.id, quantity: 1 }];\n      for (var r = 0; r \u003c chosen - 1; r++) {\n        var ev = variantFor(extra[r].fin, extra[r].size) || v;\n        var hit = list.filter(function (x) { return x.id === ev.id; })[0];\n        if (hit) hit.quantity++; else list.push({ id: ev.id, quantity: 1 });\n      }\n      return list;\n    }\n    var busy = false;\n    function coreAdd(id, qty) {\n      var f = document.createElement('form');\n      f.method = 'post'; f.action = '\/cart\/add'; f.className = 'cl-core-add'; f.style.display = 'none';\n      f.innerHTML = '\u003cinput name=\"id\" value=\"' + id + '\"\u003e\u003cinput name=\"quantity\" value=\"' + qty + '\"\u003e';\n      document.body.appendChild(f);\n      if (f.requestSubmit) { f.requestSubmit(); } else { f.dispatchEvent(new Event('submit', { bubbles: true, cancelable: true })); }\n      setTimeout(function () { if (f.parentNode) f.parentNode.removeChild(f); }, 5000);\n    }\n    function addBundle() {\n      if (busy) return;\n      busy = true;\n      var btns = document.querySelectorAll('form[action*=\"\/cart\/add\"] button, #cl-sticky-btn');\n      Array.prototype.forEach.call(btns, function (b) { b.disabled = true; });\n      var list = items();\n      var first = list.shift();\n      var done = function () { coreAdd(first.id, first.quantity); setTimeout(function () { busy = false; Array.prototype.forEach.call(btns, function (b) { b.disabled = false; }); }, 1500); };\n      if (!list.length) { done(); return; }\n      fetch('\/cart\/add.js', { method: 'POST', credentials: 'same-origin', headers: { 'Content-Type': 'application\/json', 'Accept': 'application\/json' }, body: JSON.stringify({ items: list }) })\n        .then(function (r) { return r.json(); })\n        .then(done)\n        .catch(function () { busy = false; Array.prototype.forEach.call(btns, function (b) { b.disabled = false; }); });\n    }\n    function isAdd(el) {\n      if (!el) return false;\n      if (el.id === 'cl-sticky-btn') return true;\n      var f = el.closest \u0026\u0026 el.closest('form[action*=\"\/cart\/add\"]');\n      if (!f) return false;\n      return el.matches('button, [type=\"submit\"], .product-form__submit') || !!el.closest('button, [type=\"submit\"]');\n    }\n    document.addEventListener('click', function (e) {\n      var t = e.target;\n      var card = t \u0026\u0026 t.closest ? t.closest('#cl-sets .clb-card') : null;\n      if (card) { chosen = parseInt(card.getAttribute('data-qty'), 10) || 1; apply(); return; }\n      var opt = t \u0026\u0026 t.closest ? t.closest('#cl-sets .clb-opt') : null;\n      if (opt) {\n        var r = parseInt(opt.getAttribute('data-ring'), 10);\n        extra[r][opt.getAttribute('data-key')] = opt.getAttribute('data-val');\n        render();\n        return;\n      }\n      var btn = t \u0026\u0026 t.closest ? t.closest('button, [type=\"submit\"], #cl-sticky-btn') : null;\n      if (isAdd(btn)) { e.preventDefault(); e.stopImmediatePropagation(); addBundle(); }\n    }, true);\n    document.addEventListener('submit', function (e) {\n      if (e.target \u0026\u0026 e.target.matches \u0026\u0026 e.target.matches('form[action*=\"\/cart\/add\"]') \u0026\u0026 !e.target.classList.contains('cl-core-add')) { e.preventDefault(); e.stopImmediatePropagation(); addBundle(); }\n    }, true);\n    document.addEventListener('change', function (e) {\n      if (e.target \u0026\u0026 !e.target.closest('#cl-sets') \u0026\u0026 (e.target.type === 'radio' || e.target.tagName === 'SELECT')) setTimeout(apply, 60);\n    }, true);\n    setInterval(function () { setQty(1); }, 1200);\n    apply();\n  }\n  if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', boot); } else { boot(); }\n})();\n\u003c\/script\u003e\n","brand":"Clyro","offers":[{"title":"Silver \/ 5","offer_id":58722780741964,"sku":"CL-SR-SIL-05","price":21.95,"currency_code":"EUR","in_stock":true},{"title":"Silver \/ 6","offer_id":58722780774732,"sku":"CL-SR-SIL-06","price":21.95,"currency_code":"EUR","in_stock":true},{"title":"Silver \/ 7","offer_id":58722780807500,"sku":"CL-SR-SIL-07","price":21.95,"currency_code":"EUR","in_stock":true},{"title":"Silver \/ 8","offer_id":58722780840268,"sku":"CL-SR-SIL-08","price":21.95,"currency_code":"EUR","in_stock":true},{"title":"Silver \/ 9","offer_id":58722780873036,"sku":"CL-SR-SIL-09","price":21.95,"currency_code":"EUR","in_stock":true},{"title":"Silver \/ 10","offer_id":58722780905804,"sku":"CL-SR-SIL-10","price":21.95,"currency_code":"EUR","in_stock":true},{"title":"Silver \/ 11","offer_id":58722780938572,"sku":"CL-SR-SIL-11","price":21.95,"currency_code":"EUR","in_stock":true},{"title":"Silver \/ 12","offer_id":58722780971340,"sku":"CL-SR-SIL-12","price":21.95,"currency_code":"EUR","in_stock":true},{"title":"Gold \/ 5","offer_id":58722781004108,"sku":"CL-SR-GLD-05","price":21.95,"currency_code":"EUR","in_stock":true},{"title":"Gold \/ 6","offer_id":58722781036876,"sku":"CL-SR-GLD-06","price":21.95,"currency_code":"EUR","in_stock":true},{"title":"Gold \/ 7","offer_id":58722781069644,"sku":"CL-SR-GLD-07","price":21.95,"currency_code":"EUR","in_stock":true},{"title":"Gold \/ 8","offer_id":58722781102412,"sku":"CL-SR-GLD-08","price":21.95,"currency_code":"EUR","in_stock":true},{"title":"Gold \/ 9","offer_id":58722781135180,"sku":"CL-SR-GLD-09","price":21.95,"currency_code":"EUR","in_stock":true},{"title":"Gold \/ 10","offer_id":58722781167948,"sku":"CL-SR-GLD-10","price":21.95,"currency_code":"EUR","in_stock":true},{"title":"Gold \/ 11","offer_id":58722781200716,"sku":"CL-SR-GLD-11","price":21.95,"currency_code":"EUR","in_stock":true},{"title":"Gold \/ 12","offer_id":58722781233484,"sku":"CL-SR-GLD-12","price":21.95,"currency_code":"EUR","in_stock":true},{"title":"Rose Gold \/ 5","offer_id":58722781266252,"sku":"CL-SR-RGD-05","price":21.95,"currency_code":"EUR","in_stock":true},{"title":"Rose Gold \/ 6","offer_id":58722781299020,"sku":"CL-SR-RGD-06","price":21.95,"currency_code":"EUR","in_stock":true},{"title":"Rose Gold \/ 7","offer_id":58722781331788,"sku":"CL-SR-RGD-07","price":21.95,"currency_code":"EUR","in_stock":true},{"title":"Rose Gold \/ 8","offer_id":58722781364556,"sku":"CL-SR-RGD-08","price":21.95,"currency_code":"EUR","in_stock":true},{"title":"Rose Gold \/ 9","offer_id":58722781397324,"sku":"CL-SR-RGD-09","price":21.95,"currency_code":"EUR","in_stock":true},{"title":"Rose Gold \/ 10","offer_id":58722781430092,"sku":"CL-SR-RGD-10","price":21.95,"currency_code":"EUR","in_stock":true},{"title":"Rose Gold \/ 11","offer_id":58722781462860,"sku":"CL-SR-RGD-11","price":21.95,"currency_code":"EUR","in_stock":true},{"title":"Rose Gold \/ 12","offer_id":58722781495628,"sku":"CL-SR-RGD-12","price":21.95,"currency_code":"EUR","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/1079\/2524\/2188\/files\/b70c602e7b3a421cbd7f09a532ddf0ed_tplv-fhlh96nyum-crop-webp_800_800.jpg?v=1788842442","url":"https:\/\/clyro22.com\/products\/steel-spinner-ring","provider":"clyro","version":"1.0","type":"link"}