{
  "version": 3,
  "sources": ["/cdn/shop/t/56/assets/app.js?cb=1"],
  "sourcesContent": ["/* ==========================================================================\n   Aura Smart. Shared runtime\n   Chrome (header, menus, search, cart, footer), cart store, product cards,\n   and the motion layer. Pages call A.ready(fn) for page-specific code.\n   ========================================================================== */\n(() => {\n  const D = window.AURA;\n  const route = D.route;\n  const I = window.AURA_ICONS;\n  const root = document.documentElement;\n  root.classList.remove('no-js');\n  root.classList.add('js');\n  // ?noanim renders the final state instantly (QA screenshots); also honours reduced motion\n  const reduced = matchMedia('(prefers-reduced-motion: reduce)').matches || /[?&]noanim(?:&|=|$)/.test(location.search);\n  if (reduced) root.classList.add('reduce');\n  const fine = matchMedia('(hover: hover) and (pointer: fine)').matches;\n  const touch = matchMedia('(hover: none)').matches;   // the same test the touch styles in main.css use\n\n  /* ---------- a screen height that holds still ----------\n     On a phone the address bar slides in and out as you scroll, and many browsers (in-app\n     browsers especially) recompute viewport units each time. Everything sized from them, the\n     hero, the pinned story, the banner and the footer, would change height mid-scroll: the\n     hero photo re-crops, its clouds canvas is wiped, and the page below jumps. So touch screens\n     measure the screen once and keep it until the width changes (the phone is turned); the\n     keyboard opening doesn't count either. main.css sizes those sections from --screen.\n     --screen-full is the whole screen, for scenes that fill it (blackout-blinds.html): Safari on\n     iPhone draws the page on under its floating address bar, past the window, so a scene sized to\n     --screen left a band of page showing. Viewport units can't give it (100lvh measured just the\n     window on an iPhone, and units that move would make the page jump), so it's the device's\n     screen, the way up it's held (iOS reports it portrait-way round), measured with the rest.\n     This runs while the page is still being parsed, before any of them is laid out. */\n  if (touch) {\n    let w = innerWidth, t = 0;\n    const measure = () => {\n      // the larger of the window and the layout viewport (which toolbars don't move), in case an\n      // in-app browser reports a squashed window while the page is still loading\n      const h = Math.max(innerHeight, root.clientHeight);\n      const sides = [screen.width, screen.height], tall = innerWidth < innerHeight ? Math.max(...sides) : Math.min(...sides);\n      root.style.setProperty('--screen', `${h}px`);\n      root.style.setProperty('--screen-full', `${Math.max(h, tall)}px`);\n      root.classList.toggle('is-short-screen', h < 700);\n    };\n    measure();\n    // a turn shows up as a new width, either as a resize event or in the page's own box\n    const turned = () => { if (innerWidth === w) return; w = innerWidth; clearTimeout(t); t = setTimeout(measure, 150); };\n    addEventListener('resize', turned);\n    new ResizeObserver(turned).observe(root);\n  }\n\n  /* ---------- helpers ---------- */\n  const $ = (s, c = document) => c.querySelector(s);\n  const $$ = (s, c = document) => [...c.querySelectorAll(s)];\n  const esc = s => String(s).replace(/[&<>\"']/g, c => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' }[c]));\n  // made once: toLocaleString builds a new formatter on every call, and every price on a page goes through here\n  const euros = new Intl.NumberFormat('en-IE'), cents = new Intl.NumberFormat('en-IE', { minimumFractionDigits: 2, maximumFractionDigits: 2 });\n  const fmt = n => '\u20AC' + (Number.isInteger(n) ? euros : cents).format(n);\n  const icon = (n, cls = '') => `<svg class=\"ico ${cls}\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">${I[n] || ''}</svg>`;\n  const stars = (n = 5) => `<span class=\"stars\" aria-label=\"${n} out of 5 stars\">${Array.from({ length: 5 }, (_, i) => `<svg class=\"ico ico--fill${i < Math.round(n) ? '' : ' ico--off'}\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">${I.star}</svg>`).join('')}</span>`;\n  const qs = k => new URLSearchParams(location.search).get(k);\n  // Keep rendered copy and search/social previews together.\n  function seo({ title = document.title, description = $('meta[name=\"description\"]')?.content || '', image, type, noindex } = {}) {\n    const meta = (key, value, property = false) => {\n      const attr = property ? 'property' : 'name';\n      let el = $(`meta[${attr}=\"${key}\"]`);\n      if (!el) { el = document.createElement('meta'); el.setAttribute(attr, key); document.head.appendChild(el); }\n      el.content = value;\n    };\n    document.title = title;\n    meta('description', description);\n    meta('og:title', title, true);\n    meta('og:description', description, true);\n    meta('og:site_name', D.site.name, true);\n    meta('og:locale', 'en_IE', true);\n    if (type) meta('og:type', type, true);\n    if (image) meta('og:image', new URL(image, location.href).href, true);\n    if (noindex === true) meta('robots', 'noindex');\n    else if (noindex === false) $('meta[name=\"robots\"]')?.remove();\n  }\n  const page = window.AURA_PAGE || (location.pathname.split('/').pop() || 'index.html').replace(/\\.html$/, '') || 'index';\n  if (!D.shown(page)) location.replace(route('index.html'));   // a page that's switched off (data.js features)\n  const avColors = ['#2588C9', '#0D1116', '#5A7D9A', '#17699F', '#3B4A5A', '#6E8CA6'];\n  const initials = n => n.split(/\\s+/).map(w => w[0]).join('').slice(0, 2).toUpperCase();\n  const avColor = n => avColors[[...n].reduce((a, c) => a + c.charCodeAt(0), 0) % avColors.length];\n\n  // Paths from the brand SVG (assets/img/logo.svg)\n  const LOGO_PATHS = {\n    u1: 'M201.92,116v17.69c-13.54-1.63-25.4-8.15-35.36-19.4-11.49-12.94-17.42-28.78-17.6-47.09V2.06H165.4V67.12c.17,13.66,4.56,25.5,13.08,35.12,6.81,7.69,14.52,12.22,23.44,13.72',\n    u2: 'M268.81,2.06V67.29c-.24,18.29-6.19,34.11-17.69,47-9.95,11.2-21.78,17.68-35.26,19.31V115.94c8.87-1.52,16.56-6,23.37-13.63,8.51-9.56,12.93-21.33,13.15-35V2.06Z',\n    r: 'M283.73,132.87V63.95a61.87,61.87,0,0,1,18.61-45.32A62,62,0,0,1,347.5,0c2,0,4,.09,5.93.27L357,.6V17.86l-4.26-.41c-1.64-.16-3.36-.24-5.11-.24a44.84,44.84,0,0,0-33.07,13.69c-9.14,9.14-13.59,20-13.59,33.05v68.92Z',\n    a2: 'M424.11,134.41a64.85,64.85,0,0,1-47.39-19.65,64.85,64.85,0,0,1-19.65-47.39A65.16,65.16,0,0,1,376.81,20a67,67,0,0,1,94.77,0,64.56,64.56,0,0,1,19.56,47.4V133H474.46V111.63q-1.42,1.6-3,3.13a64.85,64.85,0,0,1-47.39,19.65m0-117.38a48.3,48.3,0,0,0-35.64,14.72,48.28,48.28,0,0,0-14.7,35.62A48.29,48.29,0,0,0,388.49,103a50.51,50.51,0,0,0,71.27,0,48.29,48.29,0,0,0,14.7-35.63,48.3,48.3,0,0,0-14.72-35.64A48.29,48.29,0,0,0,424.11,17',\n    a1: 'M67,134.41a64.85,64.85,0,0,1-47.39-19.65A64.85,64.85,0,0,1,0,67.38,65.16,65.16,0,0,1,19.73,20,64.85,64.85,0,0,1,67.12.34,64.86,64.86,0,0,1,114.51,20a64.56,64.56,0,0,1,19.56,47.4V133H117.38V111.63q-1.42,1.6-3,3.13A64.85,64.85,0,0,1,67,134.41M67,17A48.3,48.3,0,0,0,31.39,31.75a48.28,48.28,0,0,0-14.7,35.62A48.29,48.29,0,0,0,31.41,103,48.28,48.28,0,0,0,67,117.72,48.3,48.3,0,0,0,102.67,103a48.29,48.29,0,0,0,14.7-35.63,48.3,48.3,0,0,0-14.72-35.64A48.29,48.29,0,0,0,67,17',\n  };\n  const logoShapes = (attrs = {}) => ['u1', 'u2', 'r', 'a2', 'a1'].map(k => `<path ${attrs[k[0] === 'u' ? 'u' : 'ink'] || ''} d=\"${LOGO_PATHS[k]}\"/>`).join('');\n  const logo = (title = 'Aura Smart') => `<svg viewBox=\"0 0 491.15 134.41\" role=\"img\" aria-label=\"${title}\">${logoShapes({ u: 'class=\"logo-blue\"', ink: 'class=\"logo-ink\"' })}</svg>`;\n  // Header / mobile-menu logo: the \"u\" is top-lit with a soft gradient, and a light\n  // sheen (masked to the letterforms) can sweep across it. Aura-header.js plays the sheen.\n  let logoN = 0;\n  const logoFx = (title = 'Aura Smart') => {\n    const id = `lg${++logoN}`;\n    return `<svg class=\"logo-fx\" viewBox=\"0 0 491.15 134.41\" role=\"img\" aria-label=\"${title}\">\n      <defs>\n        <linearGradient id=\"${id}u\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#5DB2E8\"/><stop offset=\"1\" stop-color=\"#1F7BBF\"/></linearGradient>\n        <linearGradient id=\"${id}s\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"0\"><stop offset=\"0\" stop-color=\"#fff\" stop-opacity=\"0\"/><stop offset=\".5\" stop-color=\"#fff\" stop-opacity=\".7\"/><stop offset=\"1\" stop-color=\"#fff\" stop-opacity=\"0\"/></linearGradient>\n        <mask id=\"${id}m\" maskUnits=\"userSpaceOnUse\" x=\"0\" y=\"0\" width=\"491.15\" height=\"134.41\">${logoShapes({ u: 'fill=\"#fff\"', ink: 'fill=\"#fff\"' })}</mask>\n      </defs>\n      ${logoShapes({ u: `class=\"logo-blue\" style=\"fill:url(#${id}u)\"`, ink: 'class=\"logo-ink\"' })}\n      <g mask=\"url(#${id}m)\"><g class=\"logo-sheen\"><rect x=\"-110\" y=\"-20\" width=\"90\" height=\"175\" fill=\"url(#${id}s)\" transform=\"skewX(-18)\"/></g></g>\n    </svg>`;\n  };\n  // Footer wordmark, keeping watch at night: the bowls of the two a's are lenses\n  // with a glint on their inner rim (aura-watch.js turns them), and a soft glow\n  // behind the u breathes like a standby light. The u is top-lit like the header logo's.\n  const watchMark = () => {\n    // a 70\u00B0 arc just inside each bowl, pointing right until it's turned\n    const arc = 'M36.86,-25.81A45,45 0 0 1 36.86,25.81';\n    const lens = ([x, y]) => `<g class=\"watch-lens\" transform=\"translate(${x} ${y}) rotate(-90)\"><circle r=\"50\" fill=\"url(#lensSheen)\"/><path class=\"glint-soft\" d=\"${arc}\" filter=\"url(#glintBlur)\"/><path class=\"glint\" d=\"${arc}\"/></g>`;\n    return `<svg viewBox=\"0 0 491.15 134.41\" preserveAspectRatio=\"xMidYMax meet\">\n      <defs>\n        <linearGradient id=\"watchU\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#5DB2E8\"/><stop offset=\"1\" stop-color=\"#1F7BBF\"/></linearGradient>\n        <linearGradient id=\"glintFade\" gradientUnits=\"userSpaceOnUse\" x1=\"0\" y1=\"-26\" x2=\"0\" y2=\"26\"><stop offset=\"0\" stop-color=\"#A8D4F2\" stop-opacity=\"0\"/><stop offset=\".5\" stop-color=\"#E6F4FF\"/><stop offset=\"1\" stop-color=\"#A8D4F2\" stop-opacity=\"0\"/></linearGradient>\n        <radialGradient id=\"lensSheen\" gradientUnits=\"userSpaceOnUse\" cx=\"24\" cy=\"0\" r=\"46\"><stop offset=\"0\" stop-color=\"#79BDEB\" stop-opacity=\".1\"/><stop offset=\"1\" stop-color=\"#79BDEB\" stop-opacity=\"0\"/></radialGradient>\n        <filter id=\"glintBlur\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\"><feGaussianBlur stdDeviation=\"2.4\"/></filter>\n        <filter id=\"breathBlur\" x=\"-60%\" y=\"-40%\" width=\"220%\" height=\"180%\"><feGaussianBlur stdDeviation=\"8\"/></filter>\n      </defs>\n      <g class=\"watch-breath\" filter=\"url(#breathBlur)\"><path d=\"${LOGO_PATHS.u1}\"/><path d=\"${LOGO_PATHS.u2}\"/></g>\n      ${logoShapes({ u: 'class=\"logo-blue\"', ink: 'class=\"logo-ink\"' })}\n      ${lens([67, 67.37])}${lens([424.11, 67.37])}\n    </svg>`;\n  };\n\n  /* ---------- payment marks ----------\n     The card-shaped acceptance marks Shopify's own themes use (activemerchant/payment_icons,\n     MIT), drawn inline at 38 \u00D7 24. On Shopify the footer row becomes\n     {%- for type in shop.enabled_payment_types -%}{{ type | payment_type_svg_tag: class: 'pay-icon' }}{%- endfor -%}\n     so these show whatever payment methods the store has switched on. */\n  const PAY = {\n    visa: [\"Visa\", \"0 0 38 24\", '<rect x=\".5\" y=\".5\" width=\"37\" height=\"23\" rx=\"2.5\" stroke=\"#000\" stroke-opacity=\".07\" fill=\"none\"/><path d=\"M35 0H3C1.3 0 0 1.3 0 3V21C0 22.7 1.4 24 3 24H35C36.7 24 38 22.7 38 21V3C38 1.3 36.6 0 35 0Z\" fill=\"#142FBD\"/><path d=\"M35 1C36.1 1 37 1.9 37 3V21C37 22.1 36.1 23 35 23H3C1.9 23 1 22.1 1 21V3C1 1.9 1.9 1 3 1H35Z\" fill=\"#1532CB\"/><path d=\"M29.5944 10.2167H29.2778C28.8556 11.2722 28.5389 11.8 28.2222 13.3833H30.2278C29.9111 11.8 29.9111 11.0611 29.5944 10.2167V10.2167ZM32.6556 16.4444H30.8611C30.7556 16.4444 30.7556 16.4444 30.65 16.3389L30.4389 15.3889L30.3333 15.1778H27.8C27.6944 15.1778 27.5889 15.1778 27.5889 15.3889L27.2722 16.3389C27.2722 16.4444 27.1667 16.4444 27.1667 16.4444H24.95L25.1611 15.9167L28.2222 8.73889C28.2222 8.21111 28.5389 8 29.0667 8H30.65C30.7556 8 30.8611 8 30.8611 8.21111L32.3389 15.0722C32.4444 15.4944 32.55 15.8111 32.55 16.2333C32.6556 16.3389 32.6556 16.3389 32.6556 16.4444V16.4444ZM18.5111 16.1278L18.9333 14.2278C19.0389 14.2278 19.1444 14.3333 19.1444 14.3333C19.8833 14.65 20.6222 14.8611 21.3611 14.7556C21.5722 14.7556 21.8889 14.65 22.1 14.5444C22.6278 14.3333 22.6278 13.8056 22.2056 13.3833C21.9944 13.1722 21.6778 13.0667 21.3611 12.8556C20.9389 12.6444 20.5167 12.4333 20.2 12.1167C18.9333 11.0611 19.3556 9.58333 20.0944 8.84444C20.7278 8.42222 21.0444 8 21.8889 8C23.1556 8 24.5278 8 25.1611 8.21111H25.2667C25.1611 8.84444 25.0556 9.37222 24.8444 10.0056C24.3167 9.79444 23.7889 9.58333 23.2611 9.58333C22.9444 9.58333 22.6278 9.58333 22.3111 9.68889C22.1 9.68889 21.9944 9.79444 21.8889 9.9C21.6778 10.1111 21.6778 10.4278 21.8889 10.6389L22.4167 11.0611C22.8389 11.2722 23.2611 11.4833 23.5778 11.6944C24.1056 12.0111 24.6333 12.5389 24.7389 13.1722C24.95 14.1222 24.6333 14.9667 23.7889 15.6C23.2611 16.0222 23.05 16.2333 22.3111 16.2333C20.8333 16.2333 19.6722 16.3389 18.7222 16.0222C18.6167 16.2333 18.6167 16.2333 18.5111 16.1278V16.1278ZM14.8167 16.4444C14.9222 15.7056 14.9222 15.7056 15.0278 15.3889C15.5556 13.0667 16.0833 10.6389 16.5056 8.31667C16.6111 8.10556 16.6111 8 16.8222 8H18.7222C18.5111 9.26667 18.3 10.2167 17.9833 11.3778C17.6667 12.9611 17.35 14.5444 16.9278 16.1278C16.9278 16.3389 16.8222 16.3389 16.6111 16.3389L14.8167 16.4444ZM5 8.21111C5 8.10556 5.21111 8 5.31667 8H8.90556C9.43333 8 9.85556 8.31667 9.96111 8.84444L10.9111 13.4889C10.9111 13.5944 10.9111 13.5944 11.0167 13.7C11.0167 13.5944 11.1222 13.5944 11.1222 13.5944L13.3389 8.21111C13.2333 8.10556 13.3389 8 13.4444 8H15.6611C15.6611 8.10556 15.6611 8.10556 15.5556 8.21111L12.2833 15.9167C12.1778 16.1278 12.1778 16.2333 12.0722 16.3389C11.9667 16.4444 11.7556 16.3389 11.5444 16.3389H9.96111C9.85556 16.3389 9.75 16.3389 9.75 16.1278L8.06111 9.58333C7.85 9.37222 7.53333 9.05556 7.11111 8.95C6.47778 8.63333 5.31667 8.42222 5.10556 8.42222L5 8.21111Z\" fill=\"white\"/>'],\n    master: [\"Mastercard\", \"0 0 38 24\", '<rect x=\".5\" y=\".5\" width=\"37\" height=\"23\" rx=\"2.5\" stroke=\"#000\" stroke-opacity=\".07\" fill=\"none\"/><path d=\"M35 0H3C1.3 0 0 1.3 0 3V21C0 22.7 1.4 24 3 24H35C36.7 24 38 22.7 38 21V3C38 1.3 36.6 0 35 0Z\" fill=\"#1C1C1C\"/><path d=\"M35 1C36.1 1 37 1.9 37 3V21C37 22.1 36.1 23 35 23H3C1.9 23 1 22.1 1 21V3C1 1.9 1.9 1 3 1H35Z\" fill=\"#232323\"/><path d=\"M14.6364 19.2727C18.8538 19.2727 22.2727 15.8538 22.2727 11.6364C22.2727 7.41892 18.8538 4 14.6364 4C10.4189 4 7 7.41892 7 11.6364C7 15.8538 10.4189 19.2727 14.6364 19.2727Z\" fill=\"#EB001B\"/><path d=\"M23.3637 19.2727C27.5811 19.2727 31 15.8538 31 11.6364C31 7.41892 27.5811 4 23.3637 4C19.1462 4 15.7273 7.41892 15.7273 11.6364C15.7273 15.8538 19.1462 19.2727 23.3637 19.2727Z\" fill=\"#F79E1B\"/><path d=\"M22.2727 11.6362C22.2727 9.01797 20.9637 6.72706 19 5.41797C17.0364 6.83615 15.7273 9.12706 15.7273 11.6362C15.7273 14.1452 17.0364 16.5452 19 17.8543C20.9637 16.5452 22.2727 14.2543 22.2727 11.6362Z\" fill=\"#FF5F00\"/>'],\n    apple_pay: [\"Apple Pay\", \"0 0 165.521 105.965\", '<path fill=\"#000\" d=\"M150.698 0H14.823c-.566 0-1.133 0-1.698.003-.477.004-.953.009-1.43.022-1.039.028-2.087.09-3.113.274a10.51 10.51 0 0 0-2.958.975 9.932 9.932 0 0 0-4.35 4.35 10.463 10.463 0 0 0-.975 2.96C.113 9.611.052 10.658.024 11.696a70.22 70.22 0 0 0-.022 1.43C0 13.69 0 14.256 0 14.823v76.318c0 .567 0 1.132.002 1.699.003.476.009.953.022 1.43.028 1.036.09 2.084.275 3.11a10.46 10.46 0 0 0 .974 2.96 9.897 9.897 0 0 0 1.83 2.52 9.874 9.874 0 0 0 2.52 1.83c.947.483 1.917.79 2.96.977 1.025.183 2.073.245 3.112.273.477.011.953.017 1.43.02.565.004 1.132.004 1.698.004h135.875c.565 0 1.132 0 1.697-.004.476-.002.952-.009 1.431-.02 1.037-.028 2.085-.09 3.113-.273a10.478 10.478 0 0 0 2.958-.977 9.955 9.955 0 0 0 4.35-4.35c.483-.947.789-1.917.974-2.96.186-1.026.246-2.074.274-3.11.013-.477.02-.954.022-1.43.004-.567.004-1.132.004-1.699V14.824c0-.567 0-1.133-.004-1.699a63.067 63.067 0 0 0-.022-1.429c-.028-1.038-.088-2.085-.274-3.112a10.4 10.4 0 0 0-.974-2.96 9.94 9.94 0 0 0-4.35-4.35A10.52 10.52 0 0 0 156.939.3c-1.028-.185-2.076-.246-3.113-.274a71.417 71.417 0 0 0-1.431-.022C151.83 0 151.263 0 150.698 0z\" /><path fill=\"#FFF\" d=\"M150.698 3.532l1.672.003c.452.003.905.008 1.36.02.793.022 1.719.065 2.583.22.75.135 1.38.34 1.984.648a6.392 6.392 0 0 1 2.804 2.807c.306.6.51 1.226.645 1.983.154.854.197 1.783.218 2.58.013.45.019.9.02 1.36.005.557.005 1.113.005 1.671v76.318c0 .558 0 1.114-.004 1.682-.002.45-.008.9-.02 1.35-.022.796-.065 1.725-.221 2.589a6.855 6.855 0 0 1-.645 1.975 6.397 6.397 0 0 1-2.808 2.807c-.6.306-1.228.511-1.971.645-.881.157-1.847.2-2.574.22-.457.01-.912.017-1.379.019-.555.004-1.113.004-1.669.004H14.801c-.55 0-1.1 0-1.66-.004a74.993 74.993 0 0 1-1.35-.018c-.744-.02-1.71-.064-2.584-.22a6.938 6.938 0 0 1-1.986-.65 6.337 6.337 0 0 1-1.622-1.18 6.355 6.355 0 0 1-1.178-1.623 6.935 6.935 0 0 1-.646-1.985c-.156-.863-.2-1.788-.22-2.578a66.088 66.088 0 0 1-.02-1.355l-.003-1.327V14.474l.002-1.325a66.7 66.7 0 0 1 .02-1.357c.022-.792.065-1.717.222-2.587a6.924 6.924 0 0 1 .646-1.981c.304-.598.7-1.144 1.18-1.623a6.386 6.386 0 0 1 1.624-1.18 6.96 6.96 0 0 1 1.98-.646c.865-.155 1.792-.198 2.586-.22.452-.012.905-.017 1.354-.02l1.677-.003h135.875\" /><g><g><path fill=\"#000\" d=\"M43.508 35.77c1.404-1.755 2.356-4.112 2.105-6.52-2.054.102-4.56 1.355-6.012 3.112-1.303 1.504-2.456 3.959-2.156 6.266 2.306.2 4.61-1.152 6.063-2.858\" /><path fill=\"#000\" d=\"M45.587 39.079c-3.35-.2-6.196 1.9-7.795 1.9-1.6 0-4.049-1.8-6.698-1.751-3.447.05-6.645 2-8.395 5.1-3.598 6.2-.95 15.4 2.55 20.45 1.699 2.5 3.747 5.25 6.445 5.151 2.55-.1 3.549-1.65 6.647-1.65 3.097 0 3.997 1.65 6.696 1.6 2.798-.05 4.548-2.5 6.247-5 1.95-2.85 2.747-5.6 2.797-5.75-.05-.05-5.396-2.101-5.446-8.251-.05-5.15 4.198-7.6 4.398-7.751-2.399-3.548-6.147-3.948-7.447-4.048\" /></g><g><path fill=\"#000\" d=\"M78.973 32.11c7.278 0 12.347 5.017 12.347 12.321 0 7.33-5.173 12.373-12.529 12.373h-8.058V69.62h-5.822V32.11h14.062zm-8.24 19.807h6.68c5.07 0 7.954-2.729 7.954-7.46 0-4.73-2.885-7.434-7.928-7.434h-6.706v14.894z\" /><path fill=\"#000\" d=\"M92.764 61.847c0-4.809 3.665-7.564 10.423-7.98l7.252-.442v-2.08c0-3.04-2.001-4.704-5.562-4.704-2.938 0-5.07 1.507-5.51 3.82h-5.252c.157-4.86 4.731-8.395 10.918-8.395 6.654 0 10.995 3.483 10.995 8.89v18.663h-5.38v-4.497h-.13c-1.534 2.937-4.914 4.782-8.579 4.782-5.406 0-9.175-3.222-9.175-8.057zm17.675-2.417v-2.106l-6.472.416c-3.64.234-5.536 1.585-5.536 3.95 0 2.288 1.975 3.77 5.068 3.77 3.95 0 6.94-2.522 6.94-6.03z\" /><path fill=\"#000\" d=\"M120.975 79.652v-4.496c.364.051 1.247.103 1.715.103 2.573 0 4.029-1.09 4.913-3.899l.52-1.663-9.852-27.293h6.082l6.863 22.146h.13l6.862-22.146h5.927l-10.216 28.67c-2.34 6.577-5.017 8.735-10.683 8.735-.442 0-1.872-.052-2.261-.157z\" /></g></g>'],\n    google_pay: [\"Google Pay\", \"0 0 38 24\", '<path d=\"M35 0H3C1.3 0 0 1.3 0 3v18c0 1.7 1.4 3 3 3h32c1.7 0 3-1.3 3-3V3c0-1.7-1.4-3-3-3z\" fill=\"#000\" opacity=\".07\"/><path d=\"M35 1c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2h32\" fill=\"#FFF\"/><path d=\"M18.093 11.976v3.2h-1.018v-7.9h2.691a2.447 2.447 0 0 1 1.747.692 2.28 2.28 0 0 1 .11 3.224l-.11.116c-.47.447-1.098.69-1.747.674l-1.673-.006zm0-3.732v2.788h1.698c.377.012.741-.135 1.005-.404a1.391 1.391 0 0 0-1.005-2.354l-1.698-.03zm6.484 1.348c.65-.03 1.286.188 1.778.613.445.43.682 1.03.65 1.649v3.334h-.969v-.766h-.049a1.93 1.93 0 0 1-1.673.931 2.17 2.17 0 0 1-1.496-.533 1.667 1.667 0 0 1-.613-1.324 1.606 1.606 0 0 1 .613-1.336 2.746 2.746 0 0 1 1.698-.515c.517-.02 1.03.093 1.49.331v-.208a1.134 1.134 0 0 0-.417-.901 1.416 1.416 0 0 0-.98-.368 1.545 1.545 0 0 0-1.319.717l-.895-.564a2.488 2.488 0 0 1 2.182-1.06zM23.29 13.52a.79.79 0 0 0 .337.662c.223.176.5.269.785.263.429-.001.84-.17 1.146-.472.305-.286.478-.685.478-1.103a2.047 2.047 0 0 0-1.324-.374 1.716 1.716 0 0 0-1.03.294.883.883 0 0 0-.392.73zm9.286-3.75l-3.39 7.79h-1.048l1.281-2.728-2.224-5.062h1.103l1.612 3.885 1.569-3.885h1.097z\" fill=\"#5F6368\"/><path d=\"M13.986 11.284c0-.308-.024-.616-.073-.92h-4.29v1.747h2.451a2.096 2.096 0 0 1-.9 1.373v1.134h1.464a4.433 4.433 0 0 0 1.348-3.334z\" fill=\"#4285F4\"/><path d=\"M9.629 15.721a4.352 4.352 0 0 0 3.01-1.097l-1.466-1.14a2.752 2.752 0 0 1-4.094-1.44H5.577v1.17a4.53 4.53 0 0 0 4.052 2.507z\" fill=\"#34A853\"/><path d=\"M7.079 12.05a2.709 2.709 0 0 1 0-1.735v-1.17H5.577a4.505 4.505 0 0 0 0 4.075l1.502-1.17z\" fill=\"#FBBC04\"/><path d=\"M9.629 8.44a2.452 2.452 0 0 1 1.74.68l1.3-1.293a4.37 4.37 0 0 0-3.065-1.183 4.53 4.53 0 0 0-4.027 2.5l1.502 1.171a2.715 2.715 0 0 1 2.55-1.875z\" fill=\"#EA4335\"/>'],\n  };\n  const payIcon = k => { const [name, vb, body] = PAY[k]; return `<svg class=\"pay-icon\" viewBox=\"${vb}\" role=\"img\" aria-label=\"${name}\">${body}</svg>`; };\n\n  /* ---------- cart store ---------- */\n  const KEY = 'aura-cart-v1';\n  // a saved line for a product that has left the catalogue is dropped, not shown broken\n  const load = () => { try { return (JSON.parse(localStorage.getItem(KEY)) || []).filter(i => D.byHandle(i?.handle)); } catch { return []; } };\n  const save = items => { try { localStorage.setItem(KEY, JSON.stringify(items)); } catch {} };\n  const Cart = window.createAuraShopifyCart ? window.createAuraShopifyCart(D) : {\n    items: load(),\n    key: (h, v, c) => [h, v, c || ''].join('|'),\n    priceOf(line) { const p = D.byHandle(line.handle); return p ? p.price[line.variant === 'diy' ? 1 : 0] : 0; },\n    add(handle, variant = 'pro', color = null, qty = 1) {\n      const p = D.byHandle(handle); if (!p) return;\n      if (p.colors && !color) color = p.colors[0].name;\n      const k = this.key(handle, variant, color);\n      const ex = this.items.find(i => i.key === k);\n      if (ex) ex.qty += qty; else this.items.push({ key: k, handle, variant, color, qty });\n      this.commit();\n      bumpBadge();\n    },\n    set(key, qty) { const it = this.items.find(i => i.key === key); if (!it) return; it.qty = Math.max(0, Math.min(20, qty)); if (!it.qty) this.items = this.items.filter(i => i !== it); this.commit(); },\n    remove(key) { this.items = this.items.filter(i => i.key !== key); this.commit(); },\n    // switch a line between Pro and DIY where it stands (merging if that version is already in the cart)\n    setVariant(key, variant) {\n      const it = this.items.find(i => i.key === key); if (!it || it.variant === variant) return;\n      const k = this.key(it.handle, variant, it.color), dup = this.items.find(i => i.key === k);\n      if (dup) { dup.qty = Math.min(20, dup.qty + it.qty); this.items = this.items.filter(i => i !== it); }\n      else { it.variant = variant; it.key = k; }\n      this.commit();\n    },\n    clear() { this.items = []; this.commit(); },\n    count() { return this.items.reduce((a, i) => a + i.qty, 0); },\n    subtotal() { return this.items.reduce((a, i) => a + this.priceOf(i) * i.qty, 0); },\n    compareTotal() { return this.items.reduce((a, i) => a + (D.byHandle(i.handle)?.compare || this.priceOf(i)) * i.qty, 0); },\n    hasPro() { return this.items.some(i => i.variant === 'pro'); },\n    commit() { save(this.items); document.dispatchEvent(new CustomEvent('cart:change')); },\n  };\n  window.addEventListener('storage', e => { if (!window.createAuraShopifyCart && e.key === KEY) { Cart.items = load(); document.dispatchEvent(new CustomEvent('cart:change')); } });\n\n  /* ---------- recently viewed (product.html records each visit, newest first) ---------- */\n  const RECENT = 'aura-recent';\n  const recent = (exclude = []) => {\n    let list = []; try { list = JSON.parse(localStorage.getItem(RECENT)) || []; } catch {}\n    return list.filter(h => !exclude.includes(h)).map(D.byHandle).filter(Boolean);\n  };\n  const markViewed = handle => { try { const r = [handle, ...recent([handle]).map(p => p.handle)]; localStorage.setItem(RECENT, JSON.stringify(r.slice(0, 8))); } catch {} };\n\n  /* ---------- product card ---------- */\n  // Status chips on cards / gallery: New (from catalogue badge) + Best seller (handle list).\n  // Feature chips (Wire-Free, SD Card, door-fit, etc.) removed per draft feedback.\n  const CARD_BESTSELLER = ['smart-lock-slim', 'solar-camera-pro', 'video-door-phone', 'floodlight-camera'];\n  // Card price, as on the product page: installed (Pro) variant is the headline, the DIY variant\n  // underneath, and a saving only where the installed variant's compare-at is above its price.\n  function cardPrice(p) {\n    const vs = p.variants || [];\n    const pro = vs.find(v => v.mode === 'pro');\n    const diyVariant = vs.find(v => v.mode === 'diy');\n    const main = pro || diyVariant || vs[0];\n    const installed = main ? +main.price || 0 : +(p.price && p.price[0]) || 0;\n    const compare = main ? +main.compare || 0 : +p.compare || 0;\n    const seedDiy = +(p.price && p.price[1]) || 0;\n    const diy = main ? (pro && diyVariant ? +diyVariant.price : null) : (seedDiy && seedDiy !== installed ? seedDiy : null);\n    const diyCompare = pro && diyVariant ? +diyVariant.compare || 0 : 0;\n    const installedSale = compare > installed;\n    const diySale = diy != null && diyCompare > diy;\n    const salePercent = installedSale ? Math.round((compare - installed) / compare * 100) : diySale ? Math.round((diyCompare - diy) / diyCompare * 100) : 0;\n    return { installed, diy, compare, diyCompare, salePercent, save: installedSale ? compare - installed : 0 };\n  }\n\n  function productCard(p, { idx = 0, alt = true, mode = 'from' } = {}) {\n    // the second photo only shows on hover (main.css), so a touch screen, which can't hover, never loads it\n    const altImg = alt && !touch && p.hover;\n    const pr = cardPrice(p);\n    const status = [];\n    if (p.badge === 'New') status.push('<span class=\"badge badge--blue badge--new\">New</span>');\n    if (CARD_BESTSELLER.includes(p.handle)) status.push('<span class=\"badge badge--blue\">Best seller</span>');\n    const chips = status.join('');\n    const markup = `\n    <article data-product-handle=\"${esc(p.handle)}\" class=\"pcard ${altImg ? 'has-alt' : ''}\" data-reveal style=\"--d:${(idx % 4) * 80};--tint:${p.tint || '#E8E5DF'}\">\n      <div class=\"pcard__media\">\n        <div class=\"pcard__badges\"><span class=\"pcard__chips\">${chips}</span>${pr.salePercent > 0 ? `<span class=\"pcard__badges-end\"><span class=\"badge badge--sale\">-${pr.salePercent}%</span></span>` : ''}</div>\n        <div class=\"pcard__img pcard__img--main\"><img src=\"${p.images[0]}\" alt=\"${esc(p.name)}\" loading=\"lazy\" width=\"600\" height=\"600\"></div>\n        ${altImg ? `<div class=\"pcard__img pcard__img--alt\"><img src=\"${altImg}\" alt=\"\" loading=\"lazy\" style=\"object-position:${p.hoverAt}\"></div>` : ''}\n        <div class=\"pcard__quick\"><button class=\"btn btn--light btn--noarrow\" type=\"button\" data-quick=\"${p.handle}\">${icon('plus')} Quick add</button></div>\n        <button class=\"pcard__add\" type=\"button\" data-quick=\"${p.handle}\" aria-label=\"Quick add ${esc(p.name)}\">${icon('plus')}</button>\n      </div>\n      <div class=\"pcard__body\">\n        <div class=\"pcard__row\">\n          <h3 class=\"pcard__name\"><a href=\"${route(`product.html?p=${p.handle}`)}\">${esc(p.name)}</a></h3>\n          ${p.colors ? `<div class=\"pcard__swatches\" aria-label=\"${p.colors.length} finishes\" data-handle=\"${p.handle}\">${A.cardColors(p.colors).map(c => `<span class=\"swatch-dot\" style=\"--c:${c.hex}\" role=\"img\" aria-label=\"${esc(c.name)}\" data-color=\"${esc(c.name)}\"></span>`).join('')}</div>` : ''}\n        </div>\n        <div class=\"pcard__type\">${esc(p.tagline)}</div>\n        <div class=\"pcard__row pcard__foot\">\n          <span class=\"price pcard__price\"><span class=\"pcard__now\">${pr.diy != null ? '<span class=\"sr-only\">Installed price </span>' : ''}<span class=\"pcard__amt\">${fmt(pr.installed)}</span>${pr.compare > pr.installed ? `<s class=\"pcard__was\">${fmt(pr.compare)}</s>` : ''}${pr.diy != null ? '<span class=\"install-pill\" title=\"Installation included\">Installation incl.</span>' : ''}</span>${pr.diy != null ? `<small class=\"pcard__diy\">DIY ${fmt(pr.diy)}${pr.diyCompare > pr.diy ? `<s>${fmt(pr.diyCompare)}</s>` : ''}</small>` : ''}</span>\n          \n        </div>\n      </div>\n    </article>`;\n    return markup;\n  }\n\n\n  /* ---------- shared renderers ---------- */\n  // A review from Google or Facebook (Shopify's `reviews-data` snippet, window.AURA_REVIEWS) says\n  // where it was written; a Facebook recommendation has no stars. Long ones are cut to the length of the\n  // longest testimonial the rows were designed with, so one review doesn't make its row tall.\n  const REVIEW_SITES = { google: 'Google review', facebook: 'Facebook review' };\n  const clip = (t, n = 220) => t.length > n ? t.slice(0, t.lastIndexOf(' ', n)).replace(/[\\s,.;:!?\u2013\u2014-]+$/, '') + '\u2026' : t;\n  const reviewCard = r => {\n    const show = window.AURA_REVIEWS?.show || {};\n    const site = REVIEW_SITES[r.source], link = site && window.AURA_REVIEWS?.links?.[r.source];\n    // The whole card links to the site the review was written on, so the site name below is plain text (no link inside a link).\n    const mark = site && show.source !== false ? `<span class=\"rcard__src\">${icon(r.source)} ${site}</span>` : `<span>${icon('check-circle')} Aura Smart customer</span>`;\n    const score = site && r.rating === null ? `<span class=\"rcard__rec\">${icon('check-circle')} Recommends</span>` : stars(r.rating ?? 5);\n    const tag = r.tag && show.tags !== false ? `<span class=\"pill pill--blue rcard__tag\">${esc(r.tag)}</span>` : '';\n    const who = link ? 'div' : 'figcaption';\n    const body = `<div class=\"rcard__top\">${score}${tag}</div><blockquote class=\"rcard__text\">\u201C${esc(clip(r.text))}\u201D</blockquote><${who} class=\"rcard__who\"><span class=\"avatar\" style=\"--av:${avColor(r.name)}\">${initials(r.name)}</span><div><b>${esc(r.name)}</b>${mark}</div></${who}>`;\n    return link ? `<a class=\"rcard\" href=\"${esc(link)}\" target=\"_blank\" rel=\"noopener\">${body}</a>` : `<figure class=\"rcard\">${body}</figure>`;\n  };\n  // Rows gliding opposite ways, laid out as theme settings \u2192 Reviews says (window.AURA_REVIEWS.show):\n  // \"split\", Google on top and Facebook below (\"split_reverse\" the other way round); \"mixed\", both\n  // sites newest first, shared between the rows; \"google\" or \"facebook\", that site only. One row holds\n  // them all in the same order, as does one site with under 6 reviews. Without live reviews, the given\n  // reviews. A short row repeats its cards so it still fills a wide screen.\n  const reviewRows = (list = D.reviews) => {\n    const live = window.AURA_REVIEWS || {}, show = live.show || {};\n    const per = show.perRow || 12, two = (show.rows || 2) > 1;\n    const newest = l => [...(l || [])].sort((a, b) => (b.date || '').localeCompare(a.date || ''));\n    const g = newest(live.google).slice(0, per), f = newest(live.facebook).slice(0, per);\n    const halves = l => { const half = Math.ceil(l.length / 2); return [l.slice(0, half), l.slice(half)]; };\n    const alternate = l => [l.filter((_, i) => i % 2 === 0), l.filter((_, i) => i % 2)];\n    let rows;\n    if (!g.length && !f.length) rows = two ? halves(list) : [list];\n    else if (show.layout === 'mixed') { const all = newest([...g, ...f]).slice(0, two ? per * 2 : per); rows = two ? alternate(all) : [all]; }\n    else {\n      const [a, b] = show.layout === 'split_reverse' ? [f, g] : [g, f];\n      const one = a.length ? a : b;\n      rows = a.length && b.length ? (two ? [a, b] : [[...a, ...b].slice(0, per)]) : (two && one.length >= 6 ? halves(one) : [one]);\n    }\n    const fill = row => { let out = row; while (row.length && out.length < 4) out = out.concat(row); return out; };\n    return rows.filter(row => row.length).map((row, i) => `<div class=\"marquee ${i ? 'marquee--rev' : ''}\"><div class=\"marquee__track\">${fill(row).map(reviewCard).join('')}</div></div>`).join('');\n  };\n  const faqHTML = (items, openFirst = true) => items.map(([q, a], i) => `<details class=\"acc__item\" ${openFirst && i === 0 ? 'open' : ''}><summary>${esc(q)}<span class=\"acc__icon\">${icon('plus')}</span></summary><div class=\"acc__content\"><div>${esc(a)}</div></div></details>`).join('');\n  const jcard = (a, i = 0) => `<article class=\"jcard\" data-reveal style=\"--d:${(i % 3) * 100}\"><div class=\"jcard__media\"><img src=\"${a.image}\" alt=\"\" loading=\"lazy\"></div><div class=\"jcard__meta\"><span class=\"pill\">${esc(a.tag)}</span><span>${a.minutes} min read</span></div><h3><a href=\"${route(`article.html?a=${a.slug}`)}\">${esc(a.title)}</a></h3></article>`;\n\n  /* ---------- chrome markup ---------- */\n  // Announcement bar messages (on Shopify: blocks in the announcement section).\n  // `short` is the phone version, so nothing gets cut off with an ellipsis.\n  const announceMsgs = [\n    { icon: 'sparkle', text: 'Planning several devices? Ask for a bundle quote', short: 'Ask for a bundle quote', cta: 'Get a quote', href: 'contact.html#quote' },\n    { icon: 'euro', text: 'Use local recordings without a required subscription', short: 'No required subscription', cta: 'Storage details', href: 'faq.html?q=monthly%20fees' },\n    { icon: 'tools', text: 'Pro installation across Dublin, Cork, Galway and County Meath', short: 'Pro install: Dublin, Cork, Galway &amp; Meath', cta: 'See fitted prices', href: 'pro-installation.html' },\n    { icon: 'shield-plain', text: '18-month warranty on every device', short: '18-month warranty on everything', cta: 'Warranty terms', href: 'faq.html?q=warranty' },\n  ];\n\n  // Markup only (the future sections/header.liquid). Behaviour lives in\n  // src/header/aura-header.js, which upgrades <aura-header> when it loads.\n  function headerHTML() {\n    const cols = D.collections.filter(c => c.handle !== 'all');\n    const featured = ['floodlight-camera', 'smart-lock', 'solar-camera-pro', 'indoorcam-p1'].map(D.byHandle);\n    const cap = s => s.replace(/^./, m => m.toUpperCase());\n    const onShop = page === 'shop' || page === 'product';\n    const curCat = page === 'shop' ? qs('c') || 'all' : null;\n    const prod = (p, pair) => `<a class=\"mega__prod\" href=\"${route(`product.html?p=${p.handle}`)}\"><span class=\"media\" style=\"--tint:${p.tint}\"><img src=\"${p.images[0]}\" alt=\"\" loading=\"lazy\">${pair ? '<span class=\"mega__tag\">Pairs well</span>' : ''}</span><b>${p.name}</b><span>${fmt(p.from)}</span></a>`;\n    // One panel per category. Small categories are topped up with bestsellers that pair well with them.\n    const panel = (handle, title, own, total) => {\n      const fill = featured.filter(p => !own.includes(p)).slice(0, Math.max(0, 4 - own.length));\n      return `<div class=\"mega__panel\" data-mega-panel=\"${handle}\" ${handle === 'all' ? '' : 'hidden'}>\n        <div class=\"mega__head\"><b>${title}</b><a class=\"link small\" href=\"${route(`shop.html${handle === 'all' ? '' : '?c=' + handle}`)}\">View all ${total} ${icon('arrow')}</a></div>\n        <div class=\"mega__products\">${own.slice(0, 4).map(p => prod(p)).join('')}${fill.map(p => prod(p, true)).join('')}</div>\n      </div>`;\n    };\n    return `\n    <a class=\"skip-link\" href=\"#main\">Skip to content</a>\n    <aura-announce class=\"announce\" role=\"region\" aria-label=\"Announcements\">\n      <div class=\"container announce__inner\">\n        <div class=\"announce__side\"><a href=\"${D.site.phoneHref}\">${icon('phone')} ${D.site.phone}</a><a href=\"${D.site.whatsappHref}\" target=\"_blank\" rel=\"noopener\">${icon('whatsapp')} WhatsApp us</a></div>\n        <div class=\"announce__center\">\n          <button class=\"announce__nav\" type=\"button\" data-announce-step=\"-1\" aria-label=\"Previous announcement\">${icon('chevron-left')}</button>\n          <div class=\"announce__track\" aria-live=\"off\">${announceMsgs.map((m, i) => `<a class=\"announce__msg ${i === 0 ? 'is-active' : ''}\" href=\"${route(m.href)}\" ${i === 0 ? '' : 'inert'}>${icon(m.icon)}<span class=\"announce__text\"><span class=\"announce__long\">${m.text}</span><span class=\"announce__short\">${m.short}</span></span><span class=\"announce__cta\">${m.cta}${icon('arrow')}</span></a>`).join('')}</div>\n          <button class=\"announce__nav\" type=\"button\" data-announce-step=\"1\" aria-label=\"Next announcement\">${icon('chevron-right')}</button>\n        </div>\n        <div class=\"announce__side\"><a class=\"announce__rating\" href=\"${route(`index.html#reviews`)}\">${stars()}<span><b>${D.site.rating}</b> from ${D.site.reviewCount} reviews</span>${icon('arrow')}</a></div>\n      </div>\n    </aura-announce>\n    <header class=\"site-header\" id=\"siteHeader\">\n      <aura-header class=\"container\">\n        <nav class=\"nav-bar\" aria-label=\"Main\">\n          <span class=\"nav-pill\" aria-hidden=\"true\"></span>\n          <a class=\"brand\" href=\"${route(`index.html`)}\" aria-label=\"Aura Smart home\">${logoFx()}</a>\n          <ul class=\"nav-links\" role=\"list\">\n            ${D.nav.map(n => n.mega\n              ? `<li class=\"nav-mega\"><button type=\"button\" aria-expanded=\"false\" aria-controls=\"mega\" data-mega-toggle ${onShop ? 'data-current' : ''}>${n.label} ${icon('chevron')}</button>${megaHTML()}</li>`\n              : `<li><a href=\"${route(n.href)}\" ${page === n.href.replace('.html', '') ? 'aria-current=\"page\"' : ''}>${n.label}</a></li>`).join('')}\n          </ul>\n          <div class=\"nav-actions\">\n            <button class=\"icon-btn\" type=\"button\" data-search-open aria-label=\"Search\">${icon('search')}</button>\n            <a class=\"icon-btn hide-sm\" href=\"${D.site.whatsappHref}\" target=\"_blank\" rel=\"noopener\" aria-label=\"WhatsApp us\">${icon('whatsapp')}</a>\n            <button class=\"icon-btn\" type=\"button\" data-cart-open aria-label=\"Open cart\">${icon('bag')}<span class=\"count-badge\" data-cart-count>0</span></button>\n            <a class=\"btn btn--sm btn--blue nav-cta\" href=\"${route(`contact.html#quote`)}\">Free quote</a>\n            <button class=\"icon-btn nav-toggle\" type=\"button\" data-mnav-open aria-label=\"Open menu\" aria-expanded=\"false\">${icon('menu')}</button>\n          </div>\n        </nav>\n      </aura-header>\n    </header>\n    <div class=\"mega-scrim\" data-mega-scrim></div>`;\n\n    // Lives inside the Shop <li> so Tab moves from the Shop button straight into the menu\n    function megaHTML() {\n      const catLink = (handle, title, n) => `<a class=\"mega__col-link ${handle === 'all' ? 'is-active' : ''}\" href=\"${route(`shop.html${handle === 'all' ? '' : '?c=' + handle}`)}\" data-mega-cat=\"${handle}\" ${curCat === handle ? 'aria-current=\"page\"' : ''}>${title} <small>${n}</small></a>`;\n      return `\n          <div class=\"mega\" id=\"mega\" role=\"region\" aria-label=\"Shop menu\">\n            <div class=\"mega__cols\">\n              <span class=\"eyebrow\">Shop by category</span>\n              ${catLink('all', 'Shop all', D.products.length)}\n              ${cols.map(c => catLink(c.handle, cap(c.title), D.inCollection(c.handle).length)).join('')}\n            </div>\n            <div class=\"mega__panels\">\n              ${panel('all', 'Bestsellers', featured, D.products.length)}\n              ${cols.map(c => panel(c.handle, cap(c.title), D.inCollection(c.handle), D.inCollection(c.handle).length)).join('')}\n            </div>\n            <a class=\"mega__promo\" href=\"${route(`pro-installation.html`)}\">\n              <img src=\"${D.asset('assets/img/card-pro-install.webp')}\" alt=\"\" loading=\"lazy\">\n              <span class=\"pill pill--glass\">${icon('tools')} Pro installation</span>\n              <h4>Fitted by licensed installers</h4>\n              <p>Dublin, Cork, Galway and County Meath. Typically 40 minutes to 2 hours.</p>\n            </a>\n          </div>`;\n    }\n  }\n\n  // Mobile menu: search, then shopping (swipeable categories), then the rest.\n  // The quote button sits in a footer outside the scroll area so it's always in reach.\n  function mnavHTML() {\n    const links = [['Pro installation', 'pro-installation.html', 'Book'], ['App', 'index.html#app', 'iPhone & Android'], ['Smart blinds', 'smart-blinds.html', 'New'], ['Blackout blinds', 'blackout-blinds.html', 'Guard'], ['Showroom', 'showroom.html', 'Bray'], ['About', 'about.html', ''], ['Journal', 'journal.html', ''], ['Support & FAQ', 'faq.html', ''], ['Contact', 'contact.html', '']].filter(l => D.shown(l[1]));\n    const cats = D.collections.filter(c => c.handle !== 'all');\n    const curCat = page === 'shop' ? qs('c') : null;\n    const here = href => page === href.replace('.html', '');\n    return `\n    <div class=\"mnav\" id=\"mnav\" role=\"dialog\" aria-modal=\"true\" aria-label=\"Menu\">\n      <div class=\"mnav__top\"><a class=\"brand\" href=\"${route(`index.html`)}\" aria-label=\"Aura Smart home\">${logoFx()}</a><button class=\"icon-btn icon-btn--solid\" type=\"button\" data-mnav-close aria-label=\"Close menu\">${icon('close')}</button></div>\n      <div class=\"mnav__body\">\n        <button class=\"mnav__search mnav__in\" type=\"button\" data-search-open style=\"--i:0\">${icon('search')}<span>Search products, answers\u2026</span></button>\n        <section class=\"mnav__shop mnav__in\" aria-labelledby=\"mnavShop\" style=\"--i:1\">\n          <div class=\"mnav__head\"><h2 class=\"eyebrow\" id=\"mnavShop\">Shop</h2><a class=\"link small\" href=\"${route(`shop.html`)}\" ${page === 'shop' && !curCat ? 'aria-current=\"page\"' : ''}>Shop all ${D.products.length} ${icon('arrow')}</a></div>\n          <div class=\"mnav__cats\">${cats.map(c => `<a class=\"mnav__cat\" href=\"${route(`shop.html?c=${c.handle}`)}\" ${curCat === c.handle ? 'aria-current=\"page\"' : ''}><span class=\"media\"><img src=\"${c.image}\" alt=\"\" loading=\"lazy\"></span><span class=\"mnav__cat-name\">${c.title.replace(/^./, m => m.toUpperCase())} <small>${D.inCollection(c.handle).length}</small></span></a>`).join('')}</div>\n        </section>\n        <nav class=\"mnav__links\" aria-label=\"Menu\">${links.map((l, i) => `<a class=\"mnav__in\" href=\"${route(l[1])}\" style=\"--i:${i + 2}\" ${here(l[1]) ? 'aria-current=\"page\"' : ''}>${l[0]} <small>${here(l[1]) ? 'You\u2019re here' : l[2]}</small></a>`).join('')}</nav>\n        <div class=\"mnav__contact mnav__in\" style=\"--i:${links.length + 2}\">\n          <a href=\"${D.site.whatsappHref}\" target=\"_blank\" rel=\"noopener\">${icon('whatsapp')}<b>WhatsApp</b>${D.site.whatsapp}</a>\n          <a href=\"${D.site.phoneHref}\">${icon('phone')}<b>Call us</b>${D.site.phone}</a>\n        </div>\n      </div>\n      <div class=\"mnav__foot\"><a class=\"btn btn--blue btn--block\" href=\"${route(`contact.html#quote`)}\">Get a free quote</a></div>\n    </div>`;\n  }\n\n  function overlaysHTML() {\n    return `\n    <div class=\"scrim\" data-scrim></div>\n    <aside class=\"drawer\" id=\"cartDrawer\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"cartTitle\" aria-hidden=\"true\">\n      <div class=\"drawer__head\"><h2 id=\"cartTitle\">Your cart <small data-cart-count-text></small></h2><button class=\"icon-btn\" type=\"button\" data-cart-close aria-label=\"Close cart\">${icon('close')}</button></div>\n      <div class=\"drawer__body\" data-cart-body></div>\n      <div class=\"drawer__foot\" data-cart-foot></div>\n    </aside>\n    <div class=\"modal\" id=\"quickModal\" role=\"dialog\" aria-modal=\"true\" aria-label=\"Quick add\" aria-hidden=\"true\"><div class=\"modal__panel\"><button class=\"icon-btn icon-btn--solid modal__close\" type=\"button\" data-modal-close aria-label=\"Close\">${icon('close')}</button><div data-modal-body></div></div></div>\n    <aura-search class=\"search\" id=\"search\" role=\"dialog\" aria-modal=\"true\" aria-label=\"Search\" aria-hidden=\"true\">\n      <div class=\"search__scrim\" data-search-close></div>\n      <div class=\"search__panel\">\n        <div class=\"search__field\">${icon('search')}<input type=\"search\" placeholder=\"Search products, answers, guides\u2026 try \u201Ccamera under 150\u201D\" aria-label=\"Search the store\" role=\"combobox\" aria-expanded=\"true\" aria-controls=\"searchResults\" aria-autocomplete=\"list\" data-search-input autocomplete=\"off\" spellcheck=\"false\" enterkeyhint=\"search\"><kbd>Esc</kbd><button class=\"icon-btn\" type=\"button\" data-search-close aria-label=\"Close search\">${icon('close')}</button></div>\n        <div class=\"search__results\" id=\"searchResults\" role=\"listbox\" aria-label=\"Search results\" data-search-results></div>\n        <p class=\"sr-only\" aria-live=\"polite\" data-search-status></p>\n      </div>\n    </aura-search>\n    <div class=\"toast-wrap\" aria-live=\"polite\" data-toasts></div>\n    <a class=\"fab\" href=\"${D.site.whatsappHref}\" target=\"_blank\" rel=\"noopener\" aria-label=\"Chat with us on WhatsApp\"><span class=\"wa\">${icon('whatsapp')}</span><span class=\"fab__label\"><small>Need help?</small><b>Chat on WhatsApp</b></span></a>`;\n  }\n\n  const FOOT_PHONE = '(max-width: 699px)';   // footer link groups collapse below this (main.css matches)\n  function footerHTML() {\n    // each link group is a disclosure: tap-to-open on phones, always open from 700px (initFootCols)\n    const open = !matchMedia(FOOT_PHONE).matches;\n    // the page you're on (a link with a #fragment is a place on a page, never the page itself)\n    const here = href => { if (/^[a-z]+:|#/.test(href)) return false; const u = new URL(href, location.href); return u.pathname.split('/').pop().replace(/\\.html$/, '') === page && u.search === location.search; };\n    const link = ([label, href, cls]) => `<li><a ${cls ? `class=\"${cls}\" ` : ''}href=\"${route(href)}\"${here(href) ? ' aria-current=\"page\"' : ''}><span>${label}</span></a></li>`;\n    const col = (title, links, more = '', cls = '') => `<details class=\"foot-col${cls}${open ? ' is-open' : ''}\"${open ? ' open' : ''}><summary><h3>${title}</h3></summary><div class=\"foot-col__body\"><ul>${links.filter(l => D.shown(l[1])).map(link).join('')}</ul>${more}</div></details>`;\n    const social = (label, href, ico) => `<a href=\"${route(href)}\" target=\"_blank\" rel=\"noopener\" aria-label=\"${label}\">${icon(ico)}</a>`;\n    const talk = col('Talk to us', [[D.site.phone, D.site.phoneHref, 'foot-tel'], [D.site.email, 'mailto:' + D.site.email], ['Showroom, ' + D.site.showroom.town, 'showroom.html']],\n      `<div class=\"foot-social\">${social('Aura Smart on Facebook', D.site.facebook, 'facebook')}${social('Aura Smart on Instagram', D.site.instagram, 'instagram')}</div>`, ' foot-col--talk')\n      // the email can be copied as well as opened (a mouse only: on a phone, press and hold the address)\n      .replace(`<li><a href=\"mailto:${D.site.email}\"`, `<li class=\"foot-has-copy\"><a href=\"mailto:${D.site.email}\"`)\n      .replace(`<span>${D.site.email}</span></a>`, `<span>${D.site.email}</span></a><button class=\"foot-copy\" type=\"button\" data-copy=\"${D.site.email}\" aria-label=\"Copy the email address\">${icon('copy')}${icon('check')}</button>`);\n    return `\n    <footer class=\"site-footer on-dark\">\n      <div class=\"container\">\n        <div class=\"foot-top\">\n          <div class=\"foot-news\">\n            <h2>Get Aura Smart <span class=\"accent\">updates</span></h2>\n            <p id=\"newsHint\">Enter your email below for product news, security tips and offers. Unsubscribe at any time.</p>\n            <form class=\"news-form\" data-news-form novalidate><label class=\"sr-only\" for=\"newsEmail\">Email address</label><input id=\"newsEmail\" type=\"text\" inputmode=\"email\" autocomplete=\"email\" autocapitalize=\"off\" spellcheck=\"false\" enterkeyhint=\"send\" placeholder=\"Your email address\" aria-describedby=\"newsHint newsNote\" aria-required=\"true\"><button class=\"btn btn--light btn--sm\" type=\"submit\">Try signup form</button></form>\n            <p class=\"news-form__err\" id=\"newsErr\" role=\"alert\" hidden></p>\n            <p class=\"news-note\" id=\"newsNote\">By signing up, you agree to our <a href=\"${route(`policy.html?p=privacy`)}\">privacy policy</a>.</p>\n          </div>\n          <div class=\"foot-cols\">\n            ${col('Shop', [['All products', 'shop.html'], ['Security cameras', 'shop.html?c=cameras'], ['Floodlight cameras', 'shop.html?c=floodlights'], ['Smart locks', 'shop.html?c=locks'], ['House alarms', 'shop.html?c=alarms'], ['Smart control panels', 'shop.html?c=panels'], ['Smart sockets & switches', 'shop.html?c=power']])}\n            ${col('Services', [['Pro installation', 'pro-installation.html'], ['Smart blinds', 'smart-blinds.html'], ['Blackout blinds', 'blackout-blinds.html'], ['Upgrade programme', 'upgrade.html'], ['Free quote', 'contact.html#quote']])}\n            ${col('Company', [['About us', 'about.html'], ['Journal', 'journal.html'], ['FAQ & support', 'faq.html'], ['Contact', 'contact.html']])}\n            ${talk}\n          </div>\n        </div>\n      </div>\n      <div class=\"foot-sky\">\n        <aura-sky aria-hidden=\"true\"><canvas></canvas></aura-sky>\n        <div class=\"container\">\n        <aura-watch class=\"foot-mark\" aria-hidden=\"true\">${watchMark()}</aura-watch>\n        <div class=\"foot-bottom\">\n          <p class=\"foot-copy\">\u00A9 ${new Date().getFullYear()} Aura Smart. All rights reserved. <span>Formerly ${D.site.formerly}.</span></p>\n          <nav class=\"foot-legal\" aria-label=\"Legal\"><a href=\"${route(`policy.html?p=refund`)}\">Refund policy</a><a href=\"${route(`policy.html?p=privacy`)}\">Privacy policy</a><a href=\"${route(`policy.html?p=terms`)}\">Terms of service</a></nav>\n          <ul class=\"pay-icons\" role=\"list\" aria-label=\"Payment methods\">${['visa', 'master', 'apple_pay', 'google_pay'].map(k => `<li>${payIcon(k)}</li>`).join('')}<li class=\"pay-cash\">Cash on install</li></ul>\n        </div>\n        </div>\n      </div>\n    </footer>`;\n  }\n\n  /* ---------- mount chrome ---------- */\n  // Header mounts immediately (app.js is loaded right after #chrome-top) so it is\n  // in place before first paint; the footer + overlays mount on DOMContentLoaded.\n  function mountTop() { const top = document.getElementById('chrome-top'); if (top) top.outerHTML = headerHTML() + mnavHTML(); }\n  function mountFoot() {\n    if (window.AURA_SHOPIFY) return; // Liquid section groups already own the chrome and overlays.\n    const foot = document.getElementById('chrome-footer');\n    const minimal = document.body.dataset.chrome === 'minimal';\n    const html = (minimal ? '' : footerHTML()) + overlaysHTML();\n    if (foot) foot.outerHTML = html; else document.body.insertAdjacentHTML('beforeend', html);\n  }\n  mountTop();\n\n  /* ---------- scroll lock (with Lenis) ---------- */\n  let lenis = null;\n  let locks = 0;\n  const lock = () => { if (locks++ === 0) { lenis?.stop(); root.style.overflow = 'hidden'; } };\n  const unlock = () => { if (--locks <= 0) { locks = 0; lenis?.start(); root.style.overflow = ''; } };\n\n  /* ---------- floating WhatsApp button ----------\n     Always there in the bottom corner, from the top of the page to the foot, through the\n     films and the scroll scenes, so help is one tap away wherever you are. It only steps\n     aside while you type (the phone's keyboard would push it over the field), and lifts\n     above the product page's sticky add-to-cart bar where the two would meet (commerce.css).\n     Over the full-screen scenes marked [data-fab-tuck] (the film, the story) it keeps to its\n     round icon, in the room their foot rows leave for it (main.css). */\n  function initFab() {\n    const fab = $('.fab'); if (!fab) return;\n    let typing = false;\n    const sync = () => fab.classList.toggle('is-hidden', typing);\n    // reading on down the page, the label tucks into the icon; scrolling back up brings it out again\n    let last = scrollY, from = scrollY;\n    const scenes = new Set();\n    const tuck = () => {\n      const y = scrollY;\n      if (y < last - 4 || fab.classList.contains('is-hidden')) from = y;\n      fab.classList.toggle('is-tucked', scenes.size > 0 || y - from > 240);\n      last = y;\n    };\n    addEventListener('scroll', tuck, { passive: true });\n    const io = new IntersectionObserver(es => { es.forEach(en => (en.isIntersecting ? scenes.add(en.target) : scenes.delete(en.target))); tuck(); });\n    $$('[data-fab-tuck]').forEach(el => io.observe(el));\n    const isField = el => el?.matches?.('input:not([type=\"checkbox\"]):not([type=\"radio\"]):not([type=\"range\"]), textarea, select, [contenteditable]');\n    document.addEventListener('focusin', e => { typing = isField(e.target); sync(); });\n    document.addEventListener('focusout', () => { typing = false; requestAnimationFrame(sync); });\n    sync();\n  }\n\n  /* ---------- footer link groups ---------- */\n  // On phones the four groups collapse to their headings, one open at a time, so the\n  // whole footer fits the screen; they slide open and shut like an accordion. From 700px\n  // up they're always open and can't be closed. .is-open is the state the group is\n  // heading to (the arrow follows it at once); [open] stays on until a close finishes.\n  function initFootCols() {\n    const cols = $$('.foot-col'); if (!cols.length) return;\n    const phone = matchMedia(FOOT_PHONE);\n    const sync = () => cols.forEach(d => { d.anim?.cancel(); d.open = !phone.matches; d.classList.toggle('is-open', d.open); });\n    phone.addEventListener('change', sync);\n    sync(); // Liquid renders the desktop state; choose the initial phone state before measuring.\n    const set = (d, open) => {\n      const body = $('.foot-col__body', d);\n      const from = d.open ? body.getBoundingClientRect().height : 0;   // mid-slide: carry on from where it is\n      d.anim?.cancel();\n      d.classList.toggle('is-open', open);\n      if (open) d.open = true;\n      if (reduced) { d.open = open; return; }\n      const to = open ? body.scrollHeight : 0;\n      body.style.overflow = 'hidden';\n      d.anim = body.animate(\n        [{ height: `${from}px`, opacity: open ? 0 : 1 }, { height: `${to}px`, opacity: open ? 1 : 0 }],\n        { duration: open ? 520 : 420, easing: 'cubic-bezier(.16, 1, .3, 1)' },\n      );\n      d.anim.onfinish = () => { d.anim = null; body.style.overflow = ''; if (!open) d.open = false; };\n    };\n    cols.forEach(d => $('summary', d).addEventListener('click', e => {\n      e.preventDefault();               // the slide decides when [open] changes\n      if (!phone.matches) return;       // from 700px the groups stay open\n      const open = !d.classList.contains('is-open');\n      set(d, open);\n      if (open) cols.forEach(o => { if (o !== d && o.classList.contains('is-open')) set(o, false); });\n    }));\n  }\n\n  /* ---------- copy the email address (footer) ---------- */\n  async function copyText(text) {\n    try { await navigator.clipboard.writeText(text); return true; } catch {}\n    // some in-app browsers block the clipboard API: the old way still works there\n    const back = document.activeElement, t = document.createElement('textarea');\n    t.value = text; t.readOnly = true; t.style.cssText = 'position:fixed;top:0;left:0;opacity:0;pointer-events:none';\n    document.body.appendChild(t); t.select();\n    let ok = false; try { ok = document.execCommand('copy'); } catch {}\n    t.remove(); back?.focus?.({ preventScroll: true });\n    return ok;\n  }\n  function initCopy() {\n    document.addEventListener('click', async e => {\n      const b = e.target.closest('[data-copy]'); if (!b) return;\n      if (!await copyText(b.dataset.copy)) return;\n      b.classList.add('is-done');\n      toast(`Copied ${esc(b.dataset.copy)}`);\n      clearTimeout(b.doneTimer); b.doneTimer = setTimeout(() => b.classList.remove('is-done'), 1800);\n    });\n  }\n\n  /* ---------- the footer's links come out like stars at dusk ----------\n     The first time the link groups scroll into view they fade up one by one, in a scattered order\n     (the same on every visit), as the sky's stars do below them. With a mouse only: on a phone\n     nothing on the page waits to appear. */\n  function initFootDusk() {\n    const foot = $('.site-footer'), cols = $('.foot-cols', foot || document);\n    if (!foot || !cols || reduced || !fine) return;\n    $$('.foot-col li, .foot-social', foot).forEach((el, i) => el.style.setProperty('--dusk', `${(i * 7 + 3) % 11 * 45}ms`));\n    foot.classList.add('is-dusk');\n    new IntersectionObserver(([e], io) => { if (!e.isIntersecting) return; foot.classList.add('is-night'); io.disconnect(); }, { threshold: .3 }).observe(cols);\n  }\n\n  /* ---------- the footer fits the screen (touch phones) ----------\n     At the end of the page the footer fills the window, signup to payment marks, with no strip\n     of the section before, however the browser's bars slide in and out.\n       \u2022 Its content is fitted, once per width, to the height that's always visible (the window\n         with the bars out): the spacing scales between roomy and compact (--fit, main.css), the\n         wordmark takes any room to spare, up to the full width, and on the shortest screens it\n         steps aside (.is-tight).\n       \u2022 The footer itself is as tall as the window at its tallest (--foot-slack makes up the\n         difference), so the window never reaches past its top. main.css pins the signup and link\n         groups to the top of the window, so while the bars are out that extra height scrolls by\n         beneath them instead of hiding anything.\n     The window is at its tallest once the browser's bars tuck away, which they do on your first\n     scroll down; until then the footer is taken to need the whole screen. A lower height is only\n     ever applied while the footer is out of sight, so nothing shifts in front of you, and nothing\n     is re-measured as you scroll, as the bars move or as a link group opens. */\n  function initFootFit() {\n    const foot = $('.site-footer'); if (!foot || !touch) return;\n    const phone = matchMedia(FOOT_PHONE);\n    let width = 0, content = 0, screenH = 0, tallest = 0, inView = false;\n    let opened = innerHeight, seen = 0;   // the window when the page opened; its height with the bars tucked away, once seen\n    // the footer's height as laid out without the slack, less any open group's links\n    const contentH = () => foot.offsetHeight - $$('.foot-col.is-open .foot-col__body', foot).reduce((h, b) => h + b.offsetHeight, 0);\n    const setHeight = h => { tallest = h; foot.style.setProperty('--foot-slack', `${Math.max(0, Math.ceil(h - content) + 2)}px`); };\n    // a taller window takes effect at once (the window must never reach past the footer's top),\n    // a shorter one once the footer is out of sight\n    const settle = () => {\n      const h = seen || screenH;\n      if (content && (h > tallest || !inView)) setHeight(h);\n    };\n    const fit = () => {\n      width = innerWidth;\n      for (const p of ['--fit', '--mark-w', '--foot-slack']) foot.style.removeProperty(p);\n      foot.classList.remove('is-tight');\n      content = 0;\n      if (!phone.matches) return;\n      // the screen's height as held now (iOS reports it upright whichever way the phone is turned)\n      const long = Math.max(screen.width, screen.height), short = Math.min(screen.width, screen.height);\n      screenH = Math.max(innerHeight, innerWidth > innerHeight ? short : long);\n      // always visible: the window as it is now, or the screen less the most the browser's bars\n      // can take (status bar, about 59px with a notch or island and 20px without, and both\n      // toolbars out), whichever is smaller; a page can open with the bars already tucked away\n      const bars = (long >= 780 ? 59 : 20) + 137;\n      const room = Math.min(innerHeight, screenH - bars >= 400 ? screenH - bars : innerHeight);\n      if (contentH() > room) {\n        foot.style.setProperty('--fit', '0');\n        if (contentH() > room) foot.classList.add('is-tight');\n        else {\n          let lo = 0, hi = 1;   // the roomiest spacing that still fits\n          for (let i = 0; i < 7; i++) { const mid = (lo + hi) / 2; foot.style.setProperty('--fit', mid.toFixed(3)); if (contentH() > room) hi = mid; else lo = mid; }\n          foot.style.setProperty('--fit', lo.toFixed(3));\n        }\n      } else {\n        // room to spare: the wordmark grows into it (max-width: 100% caps it at the full width)\n        const mark = $('.foot-mark', foot), r = mark?.getBoundingClientRect();\n        if (r?.height) foot.style.setProperty('--mark-w', `${Math.floor((r.height + room - contentH()) * r.width / r.height)}px`);\n      }\n      content = contentH();\n      setHeight(seen || screenH);\n    };\n    fit();\n    document.fonts?.ready.then(fit);   // once more, with the real fonts\n    new IntersectionObserver(([e]) => { inView = e.isIntersecting; if (!inView) settle(); }).observe(foot);\n    addEventListener('resize', () => {\n      if (innerWidth !== width) { opened = innerHeight; seen = 0; return fit(); }   // turned: start afresh\n      // taller than when the page opened: the bars have tucked away (the keyboard only ever shortens it)\n      if (innerHeight > opened + 40 && innerHeight > seen) { seen = innerHeight; settle(); }\n    });\n  }\n\n  /* ---------- toasts ---------- */\n  function toast(html, action) {\n    const wrap = $('[data-toasts]'); if (!wrap) return;\n    const el = document.createElement('div');\n    el.className = 'toast';\n    el.innerHTML = `${icon('check-circle')}<span>${html}</span>${action ? `<a href=\"${action[1]}\" ${action[2] ? `data-${action[2]}` : ''}>${action[0]}</a>` : ''}`;\n    wrap.appendChild(el);\n    setTimeout(() => { el.classList.add('is-out'); setTimeout(() => el.remove(), 500); }, 3600);\n  }\n\n  /* ---------- cart drawer ---------- */\n  function bumpBadge() { $$('[data-cart-count]').forEach(b => { b.classList.remove('is-bump'); void b.offsetWidth; b.classList.add('is-bump'); }); }\n  // The sockets' and switches' quantity prices (D.volume) in the cart, for one way of buying: how many\n  // there are, the tier reached, and the next one\n  function volumeState(mode) {\n    const v = D.volume; if (!v) return null;\n    const n = Cart.items.filter(l => l.variant === mode && v.handles.includes(l.handle)).reduce((a, l) => a + l.qty, 0);\n    return n ? { n, tier: v.tiers.filter(t => n >= t.min).pop(), next: v.tiers.find(t => n < t.min), quote: n >= v.quote } : null;\n  }\n  // a line's price: what Shopify charges after its discounts, with the full price struck through, and\n  // under the name what the discount made of it\n  function cartLinePriceHTML(l, unit, compare) {\n    const now = l.finalTotal ?? unit * l.qty, full = Math.max(compare || 0, unit) * l.qty;\n    return `<div class=\"cart-line__price\">${fmt(now)}${full > now ? `<s>${fmt(full)}</s>` : ''}</div>`;\n  }\n  function cartLineDealHTML(l) {\n    const off = (l.lineDiscounts || []).reduce((a, d) => a + d.amount, 0); if (!off) return '';\n    const tier = D.volume?.handles.includes(l.handle) && volumeState(l.variant)?.tier;\n    return `<div class=\"cart-line__deal\">${icon('tag')}<span>${tier ? `${fmt(l.finalTotal / l.qty)} each, the ${tier.min}+ price` : `${esc(l.lineDiscounts[0].title)} \u00B7 \u2212 ${fmt(off)}`}</span></div>`;\n  }\n  // where the cart stands on the quantity prices, with a bar to the next one\n  function volumeNoteHTML() {\n    const v = D.volume; if (!v || !window.AURA_SHOPIFY) return '';   // the demo cart has no discounts\n    return ['pro', 'diy'].map(mode => {\n      const s = volumeState(mode); if (!s) return '';\n      const what = `${s.n} switch${s.n > 1 ? 'es' : ''} &amp; sockets${mode === 'pro' ? ', fitted' : ', supply only'}`;\n      const offAt = t => fmt(t.off[mode]);\n      const text = s.quote ? `<b>${what}</b>: for ${v.quote} or more, <a class=\"text-link\" href=\"${route('contact.html#quote')}\">ask us for a quote</a>.`\n        : `<b>${what}${s.tier ? `: ${offAt(s.tier)} off each` : ''}</b>${s.next ? ` \u00B7 add ${s.next.min - s.n} more for ${offAt(s.next)} off each` : ''}`;\n      const from = s.tier?.min || 0, to = s.next?.min || v.quote;\n      return `<div class=\"cart-vol\">${icon('tag')}<div><span>${text}</span>${s.next ? `<span class=\"cart-vol__bar\" aria-hidden=\"true\"><i style=\"width:${Math.round((s.n - from) / (to - from) * 100)}%\"></i></span>` : ''}</div></div>`;\n    }).join('');\n  }\n  function cartLineHTML(l) {\n    const p = D.byHandle(l.handle); if (!p) return '';\n    const unit = Cart.priceOf(l);\n    const compare = l.compare ?? p.compare;\n    const img = l.image || (p.colors && l.color && p.colors.find(c => c.name === l.color)?.image) || p.images[0];\n    const href = route(p.url || p.page || `product.html?p=${p.handle}`);\n    return `\n    <div class=\"cart-line\" data-key=\"${esc(l.key)}\">\n      <a class=\"cart-line__media\" href=\"${route(href)}\" style=\"--tint:${p.tint}\"><img src=\"${img}\" alt=\"${esc(p.name)}\"></a>\n      <div>\n        <div class=\"cart-line__top\">\n          <div><a class=\"cart-line__name\" href=\"${route(href)}\">${esc(p.name)}</a>\n            <div class=\"cart-line__meta\"><span>${window.AURA_SHOPIFY && p.handle === 'guard-2' ? (l.variant === 'diy' ? icon('box') + ' Delivered' : icon('tools') + ' Measured and fitted') : (l.variant === 'diy' ? icon('box') + ' DIY \u00B7 Delivered' : icon('tools') + ' Pro installation')}</span>${l.color ? `<span>${esc(l.color)}</span>` : ''}</div>${cartLineDealHTML(l)}</div>\n          ${cartLinePriceHTML(l, unit, compare)}\n        </div>\n        ${Object.entries(l.properties || {}).filter(([key]) => !key.startsWith('_')).map(([key, value]) => `<div class=\"cart-line__meta\">${esc(key)}: ${esc(value)}</div>`).join('')}\n        <div class=\"cart-line__bottom\">\n          <div class=\"qty\"><button type=\"button\" data-qty=\"-1\" aria-label=\"Decrease quantity\">${icon('minus')}</button><output aria-live=\"polite\">${l.qty}</output><button type=\"button\" data-qty=\"1\" aria-label=\"Increase quantity\">${icon('plus')}</button></div>\n          <button class=\"text-btn\" type=\"button\" data-remove>Remove</button>\n        </div>\n      </div>\n    </div>`;\n  }\n  function renderCart() {\n    const n = Cart.count();\n    $$('[data-cart-count]').forEach(b => { b.textContent = n; b.classList.toggle('is-on', n > 0); });\n    $$('[data-cart-count-text]').forEach(b => (b.textContent = n ? `${n} item${n > 1 ? 's' : ''}` : ''));\n    const body = $('[data-cart-body]'), foot = $('[data-cart-foot]'); if (!body) return;\n    if (Cart.loading) { body.innerHTML = '<div class=\"cart-empty\" role=\"status\"><p class=\"muted\">Loading your cart\u2026</p></div>'; foot.style.display = 'none'; return; }\n    if (!n) {\n      body.innerHTML = `<div class=\"cart-empty\"><div class=\"orb\">${icon('bag')}</div><h3 class=\"h4\">Your cart is empty</h3><p class=\"muted small mw-30\">Browse the devices, or ask us to recommend a setup for your home.</p><div class=\"btn-row justify-center mt-6\"><a class=\"btn btn--sm\" href=\"${route(`shop.html`)}\">Shop all</a><a class=\"btn btn--sm btn--ghost\" href=\"${route(`contact.html#quote`)}\">Free quote</a></div></div>`;\n      foot.innerHTML = ''; foot.style.display = 'none'; return;\n    }\n    foot.style.display = '';\n    const inCart = new Set(Cart.items.map(i => i.handle));\n    const ups = ['floodlight-camera', 'indoorcam-p1', 'smart-lock', 'solar-camera-pro'].filter(h => !inCart.has(h)).slice(0, 2).map(D.byHandle).filter(Boolean);\n    body.innerHTML = Cart.items.map(cartLineHTML).join('') + (ups.length ? `\n      <div class=\"cart-upsell\"><h3>Complete your system</h3>${ups.map(p => `\n        <div class=\"mini-card\"><a class=\"media\" href=\"${route(`product.html?p=${p.handle}`)}\" style=\"--tint:${p.tint}\"><img src=\"${p.images[0]}\" alt=\"\"></a><div><b>${p.name}</b><span>${fmt(p.from)}</span></div><button class=\"icon-btn icon-btn--solid\" type=\"button\" data-add=\"${p.handle}\" data-variant=\"diy\" aria-label=\"Add ${esc(p.name)}\">${icon('plus')}</button></div>`).join('')}</div>` : '');\n    // discounts: only the Shopify cart has them (the bundle discount), one row each\n    const sub = Cart.subtotal(), discounts = Cart.discounts || [], savings = Math.round((Cart.compareTotal() - sub - discounts.reduce((a, d) => a + d.amount, 0)) * 100) / 100;\n    foot.innerHTML = `\n      ${volumeNoteHTML()}\n      ${Cart.hasPro() ? `<div class=\"cart-note\">${icon('calendar')}<span>Pro installation included. We\u2019ll call to book a time that suits you after checkout.</span></div>` : ''}\n      ${savings > 0 ? `<div class=\"cart-row cart-row--save\"><span>You\u2019re saving</span><b>${fmt(savings)}</b></div>` : ''}\n      ${discounts.map(d => `<div class=\"cart-row cart-row--save\"><span>${esc(d.title)}</span><b>\u2212 ${fmt(d.amount)}</b></div>`).join('')}\n      <div class=\"cart-row cart-row--total\"><span>Subtotal</span><b>${fmt(sub)}</b></div>\n      <a class=\"btn btn--blue btn--block btn--lg\" href=\"${route(window.AURA_SHOPIFY ? 'cart.html' : 'checkout.html')}\">${window.AURA_SHOPIFY ? 'Review cart & checkout' : 'Continue to demo checkout'}</a>\n      <div class=\"flex items-center gap-12 justify-between\"><a class=\"text-btn\" href=\"${route(`cart.html`)}\">View full cart</a><span class=\"tiny muted\">No monthly fees \u00B7 ${D.site.warranty} warranty</span></div>`;\n    hydrateButtons(foot);\n  }\n  function initCart() {\n    const drawer = $('#cartDrawer'), scrim = $('[data-scrim]'); if (!drawer) return;\n    let lastFocus;\n    const open = () => { lastFocus = document.activeElement; drawer.classList.add('is-open'); drawer.setAttribute('aria-hidden', 'false'); scrim.classList.add('is-on'); lock(); setTimeout(() => $('[data-cart-close]', drawer).focus(), 50); };\n    const close = () => { if (!drawer.classList.contains('is-open')) return; drawer.classList.remove('is-open'); drawer.setAttribute('aria-hidden', 'true'); scrim.classList.remove('is-on'); unlock(); lastFocus?.focus?.(); };\n    A.openCart = open; A.closeCart = close;\n    document.addEventListener('click', async e => {\n      if (e.target.closest('[data-cart-open]')) { e.preventDefault(); open(); }\n      if (e.target.closest('[data-cart-close]') || e.target === scrim) close();\n      const line = e.target.closest('.cart-line');\n      if (line) {\n        const k = line.dataset.key, it = Cart.items.find(i => i.key === k);\n        const q = e.target.closest('[data-qty]'); if (q && it) Cart.set(k, it.qty + Number(q.dataset.qty));\n        if (e.target.closest('[data-remove]')) { line.style.transition = 'opacity .3s, transform .4s'; line.style.opacity = 0; line.style.transform = 'translateX(20px)'; setTimeout(() => Cart.remove(k), 250); }\n      }\n      const add = e.target.closest('[data-add]');\n      if (add) { e.preventDefault(); const ok = await Cart.add(add.dataset.add, add.dataset.variant || 'diy', add.dataset.color || null); if (ok === false) return; const p = D.byHandle(add.dataset.add); if (drawer.classList.contains('is-open')) toast(`${esc(p.name)} added`); else { toast(`<b>${esc(p.name)}</b> added to cart`, ['View cart', '#', 'cart-open']); } }\n    });\n    document.addEventListener('keydown', e => { if (e.key === 'Escape') close(); });\n    document.addEventListener('cart:change', renderCart);\n    renderCart();\n  }\n\n  /* ---------- quick add modal ---------- */\n  function initQuick() {\n    const modal = $('#quickModal'); if (!modal) return;\n    const scrim = $('[data-scrim]');\n    let last;\n    const close = () => { if (!modal.classList.contains('is-open')) return; modal.classList.remove('is-open'); modal.setAttribute('aria-hidden', 'true'); scrim.classList.remove('is-on'); unlock(); last?.focus?.(); };\n    const open = h => {\n      const p = D.byHandle(h); if (!p) return;\n      last = document.activeElement;\n      let variant = 'diy', color = p.colors ? p.colors[0].name : null;\n      $('[data-modal-body]', modal).innerHTML = `\n        <div class=\"qa\">\n          <div class=\"qa__media\" style=\"--tint:${p.tint}\"><img data-qa-img src=\"${p.images[0]}\" alt=\"${esc(p.name)}\"></div>\n          <div class=\"qa__body\">\n            <div><h2 class=\"h3\">${esc(p.name)}</h2><p class=\"muted mt-8\">${esc(p.tagline)}</p></div>\n            ${p.colors ? `<div><p class=\"qa__label\">Finish: <span data-qa-color>${color}</span></p>${A.swatchesHTML(p.colors, color, 'data-qa-swatch')}</div>` : ''}\n            <div class=\"opt-cards\" role=\"radiogroup\" aria-label=\"Installation\">${optCard(p, 'diy', true)}${optCard(p, 'pro', false)}</div>\n            <button class=\"btn btn--blue btn--lg btn--block\" type=\"button\" data-qa-add>Add to cart \u00B7 <span data-qa-price>${fmt(p.price[1])}</span></button>\n            <a class=\"link small\" href=\"${route(`product.html?p=${p.handle}`)}\">View product details ${icon('arrow')}</a>\n          </div>\n        </div>`;\n      const body = $('[data-modal-body]', modal);\n      hydrateButtons(body);\n      body.onclick = async e => {\n        const o = e.target.closest('[data-opt]');\n        if (o) { variant = o.dataset.opt; $$('[data-opt]', body).forEach(x => x.setAttribute('aria-checked', x === o)); $('[data-qa-price]', body).textContent = fmt(p.price[variant === 'diy' ? 1 : 0]); }\n        const s = e.target.closest('[data-qa-swatch]');\n        if (s) { color = s.dataset.qaSwatch; $$('[data-qa-swatch]', body).forEach(x => x.setAttribute('aria-pressed', x === s)); $('[data-qa-color]', body).textContent = color; $('[data-qa-img]', body).src = p.colors.find(c => c.name === color).image; }\n        if (e.target.closest('[data-qa-add]')) { const ok = await Cart.add(p.handle, variant, color); if (ok === false) return; close(); setTimeout(() => A.openCart(), 250); }\n      };\n      modal.classList.add('is-open'); modal.setAttribute('aria-hidden', 'false'); scrim.classList.add('is-on'); lock();\n      setTimeout(() => $('[data-modal-close]', modal).focus(), 60);\n    };\n    A.quickAdd = open;\n    document.addEventListener('click', e => {\n      const q = e.target.closest('[data-quick]'); if (q) { e.preventDefault(); open(q.dataset.quick); }\n      if (e.target.closest('[data-modal-close]') || (modal.classList.contains('is-open') && e.target === modal)) close();\n    });\n    scrim.addEventListener('click', close);\n    document.addEventListener('keydown', e => { if (e.key === 'Escape') close(); });\n  }\n  // finish swatches; finishes with a material are grouped under it, and an aluminium frame's\n  // swatch shows its black centre (ring)\n  function swatchesHTML(colors, selected, attr) {\n    const btn = c => `<button type=\"button\" class=\"swatch${c.ring ? ' swatch--ring' : ''}${c.material ? ` swatch--${c.material.toLowerCase()}` : ''}\" style=\"--c:${c.hex}${c.ring ? `;--ring:${c.ring}` : ''}\" aria-pressed=\"${c.name === selected}\" ${attr}=\"${esc(c.name)}\" aria-label=\"${esc(c.name)}\"></button>`;\n    const groups = [...new Set(colors.map(c => c.material).filter(Boolean))];\n    if (!groups.length) return `<div class=\"swatches\">${colors.map(btn).join('')}</div>`;\n    return `<div class=\"swatch-groups\">${groups.map(g => `<div class=\"swatch-group\"><span class=\"swatch-group__name\">${esc(g)}</span><div class=\"swatches\">${colors.filter(c => c.material === g).map(btn).join('')}</div></div>`).join('')}</div>`;\n  }\n  // The finish's photo in a small card over its swatch while the mouse rests on it. Along the row the\n  // card glides to the next swatch and its photo crossfades; it goes once the pointer leaves the swatches.\n  // (sel: what counts as a swatch, each naming its finish in data-color; srcFor(name, swatch): its photo)\n  function swatchPeek(root, srcFor, tint, sel = '.swatch[data-color]') {\n    if (!fine || !root) return;\n    let card, hideT, on = null;\n    const make = () => {\n      card = document.createElement('div'); card.className = 'swatch-peek'; card.setAttribute('aria-hidden', 'true');\n      if (tint) card.style.setProperty('--tint', tint);\n      card.innerHTML = '<span class=\"swatch-peek__media\"><img alt=\"\"><img alt=\"\"></span><span class=\"swatch-peek__name\"></span>';\n      document.body.append(card);\n    };\n    const show = sw => {\n      const name = sw.dataset.color, src = srcFor(name, sw); if (!src) return;\n      if (!card) make();\n      clearTimeout(hideT);\n      const [a, b] = $$('img', card), cur = a.classList.contains('is-on') ? a : b, next = cur === a ? b : a;\n      if (cur.getAttribute('src') !== src) { next.src = src; next.classList.add('is-on'); cur.classList.remove('is-on'); }\n      const [tone, ...rest] = name.split(' ');\n      $('.swatch-peek__name', card).innerHTML = `${esc(tone)} <small>${esc(rest.join(' '))}</small>`;\n      const r = sw.getBoundingClientRect();\n      card.style.setProperty('--x', `${r.left + r.width / 2}px`); card.style.setProperty('--y', `${r.top}px`);\n      if (!on) { card.classList.add('is-snap'); card.offsetWidth; card.classList.remove('is-snap'); }   // appears in place, glides only between swatches\n      card.classList.add('is-on'); on = sw;\n    };\n    // while the page scrolls (a smooth scroll runs on after the wheel stops) it stays on its swatch\n    const follow = () => {\n      if (!on) return;\n      if (!on.isConnected) { card.classList.remove('is-on'); on = null; return; }\n      const r = on.getBoundingClientRect();\n      card.classList.add('is-snap');\n      card.style.setProperty('--x', `${r.left + r.width / 2}px`); card.style.setProperty('--y', `${r.top}px`);\n      card.offsetWidth; card.classList.remove('is-snap');\n    };\n    const hide = (wait = 140) => { clearTimeout(hideT); hideT = setTimeout(() => { card?.classList.remove('is-on'); on = null; }, wait); };\n    root.addEventListener('pointerover', e => { const sw = e.target.closest?.(sel); if (sw && e.pointerType === 'mouse') show(sw); });\n    root.addEventListener('pointerout', e => { const sw = e.target.closest?.(sel); if (sw && !sw.contains(e.relatedTarget)) hide(); });\n    addEventListener('scroll', follow, { passive: true });\n  }\n  // a card's dots: one per colour, so \"White glass\" and \"White aluminium\" share a dot\n  const cardColors = colors => colors.filter((c, i) => colors.findIndex(x => x.name.split(' ')[0] === c.name.split(' ')[0]) === i);\n\n  function optCard(p, v, checked) {\n    const pro = v === 'pro';\n    return `<button type=\"button\" class=\"opt\" role=\"radio\" aria-checked=\"${checked}\" data-opt=\"${v}\">\n      <span class=\"opt__radio\"></span>\n      <span class=\"opt__main\"><b>${pro ? 'Pro installation' : 'DIY installation'}</b><span>${pro ? 'Fitted, tested &amp; explained by a licensed installer' : 'Delivered to your door, ready to set up'}</span></span>\n      <span class=\"opt__price\">${fmt(p.price[pro ? 0 : 1])}</span>\n    </button>`;\n  }\n\n  /* ---------- declarative icons: <span data-icon=\"lock\"></span>, <span data-stars></span> ---------- */\n  function hydrateIcons(scope = document) {\n    $$('[data-icon]', scope).forEach(el => { if (!el.firstElementChild) el.innerHTML = icon(el.dataset.icon); });\n    $$('[data-stars]', scope).forEach(el => { if (!el.firstElementChild) el.outerHTML = stars(); });\n  }\n\n  /* ---------- custom select: every <select> becomes a branded, accessible listbox ---------- */\n  let cselectId = 0;\n  function enhanceSelects(scope = document) {\n    $$('select:not([multiple]):not([data-native]):not(.cselect__native)', scope).forEach(sel => {\n      const id = ++cselectId;\n      const wrap = document.createElement('div');\n      wrap.className = 'cselect' + (sel.classList.contains('select--sm') ? ' cselect--sm' : '');\n      sel.parentNode.insertBefore(wrap, sel);\n      wrap.appendChild(sel);\n      sel.classList.add('cselect__native'); sel.tabIndex = -1; sel.setAttribute('aria-hidden', 'true');\n      const btnId = sel.id ? sel.id + '-btn' : `cselect-${id}`;\n      const label = sel.id && document.querySelector(`label[for=\"${sel.id}\"]`);\n      if (label) { label.id = label.id || `${btnId}-label`; label.htmlFor = btnId; }\n      const aria = label ? label.id : null;\n      wrap.insertAdjacentHTML('beforeend', `<button type=\"button\" class=\"cselect__btn\" id=\"${btnId}\" aria-haspopup=\"listbox\" aria-expanded=\"false\" ${aria ? `aria-labelledby=\"${aria} ${btnId}\"` : `aria-label=\"${esc(sel.getAttribute('aria-label') || 'Select')}\"`}><span class=\"cselect__value\"></span><span class=\"cselect__chev\">${icon('chevron')}</span></button><ul class=\"cselect__list\" role=\"listbox\" id=\"${btnId}-list\" tabindex=\"-1\" ${aria ? `aria-labelledby=\"${aria}\"` : ''}></ul>`);\n      const btn = $('.cselect__btn', wrap), list = $('.cselect__list', wrap), val = $('.cselect__value', wrap);\n      let active = -1, typed = '', typedT;\n      const opts = () => [...sel.options];\n      const render = () => {\n        list.innerHTML = opts().map((o, i) => `<li class=\"cselect__opt\" role=\"option\" id=\"${btnId}-o${i}\" data-i=\"${i}\" aria-selected=\"${o.selected}\" ${o.disabled ? 'aria-disabled=\"true\"' : ''}>${esc(o.textContent)}${icon('check')}</li>`).join('');\n        const cur = sel.options[sel.selectedIndex];\n        val.textContent = cur ? cur.textContent : '';\n        val.classList.toggle('is-placeholder', !cur || cur.value === '');\n      };\n      const setActive = i => {\n        const items = $$('.cselect__opt', list); if (!items.length) return;\n        active = Math.max(0, Math.min(items.length - 1, i));\n        items.forEach((li, k) => li.classList.toggle('is-active', k === active));\n        list.setAttribute('aria-activedescendant', items[active].id);\n        const li = items[active], top = li.offsetTop, bot = top + li.offsetHeight;\n        if (top < list.scrollTop) list.scrollTop = top - 6; else if (bot > list.scrollTop + list.clientHeight) list.scrollTop = bot - list.clientHeight + 6;\n      };\n      const open = () => {\n        if (wrap.classList.contains('is-open')) return;\n        $$('.cselect.is-open').forEach(o => o !== wrap && o.dispatchEvent(new Event('cselect:close')));\n        render();\n        const r = btn.getBoundingClientRect();\n        wrap.classList.toggle('is-up', innerHeight - r.bottom < 320 && r.top > innerHeight - r.bottom);\n        wrap.classList.add('is-open'); btn.setAttribute('aria-expanded', 'true');\n        setActive(sel.selectedIndex < 0 ? 0 : sel.selectedIndex);\n        list.focus({ preventScroll: true });\n      };\n      const close = (focusBtn = true) => {\n        if (!wrap.classList.contains('is-open')) return;\n        wrap.classList.remove('is-open'); btn.setAttribute('aria-expanded', 'false');\n        if (focusBtn) btn.focus({ preventScroll: true });\n      };\n      const choose = i => {\n        const o = sel.options[i]; if (!o || o.disabled) return;\n        if (sel.selectedIndex !== i) { sel.selectedIndex = i; sel.dispatchEvent(new Event('input', { bubbles: true })); sel.dispatchEvent(new Event('change', { bubbles: true })); }\n        render(); close();\n      };\n      wrap.addEventListener('cselect:close', () => close(false));\n      btn.addEventListener('click', () => (wrap.classList.contains('is-open') ? close() : open()));\n      btn.addEventListener('keydown', e => { if (['ArrowDown', 'ArrowUp', 'Enter', ' '].includes(e.key)) { e.preventDefault(); open(); } });\n      list.addEventListener('click', e => { const li = e.target.closest('.cselect__opt'); if (li) choose(+li.dataset.i); });\n      list.addEventListener('mousemove', e => { const li = e.target.closest('.cselect__opt'); if (li && +li.dataset.i !== active) setActive(+li.dataset.i); });\n      list.addEventListener('keydown', e => {\n        const n = sel.options.length;\n        if (e.key === 'ArrowDown') { e.preventDefault(); setActive(active + 1); }\n        else if (e.key === 'ArrowUp') { e.preventDefault(); setActive(active - 1); }\n        else if (e.key === 'Home') { e.preventDefault(); setActive(0); }\n        else if (e.key === 'End') { e.preventDefault(); setActive(n - 1); }\n        else if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); choose(active); }\n        else if (e.key === 'Escape') { e.preventDefault(); e.stopPropagation(); close(); }\n        else if (e.key === 'Tab') close(false);\n        else if (e.key.length === 1) {\n          typed += e.key.toLowerCase(); clearTimeout(typedT); typedT = setTimeout(() => (typed = ''), 600);\n          const i = opts().findIndex(o => o.textContent.trim().toLowerCase().startsWith(typed)); if (i > -1) setActive(i);\n        }\n      });\n      document.addEventListener('pointerdown', e => { if (!wrap.contains(e.target)) close(false); });\n      sel.addEventListener('change', render);\n      if (sel.required) btn.setAttribute('aria-required', 'true');\n      render();\n    });\n  }\n\n  /* ---------- press feedback on touch screens ----------\n     A phone sets :active the moment a thumb lands, including the start of a scroll, so\n     buttons and cards styled with :active would flash and shrink under every swipe. Here\n     a press shows only for a deliberate tap: after a short hold without moving, or briefly\n     on release. It clears as soon as the browser takes the touch for a scroll\n     (pointercancel) or the finger drifts. main.css styles .is-pressed. */\n  const PRESSABLE = '.btn, .pcard__add, .pcard, .icard, .cat-chip, .co-cm, .qcard, .svc-way, .co-link, a.co-place, .qlink, .help-card__links a, .jcard, .jr-feature, .mnav__cat, .swatch';\n  function initPress() {\n    if (!touch) return;\n    let el = null, timer = 0, x0 = 0, y0 = 0;\n    const drop = () => { clearTimeout(timer); el?.classList.remove('is-pressed'); el = null; };\n    document.addEventListener('pointerdown', e => {\n      drop();\n      if (e.pointerType === 'mouse') return;\n      el = e.target.closest(PRESSABLE); if (!el) return;\n      x0 = e.clientX; y0 = e.clientY;\n      timer = setTimeout(() => el?.classList.add('is-pressed'), 90);\n    }, { passive: true });\n    document.addEventListener('pointermove', e => { if (el && Math.hypot(e.clientX - x0, e.clientY - y0) > 10) drop(); }, { passive: true });\n    document.addEventListener('pointercancel', drop, { passive: true });\n    addEventListener('scroll', () => { if (el) drop(); }, { passive: true });\n    document.addEventListener('pointerup', () => {\n      if (!el) return;\n      const t = el; clearTimeout(timer); el = null;\n      t.classList.add('is-pressed'); setTimeout(() => t.classList.remove('is-pressed'), 160);   // a quick tap still answers\n    }, { passive: true });\n  }\n\n  /* ---------- rails: tab and chip rows that scroll sideways on small screens ---------- */\n  // Brings an item to the middle of its own sideways scroller, without moving the page\n  function centerInRail(el, smooth = true) {\n    let rail = el?.parentElement;\n    for (; rail && rail !== document.body; rail = rail.parentElement) {\n      if (/(auto|scroll)/.test(getComputedStyle(rail).overflowX) && rail.scrollWidth > rail.clientWidth + 1) break;\n    }\n    if (!rail || rail === document.body) return;\n    const r = rail.getBoundingClientRect(), b = el.getBoundingClientRect();\n    rail.scrollTo({ left: rail.scrollLeft + (b.left - r.left) - (r.width - b.width) / 2, behavior: smooth && !reduced ? 'smooth' : 'auto' });\n  }\n  function initRails() {\n    // open on the chosen tab or chip, even when it's far along the row\n    $$('[role=\"tablist\"], .chip-rail, .subnav__links').forEach(rail => {\n      const cur = $('[aria-selected=\"true\"], [aria-current=\"page\"], [aria-current=\"true\"], [aria-pressed=\"true\"], .is-active', rail);\n      if (cur) centerInRail(cur, false);\n    });\n    document.addEventListener('click', e => { const t = e.target.closest('[role=\"tab\"], .chip-rail > *'); if (t) centerInRail(t); });\n    // arrow keys, Home and End move along a tab list (WAI-ARIA tabs pattern)\n    document.addEventListener('keydown', e => {\n      const tab = e.target.closest?.('[role=\"tab\"]');\n      if (!tab || !['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(e.key)) return;\n      const tabs = $$('[role=\"tab\"]', tab.closest('[role=\"tablist\"]')).filter(t => !t.disabled && t.offsetParent);\n      const i = tabs.indexOf(tab), n = tabs.length;\n      const j = e.key === 'Home' ? 0 : e.key === 'End' ? n - 1 : (i + (e.key === 'ArrowRight' ? 1 : -1) + n) % n;\n      e.preventDefault(); tabs[j].focus(); tabs[j].click();\n    });\n  }\n\n  /* ---------- branded page scroll rail (replaces the OS scrollbar) ---------- */\n  function initRail() {\n    if (!fine) return;\n    const rail = document.createElement('div');\n    rail.className = 'rail'; rail.setAttribute('aria-hidden', 'true');\n    rail.innerHTML = '<div class=\"rail__thumb\"></div>';\n    document.body.appendChild(rail);\n    const thumb = rail.firstChild;\n    let idle, drag = null, m = null, queued = 0;\n    const metrics = () => {\n      const docH = document.documentElement.scrollHeight, vh = innerHeight, railH = rail.clientHeight;\n      const th = Math.max(40, railH * vh / docH);\n      return { docH, vh, railH, th, max: docH - vh };\n    };\n    // drawn once a frame at most, after the scroll's other handlers have moved things: the page's\n    // height is measured only when it changes, and what's under the rail is looked up once\n    const paint = () => {\n      queued = 0;\n      if (!m || rail.style.display === 'none') { rail.style.display = ''; m = metrics(); }\n      if (m.max <= 0) { rail.style.display = 'none'; return; }\n      thumb.style.height = m.th + 'px';\n      thumb.style.transform = `translateY(${(scrollY / m.max) * (m.railH - m.th)}px)`;\n      const under = document.elementFromPoint(innerWidth - 8, 60);\n      rail.classList.toggle('on-night', !!under?.closest('.story.is-night, .bg-night, .site-footer, .on-dark, .banner'));\n    };\n    const schedule = () => { if (!queued) queued = requestAnimationFrame(paint); };\n    const remeasure = () => { m = null; schedule(); };\n    const wake = () => { rail.classList.add('is-on'); clearTimeout(idle); idle = setTimeout(() => rail.classList.remove('is-on'), 1100); };\n    const scrollTo = y => (lenis ? lenis.scrollTo(y, { immediate: true, force: true }) : window.scrollTo(0, y));\n    addEventListener('scroll', () => { schedule(); wake(); }, { passive: true });\n    addEventListener('resize', remeasure);\n    new ResizeObserver(remeasure).observe(document.body);\n    thumb.addEventListener('pointerdown', e => { e.preventDefault(); drag = { y: e.clientY, s: scrollY }; rail.classList.add('is-drag'); root.classList.add('is-dragging-rail'); thumb.setPointerCapture(e.pointerId); });\n    thumb.addEventListener('pointermove', e => { if (!drag) return; const m = metrics(); scrollTo(drag.s + (e.clientY - drag.y) * (m.max / (m.railH - m.th))); });\n    const end = () => { drag = null; rail.classList.remove('is-drag'); root.classList.remove('is-dragging-rail'); wake(); };\n    thumb.addEventListener('pointerup', end); thumb.addEventListener('pointercancel', end);\n    rail.addEventListener('pointerdown', e => { if (e.target !== rail) return; const m = metrics(), r = rail.getBoundingClientRect(); const k = (e.clientY - r.top - m.th / 2) / (m.railH - m.th); lenis ? lenis.scrollTo(Math.max(0, Math.min(1, k)) * m.max) : scrollTo(k * m.max); });\n    schedule();\n  }\n\n  /* ---------- buttons: rolling label + arrow ---------- */\n  function hydrateButtons(scope = document) {\n    $$('.btn:not([data-hydrated])', scope).forEach(b => {\n      b.dataset.hydrated = '1';\n      if (b.querySelector('.btn__label')) return;\n      const text = b.textContent.trim();\n      const isIco = n => n.nodeType === 1 && (n.matches('svg') || n.matches('[data-icon]'));\n      const lead = [...b.childNodes].filter(isIco).map(n => n.outerHTML).join('');\n      const html = [...b.childNodes].filter(n => !isIco(n)).map(n => (n.nodeType === 3 ? esc(n.textContent) : n.outerHTML)).join('').trim();\n      if (!text) return;\n      const arrow = !b.classList.contains('btn--noarrow') && !b.hasAttribute('data-noarrow');\n      b.innerHTML = `${lead}<span class=\"btn__label\"><span>${html}</span><span aria-hidden=\"true\">${html}</span></span>${arrow ? `<span class=\"btn__arrow\">${icon('arrow')}</span>` : ''}`;\n    });\n  }\n\n  /* ---------- motion ---------- */\n  // Split by explicit <br>/.line markers when present, otherwise by words \u2192 measured lines.\n  // Several at once go in three passes (all into words, then every line measured, then all into\n  // lines), so the page is laid out once for all of them rather than twice for each\n  function splitLines(...els) {\n    els = els.filter(el => !el.classList.contains('is-split'));\n    const words = els.map(el => {\n      try {\n        const tmp = document.createElement('div'); tmp.innerHTML = el.innerHTML;\n        const tokens = [];\n        tmp.childNodes.forEach(n => {\n          if (n.nodeType === 3) n.textContent.split(/(\\s+)/).forEach(t => t && tokens.push(t));\n          else if (n.nodeName === 'BR') tokens.push('\\n');\n          else tokens.push(n.outerHTML);\n        });\n        el.innerHTML = tokens.map(t => (t === '\\n' ? '<br data-br>' : /^\\s+$/.test(t) ? ' ' : `<span class=\"w\" style=\"display:inline-block\">${t}</span>`)).join('');\n        return $$('.w, br[data-br]', el);\n      } catch { return null; }\n    });\n    const lines = words.map(ws => {\n      if (!ws) return null;\n      const lines = []; let top = null, cur = [];\n      ws.forEach(w => {\n        if (w.tagName === 'BR') { if (cur.length) lines.push(cur); cur = []; top = null; return; }\n        const t = w.offsetTop;\n        if (top !== null && Math.abs(t - top) > 4) { lines.push(cur); cur = []; }\n        top = t; cur.push(w.innerHTML);\n      });\n      if (cur.length) lines.push(cur);\n      return lines;\n    });\n    els.forEach((el, k) => {\n      if (lines[k]) el.innerHTML = lines[k].map((l, i) => `<span class=\"split-line\"><span style=\"--i:${i}\">${l.join(' ')}</span></span>`).join('');\n      el.classList.add('is-split');\n    });\n  }\n\n  function initMotion() {\n    splitLines(...$$('[data-split]'));\n    // Touch screens reveal as soon as anything shows, so a quick flick never lands on blank space\n    const io = new IntersectionObserver(entries => entries.forEach(en => {\n      if (en.isIntersecting) { en.target.classList.add('is-in'); io.unobserve(en.target); }\n    }), touch ? { rootMargin: '0px 0px 4% 0px', threshold: 0 } : { rootMargin: '0px 0px -8% 0px', threshold: 0.08 });\n    A.observe = scope => $$('[data-reveal]:not(.is-in), [data-split]:not(.is-in), .img-reveal:not(.is-in), [data-count]:not(.is-in)', scope).forEach(el => io.observe(el));\n    A.observe(document);\n\n    // counters\n    const cio = new IntersectionObserver(entries => entries.forEach(en => {\n      if (!en.isIntersecting) return; cio.unobserve(en.target);\n      const el = en.target, end = parseFloat(el.dataset.count), dec = (el.dataset.count.split('.')[1] || '').length;\n      const pre = el.dataset.prefix || '', suf = el.dataset.suffix || '';\n      if (reduced) { el.textContent = pre + end.toLocaleString('en-IE', { minimumFractionDigits: dec }) + suf; return; }\n      const t0 = performance.now(), dur = 1800, nf = new Intl.NumberFormat('en-IE', { minimumFractionDigits: dec, maximumFractionDigits: dec });\n      const tick = t => { const k = Math.min(1, (t - t0) / dur), e = 1 - Math.pow(1 - k, 4); el.textContent = pre + nf.format(end * e) + suf; if (k < 1) requestAnimationFrame(tick); };\n      requestAnimationFrame(tick);\n    }), { threshold: .4 });\n    $$('[data-count]').forEach(el => cio.observe(el));\n\n    // marquees: duplicate track to fill\n    $$('.marquee').forEach(m => {\n      const track = $('.marquee__track', m); if (!track || m.dataset.ready) return;\n      m.dataset.ready = 1;\n      const clone = track.cloneNode(true); clone.setAttribute('aria-hidden', 'true'); $$('a,button', clone).forEach(a => a.tabIndex = -1);\n      m.appendChild(clone);\n    });\n\n    // parallax + scroll progress\n    // Parallax only with a mouse: on a phone the page scrolls on its own thread, and a picture\n    // moved by script a frame behind it visibly jitters\n    const par = fine ? $$('[data-parallax]') : [];\n    const prog = $$('[data-progress]');\n    if (!reduced && (par.length || prog.length)) {\n      // every position read first, then everything moved, so the page is laid out once, not once per picture\n      const update = () => {\n        const vh = innerHeight;\n        const ks = par.map(el => {\n          const r = el.getBoundingClientRect();\n          return r.bottom < -200 || r.top > vh + 200 ? null : (r.top + r.height / 2 - vh / 2) / vh;\n        });\n        const ps = prog.map(el => {\n          const r = el.getBoundingClientRect();\n          const total = r.height - vh * (parseFloat(el.dataset.progressOffset || 1));\n          return Math.min(1, Math.max(0, -r.top / Math.max(1, total)));\n        });\n        par.forEach((el, i) => { if (ks[i] !== null) el.style.transform = `translate3d(0, ${(ks[i] * parseFloat(el.dataset.parallax || 60)).toFixed(1)}px, 0)`; });\n        prog.forEach((el, i) => {\n          el.style.setProperty('--p', ps[i].toFixed(4));\n          el.dispatchEvent(new CustomEvent('progress', { detail: ps[i] }));\n        });\n      };\n      A.onFrame = update;\n      addEventListener('scroll', update, { passive: true }); addEventListener('resize', update); update();\n    }\n\n    // magnetic buttons\n    if (fine && !reduced) {\n      $$('[data-magnetic]').forEach(el => {\n        el.addEventListener('mousemove', e => { const r = el.getBoundingClientRect(); el.style.transform = `translate(${(e.clientX - r.left - r.width / 2) * .25}px, ${(e.clientY - r.top - r.height / 2) * .35}px)`; });\n        el.addEventListener('mouseleave', () => { el.style.transform = ''; });\n      });\n    }\n  }\n\n  /* ---------- accordions: animated <details> ---------- */\n  function initAccordions(scope = document) {\n    $$('.acc__item:not([data-acc])', scope).forEach(d => {\n      d.dataset.acc = 1;\n      const sum = $('summary', d), content = $('.acc__content', d);\n      if (!content || reduced) return;\n      sum.addEventListener('click', e => {\n        e.preventDefault();\n        if (d.open) {\n          const h = content.offsetHeight; content.style.height = h + 'px';\n          requestAnimationFrame(() => { content.style.transition = 'height .5s var(--ease)'; content.style.height = '0px'; });\n          content.addEventListener('transitionend', () => { d.open = false; content.style.cssText = ''; }, { once: true });\n        } else {\n          if (d.closest('[data-acc-single]')) $$('.acc__item[open]', d.closest('[data-acc-single]')).forEach(o => o !== d && $('summary', o).click());\n          d.open = true; const h = content.scrollHeight; content.style.height = '0px';\n          requestAnimationFrame(() => { content.style.transition = 'height .6s var(--ease)'; content.style.height = h + 'px'; });\n          content.addEventListener('transitionend', () => { content.style.cssText = ''; }, { once: true });\n        }\n      });\n    });\n  }\n\n  /* ---------- demo forms ---------- */\n  const EMAIL = /^\\S+@\\S+\\.\\S+$/;\n  // shows (or clears) the signup's message under it; true when there's nothing wrong\n  const newsCheck = (f, msg) => {\n    const err = $('#newsErr'), inp = $('[inputmode=\"email\"]', f);\n    f.classList.toggle('is-invalid', !!msg);\n    inp?.toggleAttribute('aria-invalid', !!msg);\n    if (err) { err.textContent = msg; err.hidden = !msg; }\n    return !msg;\n  };\n  function initForms() {\n    // a message under the signup goes as soon as what's typed is an address\n    document.addEventListener('input', e => {\n      const f = e.target.closest?.('[data-news-form].is-invalid');\n      if (f && EMAIL.test(e.target.value.trim())) newsCheck(f, '');\n    });\n    // The signup checks the address itself and says what's wrong under the field: the field is plain\n    // text (with the email keyboard), so the browser never adds its own bubble or hover tooltip. Checked\n    // as the submit starts (capture), before Shopify's own bot check on its customer form sees it: a\n    // bad address stops here, a good one goes on to Shopify\n    document.addEventListener('submit', e => {\n      const f = e.target;\n      if (!f.matches('[data-news-form]')) return;\n      const inp = $('[inputmode=\"email\"]', f), v = inp.value.trim();\n      if (!newsCheck(f, v ? (EMAIL.test(v) ? '' : 'Check the address, such as name@example.ie') : 'Enter your email address, such as name@example.ie')) { e.preventDefault(); e.stopImmediatePropagation(); inp.focus(); return; }\n      if (f.matches('[data-shopify-news]')) return;\n      e.preventDefault(); e.stopImmediatePropagation();\n      f.innerHTML = `<p class=\"news-form__done\" role=\"status\">${icon('check-circle')} Demo only. You have not been subscribed. Contact us by email for updates.</p>`;\n    }, true);\n    document.addEventListener('submit', e => {\n      const f = e.target;\n      if (f.matches('[data-demo-form], [data-shopify-contact]')) {\n        if (!f.matches('[data-shopify-contact]')) e.preventDefault();\n        let ok = true;\n        $$('[required]', f).forEach(inp => {\n          const field = inp.closest('.field'); const valid = inp.type === 'email' ? /^\\S+@\\S+\\.\\S+$/.test(inp.value) : inp.value.trim().length > 1;\n          field?.classList.toggle('is-invalid', !valid); if (!valid && ok) { inp.focus(); ok = false; }\n        });\n        if (!ok) { e.preventDefault(); return; }\n        const btn = $('[type=\"submit\"]', f); btn?.classList.add('is-loading');\n        // Shopify contact forms keep the same validation, then submit to Shopify normally.\n        if (f.matches('[data-shopify-contact]')) return;\n        setTimeout(() => { (f.closest('[data-form-wrap]') || f).classList.add('is-sent'); btn?.classList.remove('is-loading'); }, 700);\n      }\n    });\n    document.addEventListener('input', e => { const fld = e.target.closest('.field.is-invalid'); if (fld) fld.classList.remove('is-invalid'); });\n    // check a filled-in field as you leave it (an empty one waits for submit, so tabbing past isn't scolded)\n    document.addEventListener('focusout', e => {\n      const inp = e.target;\n      // tidy an Irish number the way it's said: 0871234567 \u2192 087 123 4567, 00353\u2026 \u2192 +353 87 123 4567\n      if (inp.matches?.('input[type=\"tel\"]')) {\n        const d = inp.value.replace(/[^\\d+]/g, ''); let m;\n        if ((m = d.match(/^01(\\d{3})(\\d{4})$/))) inp.value = `01 ${m[1]} ${m[2]}`;\n        else if ((m = d.match(/^0(\\d{2})(\\d{3})(\\d{4})$/))) inp.value = `0${m[1]} ${m[2]} ${m[3]}`;\n        else if ((m = d.match(/^(?:\\+|00)353(\\d{2})(\\d{3})(\\d{4})$/))) inp.value = `+353 ${m[1]} ${m[2]} ${m[3]}`;\n      }\n      if (!inp.matches?.('.input[required], .textarea[required]')) return;\n      const fld = inp.closest('.field'), v = inp.value.trim(); if (!fld || !v) return;\n      fld.classList.toggle('is-invalid', inp.type === 'email' ? !/^\\S+@\\S+\\.\\S+$/.test(v) : v.length < 2);\n    });\n  }\n\n  /* ---------- smooth scroll ---------- */\n  function initLenis() {\n    if (reduced || !window.Lenis || !fine) return;\n    let against = 0, againstN = 0, againstAt = 0, lastDir = 0, lastAt = -1e9, undo = null;\n    lenis = new window.Lenis({\n      duration: 1.15, easing: t => Math.min(1, 1.001 - Math.pow(2, -10 * t)), smoothWheel: true,\n      // A wheel turned the other way turns the page at once. Each tick adds to the glide's target,\n      // so after scrolling one way the target sits well ahead of the page, and the first ticks the\n      // other way only used that up: the page kept going, stalled, then came back, a hitch felt as\n      // resistance at every change of direction. Now the glide still owed is dropped first.\n      // But only for a real turn, as the wheel may say the other way when the hand hasn't:\n      // - a worn or dusty wheel bounces: in the middle of a roll it gives a whole notch the other way\n      //   25-40 ms before or after one the right way (seen on a scroll log, 23 Oct), far quicker than\n      //   a hand turns a wheel round. So of two notches opposite ways within 70 ms, one is let go: the\n      //   second, unless the first was itself a change of way, which the second then undoes\n      // - small ticks the other way (a wheel's flick as a notch settles, or a trackpad) turn it on\n      //   one of more than 24px, or a second in a row once they add up to 8px (a trackpad's turn: a\n      //   run of small ones); a lone flick, or two of a pixel or so, is let go\n      // What's let go is kept from scrolling the page natively, which Lenis would no longer prevent\n      // While a drawer, menu, search or dialog locks the page, the wheel is the browser's: stopped,\n      // Lenis would cancel it, and the cart's list and the other panels couldn't scroll (the page\n      // can't move then anyway, its overflow is hidden)\n      prevent: () => locks > 0,\n      virtualScroll: ({ deltaY, event }) => {\n        if (!deltaY || locks) return true;\n        const now = performance.now(), dir = Math.sign(deltaY), notch = Math.abs(deltaY) >= 50;\n        const drop = () => { if (event.cancelable) event.preventDefault(); return false; };\n        if (notch) {\n          if (dir !== lastDir && now - lastAt < 70) {\n            if (!undo || now - undo.at >= 70) return drop();\n            lenis.targetScroll = undo.target; undo = null; lastDir = dir; lastAt = now;\n            return true;\n          }\n          undo = dir !== lastDir ? { target: lenis.targetScroll, at: now } : null;\n          lastDir = dir; lastAt = now;\n        }\n        const owed = lenis.targetScroll - lenis.animatedScroll;\n        if (Math.abs(owed) < 1 || dir === Math.sign(owed)) { against = 0; againstN = 0; return true; }\n        if (!notch) {\n          if (now - againstAt > 150) { against = 0; againstN = 0; }\n          against += Math.abs(deltaY); againstN++; againstAt = now;\n          if (against <= 24 && (againstN < 2 || against < 8)) return drop();\n        }\n        lenis.targetScroll = lenis.animatedScroll; against = 0; againstN = 0;\n        return true;\n      },\n    });\n    const raf = t => { lenis.raf(t); requestAnimationFrame(raf); };\n    requestAnimationFrame(raf);\n    A.lenis = lenis;\n    document.addEventListener('click', e => {\n      // smooth-scroll any link to an anchor on this same page (\"#quote\" or \"contact.html#quote\" while on contact.html)\n      const a = e.target.closest('a[href*=\"#\"]'); if (!a) return;\n      const url = new URL(a.href, location.href);\n      if (url.pathname !== location.pathname || url.hash.length < 2) return;\n      const t = document.querySelector(url.hash); if (!t) return;\n      e.preventDefault();\n      const menu = $('#mnav')?.classList.contains('is-open');\n      if (menu) $('[data-mnav-close]')?.click();\n      // (Lenis keeps the page's scroll-padding-top and the target's scroll-margin-top, as the browser does on touch;\n      // from the mobile menu, once it has closed and given the page its scroll back)\n      setTimeout(() => { const fit = fitTop(t); lenis.scrollTo(fit ?? t); }, menu ? 420 : 0);\n      history.replaceState(null, '', url.hash);\n    });\n  }\n\n  // A section marked [data-fit] (the home page's app section) is framed on the screen when a link\n  // brings you to it: its [data-fit] box centred in the room under the header. Where the box is\n  // taller than that (a phone), its core, the parts marked [data-fit-core], is framed instead, or\n  // failing that its top goes just under the header. Null for any other target\n  function fitTop(target) {\n    const box = target.matches('[data-fit]') ? target : target.querySelector('[data-fit]'); if (!box) return null;\n    // (the header's pill, as it sits once the page has scrolled: its height, its 12px from the top, and a little air)\n    const bar = $('.nav-bar'), head = bar ? bar.offsetHeight + 20 : 0, room = innerHeight - head;\n    // (where things are laid out, not where a reveal has them sliding in from)\n    const docTop = el => { let t = 0; for (; el; el = el.offsetParent) t += el.offsetTop; return t; };\n    let top = docTop(box), h = box.offsetHeight;\n    const core = h > room ? $$('[data-fit-core]', box) : [];\n    if (core.length) { const tops = core.map(docTop); h = Math.max(...core.map((c, i) => tops[i] + c.offsetHeight)) - (top = Math.min(...tops)); }\n    return Math.max(0, top - head - Math.max(0, (room - h) / 2));\n  }\n\n  /* ---------- preloader (home, once per session) ---------- */\n  function preloader() {\n    const pl = $('.preloader'); if (!pl) return Promise.resolve();\n    // (index.html's head has already hidden it, before the first paint, if it has been seen this visit)\n    let seen = root.classList.contains('intro-seen'); try { seen = seen || sessionStorage.getItem('aura-intro'); sessionStorage.setItem('aura-intro', 1); } catch {}\n    if (seen || reduced) { pl.remove(); return Promise.resolve(); }\n    // it lifts once its own drawing has played (1.95s from when it first showed, which on a slow\n    // connection has often been and gone by the time the page is ready) and the photo it uncovers\n    // is in, waiting no more than 2.5s for that\n    const played = Math.max(0, ...pl.getAnimations({ subtree: true }).map(a => a.currentTime || 0));\n    const photo = $('.hs__scene img');\n    const inPhoto = photo && !photo.complete ? Promise.race([photo.decode().catch(() => {}), new Promise(r => setTimeout(r, 2500))]) : null;\n    return Promise.all([new Promise(r => setTimeout(r, Math.max(0, 1950 - played))), inPhoto])\n      .then(() => { pl.classList.add('is-done'); setTimeout(() => { pl.remove(); }, 1100); });\n  }\n\n  /* ---------- public API ---------- */\n  const readyFns = [];\n  const A = window.A = { $, $$, esc, fmt, icon, stars, logo, qs, seo, page, route, asset: D.asset, html: D.html, byHandle: D.byHandle, Cart, productCard, optCard, swatchesHTML, swatchPeek, cardColors, fitTop, toast, hydrateButtons, hydrateIcons, enhanceSelects, reviewCard, reviewRows, faqHTML, jcard, initAccordions, splitLines, initials, avColor, centerInRail, cartLinePriceHTML, cartLineDealHTML, volumeNoteHTML, recent, markViewed, payIcon, reduced, fine, lock, unlock, ready: fn => readyFns.push(fn) };\n\n  document.addEventListener('DOMContentLoaded', () => {\n    $$('[data-feature]').forEach(el => { if (!D.features[el.dataset.feature]) el.remove(); });\n    if (!document.getElementById('siteHeader')) mountTop();\n    mountFoot();\n    initFootCols(); initFootDusk(); initCopy(); initCart(); initQuick(); initForms(); initLenis(); initPress();\n    readyFns.forEach(fn => { try { fn(A); } catch (err) { console.error(err); } });\n    $$('main [data-fills]').forEach(el => el.classList.add('is-filled'));   // includes Shopify's section wrappers\n    seo();\n    // the page complete (icons, buttons, selects) before anything below measures it, so it's laid out\n    // once as it opens rather than once for them and again after\n    hydrateIcons(); hydrateButtons(); initAccordions(); enhanceSelects();\n    initFab(); initRails(); initFootFit();   // after the page scripts, so they see what those rendered\n    // a product card's colour dots show that finish's photo too, wherever cards are\n    swatchPeek(document, (name, dot) => D.byHandle(dot.closest('[data-handle]')?.dataset.handle)?.colors?.find(c => c.name === name)?.image, '#E8E5DF', '.pcard__swatches [data-color]');\n    initRail();\n    const go = () => {\n      root.classList.add('is-loaded'); initMotion();\n      // arriving by a link to a framed section (index.html#app from another page): framed, and kept\n      // framed while what's above it is still coming in and taking its room, and after the browser's\n      // own jump to the anchor once the page has loaded, until you scroll yourself or 4s have passed\n      const at = location.hash.length > 1 && document.querySelector(location.hash);\n      // (the window itself, not Lenis: after the browser's jump Lenis still thinks it's where it was,\n      // and would take a scroll back there for one it has already done)\n      const frame = () => { const fit = fitTop(at); if (fit != null && Math.abs(scrollY - fit) > 2) { scrollTo(0, fit); lenis?.scrollTo(fit, { immediate: true, force: true }); } };\n      if (at && fitTop(at) != null) {\n        frame();\n        const ro = new ResizeObserver(() => requestAnimationFrame(frame)); ro.observe(document.body);\n        const moved = () => requestAnimationFrame(frame);\n        addEventListener('scroll', moved, { passive: true });\n        const stop = () => { ro.disconnect(); removeEventListener('scroll', moved); ['wheel', 'touchstart', 'keydown', 'pointerdown'].forEach(t => removeEventListener(t, stop)); };\n        ['wheel', 'touchstart', 'keydown', 'pointerdown'].forEach(t => addEventListener(t, stop, { passive: true }));\n        setTimeout(stop, 4000);\n      }\n      const shot = qs('shot'); // QA: ?shot=<css selector> jumps straight to a section\n      if (shot) { const el = document.querySelector(shot); if (el) { const y = el.getBoundingClientRect().top + scrollY - (+qs('off') || 100); lenis ? lenis.scrollTo(y, { immediate: true, force: true }) : scrollTo(0, y); dispatchEvent(new Event('scroll')); } }\n    };\n    // A page prerendered by instant navigation holds its entrance motion until it is actually shown\n    const shown = () => (document.prerendering ? new Promise(r => document.addEventListener('prerenderingchange', r, { once: true })) : Promise.resolve());\n    // the faces the split headings and the body text are set in, as soon as they're in: they're measured\n    // into lines as the page enters. (document.fonts.ready settles only at the next layout after the\n    // last font, and waits for any font the page asks for later.) A face that fails to load doesn't hold it up\n    const fontsIn = () => {\n      if (!document.fonts) return;\n      const fonts = new Set([document.body, ...$$('[data-split], [data-split] *')].map(el => { const s = getComputedStyle(el); return `${s.fontStyle} ${s.fontWeight} 1em ${s.fontFamily}`; }));\n      return Promise.all([...fonts].map(f => document.fonts.load(f).catch(() => {})));\n    };\n    // never let slow web fonts hold the page hostage: proceed after 1.2s regardless\n    shown().then(preloader).then(() => Promise.race([fontsIn(), new Promise(r => setTimeout(r, 1200))])).then(go);\n  });\n})();\n"],
  "mappings": "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",
  "names": ["root", "li", "scrollTo", "m", "lines"]
}
