PageSourceSearch

https://printroom.co/cart

html printroom.co collected 2026-10-04 08:38:26 UTC 349,307 bytes, 7,706 lines download raw bytes

1<!doctype html><html class="no-js" lang="en">
2  <head>
3
4
5<script type="application/vnd.locksmith+json" data-locksmith>{"version":"v346","locked":false,"initialized":true,"scope":"cart","access_granted":true,"access_denied":false,"requires_customer":false,"manual_lock":false,"remote_lock":false,"has_timeout":false,"remote_rendered":null,"hide_resource":false,"hide_links_to_resource":false,"hide_price":false,"hide_add_to_cart":false,"transparent":true,"locks":{"all":[],"opened":[]},"keys":[],"keys_signature":"a6111dc4847a5059d4622e3d27b184dd5cbae461b5d6fc459feab12efb47932d","state":{"template":"cart","theme":151830298694,"product":null,"collection":null,"page":null,"blog":null,"article":null,"app":null},"now":1791103105,"path":"\/cart","locale_root_url":"\/","canonical_url":"https:\/\/printroom.co\/cart","customer_id":null,"customer_id_signature":"a6111dc4847a5059d4622e3d27b184dd5cbae461b5d6fc459feab12efb47932d","cart":null}</script>
5<script data-locksmith>!function(){undefined;!function(){var s=window.Locksmith={},e=document.querySelector('script[type="application/vnd.locksmith+json"]'),n=e&&e.innerHTML;if(s.state={},s.util={},s.loading=!1,n)try{s.state=JSON.parse(n)}catch(d){}if(document.addEventListener&&document.querySelector){var o,a,i,t=[76,79,67,75,83,77,73,84,72,49,49],c=function(){a=t.slice(0)},l="style",r=function(e){e&&27!==e.keyCode&&"click"!==e.type||(document.removeEventListener("keydown",r),document.removeEventListener("click",r),o&&document.body.removeChild(o),o=null)};c(),document.addEventListener("keyup",function(e){if(e.keyCode===a[0]){if(clearTimeout(i),a.shift(),0<a.length)return void(i=setTimeout(c,1e3));c(),r(),(o=document.createElement("div"))[l].width="50%",o[l].maxWidth="1000px",o[l].height="85%",o[l].border="1px rgba(0, 0, 0, 0.2) solid",o[l].background="rgba(255, 255, 255, 0.99)",o[l].borderRadius="4px",o[l].position="fixed",o[l].top="50%",o[l].left="50%",o[l].transform="translateY(-50%) translateX(-50%)",o[l].boxShadow="0 2px 5px rgba(0, 0, 0, 0.3), 0 0 100vh 100vw rgba(0, 0, 0, 0.5)",o[l].zIndex="2147483645";var t=document.createElement("textarea");t.value=JSON.stringify(JSON.parse(n),null,2),t[l].border="none",t[l].display="block",t[l].boxSizing="border-box",t[l].width="100%",t[l].height="100%",t[l].background="transparent",t[l].padding="22px",t[l].fontFamily="monospace",t[l].fontSize="14px",t[l].color="#333",t[l].resize="none",t[l].outline="none",t.readOnly=!0,o.appendChild(t),document.body.appendChild(o),t.addEventListener("click",function(e){e.stopImmediatePropagation()}),t.select(),document.addEventListener("keydown",r),document.addEventListener("click",r)}})}s.isEmbedded=-1!==window.location.search.indexOf("_ab=0&_fd=0&_sc=1"),s.path=s.state.path||window.location.pathname,s.basePath=s.state.locale_root_url.concat("/apps/locksmith").replace(/^\/\//,"/"),s.reloading=!1,s.util.console=window.console||{log:function(){},error:function(){}},s.util.makeUrl=function(e,t){var n,o=s.basePath+e,a=[],i=s.cache();for(n in i)a.push(n+"="+encodeURIComponent(i[n]));for(n in t)a.push(n+"="+encodeURIComponent(t[n]));return s.state.customer_id&&(a.push("customer_id="+encodeURIComponent(s.state.customer_id)),a.push("customer_id_signature="+encodeURIComponent(s.state.customer_id_signature))),o+=(-1===o.indexOf("?")?"?":"&")+a.join("&")},s._initializeCallbacks=[],s.on=function(e,t){if("initialize"!==e)throw'Locksmith.on() currently only supports the "initialize" event';s._initializeCallbacks.push(t)},s.initializeSession=function(e){if(!s.isEmbedded){var t=!1,n=!0,o=!0;(e=e||{}).silent&&(o=n=!(t=!0)),s.ping({silent:t,spinner:n,reload:o,callback:function(){s._initializeCallbacks.forEach(function(e){e()})}})}},s.cache=function(e){var t={};try{var n=function a(e){return(document.cookie.match("(^|; )"+e+"=([^;]*)")||0)[2]};t=JSON.parse(decodeURIComponent(n("locksmith-params")||"{}"))}catch(d){}if(e){for(var o in e)t[o]=e[o];document.cookie="locksmith-params=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/",document.cookie="locksmith-params="+encodeURIComponent(JSON.stringify(t))+"; path=/"}return t},s.cache.cart=s.state.cart,s.cache.cartLastSaved=null,s.params=s.cache(),s.util.reload=function(){s.reloading=!0;try{window.location.href=window.location.href.replace(/#.*/,"")}catch(d){s.util.console.error("Preferred reload method failed",d),window.location.reload()}},s.cache.saveCart=function(e){if(!s.cache.cart||s.cache.cart===s.cache.cartLastSaved)return e?e():null;var t=s.cache.cartLastSaved;s.cache.cartLastSaved=s.cache.cart,fetch("/cart/update.js",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({attributes:{locksmith:s.cache.cart}})}).then(function(e){if(!e.ok)throw new Error("Cart update failed: "+e.status);return e.json()}).then(function(){e&&e()})["catch"](function(e){if(s.cache.cartLastSaved=t,!s.reloading)throw e})},s.util.spinnerHTML='<style>body{background:#FFF}@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}#loading{display:flex;width:100%;height:50vh;
5color:#777;align-items:center;justify-content:center}#loading .spinner{display:block;animation:spin 600ms linear infinite;position:relative;width:50px;height:50px}#loading .spinner-ring{stroke:currentColor;stroke-dasharray:100%;stroke-width:2px;stroke-linecap:round;fill:none}</style><div id="loading"><div class="spinner"><svg width="100%" height="100%"><svg preserveAspectRatio="xMinYMin"><circle class="spinner-ring" cx="50%" cy="50%" r="45%"></circle></svg></svg></div></div>',s.util.clobberBody=function(e){document.body.innerHTML=e},s.util.clobberDocument=function(e){e.responseText&&(e=e.responseText),document.documentElement&&document.removeChild(document.documentElement);var t=document.open("text/html","replace");t.writeln(e),t.close(),setTimeout(function(){var e=t.querySelector("[autofocus]");e&&e.focus()},100)},s.util.serializeForm=function(e){if(e&&"FORM"===e.nodeName){var t,n,o={};for(t=e.elements.length-1;0<=t;t-=1)if(""!==e.elements[t].name)switch(e.elements[t].nodeName){case"INPUT":switch(e.elements[t].type){default:case"text":case"hidden":case"password":case"button":case"reset":case"submit":o[e.elements[t].name]=e.elements[t].value;break;case"checkbox":case"radio":e.elements[t].checked&&(o[e.elements[t].name]=e.elements[t].value);break;case"file":}break;case"TEXTAREA":o[e.elements[t].name]=e.elements[t].value;break;case"SELECT":switch(e.elements[t].type){case"select-one":o[e.elements[t].name]=e.elements[t].value;break;case"select-multiple":for(n=e.elements[t].options.length-1;0<=n;n-=1)e.elements[t].options[n].selected&&(o[e.elements[t].name]=e.elements[t].options[n].value)}break;case"BUTTON":switch(e.elements[t].type){case"reset":case"submit":case"button":o[e.elements[t].name]=e.elements[t].value}}return o}},s.util.on=function(e,i,s,t){t=t||document;var c="locksmith-"+e+i,n=function(e){var t=e.target,n=e.target.parentElement,o=t&&t.className&&(t.className.baseVal||t.className)||"",a=n&&n.className&&(n.className.baseVal||n.className)||"";("string"==typeof o&&-1!==o.split(/\s+/).indexOf(i)||"string"==typeof a&&-1!==a.split(/\s+/).indexOf(i))&&!e[c]&&(e[c]=!0,s(e))};t.attachEvent?t.attachEvent(e,n):t.addEventListener(e,n,!1)},s.util.enableActions=function(e){s.util.on("click","locksmith-action",function(e){e.preventDefault();var t=e.target;t.dataset.confirmWith&&!confirm(t.dataset.confirmWith)||(t.disabled=!0,t.innerText=t.dataset.disableWith,s.post("/action",t.dataset.locksmithParams,{spinner:!1,type:"text",success:function(e){(e=JSON.parse(e.responseText)).message&&alert(e.message),s.util.reload()}}))},e)},s.util.inject=function(e,t){var n=["data","locksmith","append"];if(-1!==t.indexOf(n.join("-"))){var o=document.createElement("div");o.innerHTML=t,e.appendChild(o)}else e.innerHTML=t;var a,i,s=e.querySelectorAll("script");for(i=0;i<s.length;++i){a=s[i];var c=document.createElement("script");if(a.type&&(c.type=a.type),a.src)c.src=a.src;else{var l=document.createTextNode(a.innerHTML);c.appendChild(l)}e.appendChild(c)}var r=e.querySelector("[autofocus]");r&&r.focus()},s.post=function(e,t,n){!1!==(n=n||{}).spinner&&s.util.clobberBody(s.util.spinnerHTML);var o={};n.container===document?(o.layout=1,n.success=function(e){s.util.clobberDocument(e)}):n.container&&(o.layout=0,n.success=function(e){var t="string"==typeof n.container?document.getElementById(n.container):n.container;t&&(s.util.inject(t,e),t.id===t.firstChild.id&&t.parentElement.replaceChild(t.firstChild,t))}),n.form_type&&(t.form_type=n.form_type),n.include_layout_classes!==undefined&&(t.include_layout_classes=n.include_layout_classes),n.lock_id!==undefined&&(t.lock_id=n.lock_id),s.loading=!0;var a=s.util.makeUrl(e,o),i="json"===n.type||"text"===n.type;fetch(a,{method:"POST",headers:{"Content-Type":"application/json",Accept:i?"application/json":"text/html"},body:JSON.stringify(t)}).then(function(e){if(!e.ok)throw new Error("Request failed: "+e.status);return e.text()}).then(function(e){var t=n.success||s.util.clobberDocument;t(i?{responseText:e}:e)})["catch"](function(e){if(!s.reloading)if("dashboard.weglot.com"!==window.location.host){if(!n.silent)throw alert("Something went wrong! Please refresh and try again."),e;console.error(e)}else console.error(e)})["finally"](function(){s.loading=!1})},s.postResource=function(e,t){e.path=s.path,e.search=window.location.search,e.state=s.state,e.passcode&&(e.passcode=e.passcode.trim()),e.email&&(e.email=e.email.trim()),e.state.cart=s.cache.cart,e.locksmith_json=s.jsonTag,e.locksmith_json_signature=s.jsonTagSignature,s.post("/resource",e,t)},s.ping=function(t){if(!s.isEmbedded){t=t||{};var n=function(){t.reload?s.util.reload():"function"==typeof t.callback&&t.callback()};s.post("/ping",{path:s.path,search:window.location.search,state:s.state},{spinner:!!t.spinner,silent:"undefined"==typeof t.silent||t.silent,type:"text",success:function(e){e&&e.responseText?((e=JSON.parse(e.responseText)).messages&&0<e.messages.length&&s.showMessages(e.messages),e.cart&&s.cache.cart!==e.cart?(s.cache.cart=e.cart,s.cache.saveCart(function(){e.cart&&e.cart.match(/^.+:/)?(t.reload||"function"!=typeof t.callback||t.callback(),s.util.reload()):n()})):n()):console.error("[Locksmith] Invalid result in ping callback:",e)}})}},s.timeoutMonitor=function(){var e=s.cache.cart;s.ping({callback:function(){e!==s.cache.cart||setTimeout(function(){s.timeoutMonitor()},6e4)}})},s.showMessages=function(e){var t=document.createElement("div");t.style.position="fixed",t.style.left=0,t.style.right=0,t.style.bottom="-50px",t.style.opacity=0,t.style.background="#191919",t.style.color="#ddd",t.style.transition="bottom 0.2s, opacity 0.2s",t.style.zIndex=999999,t.innerHTML=["<style>","  .locksmith-ab .locksmith-b { display: none; }","  .locksmith-ab.toggled .locksmith-b { display: flex; }","  .locksmith-ab.toggled .locksmith-a { display: none; }","  .locksmith-flex { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; padding: 10px 20px; }","  .locksmith-message + .locksmith-message { border-top: 1px #555 solid; }","  .locksmith-message a { color: inherit; font-weight: bold; }","  .locksmith-message a:hover { color: inherit; opacity: 0.8; }","  a.locksmith-ab-toggle { font-weight: inherit; text-decoration: underline; }","  .locksmith-text { flex-grow: 1; }","  .locksmith-cta { flex-grow: 0; text-align: right; }","  .locksmith-cta button { transform: scale(0.8); transform-origin: left; }","  .locksmith-cta > * { display: block; }","  .locksmith-cta > * + * { margin-top: 10px; }","  .locksmith-message a.locksmith-close { flex-grow: 0; text-decoration: none; margin-left: 15px; font-size: 30px; font-family: monospace; display: block; padding: 2px 10px; }","  @media screen and (max-width: 600px) {","    .locksmith-wide-only { display: none !important; }","    .locksmith-flex { padding: 0 15px; }","    .locksmith-flex > * { margin-top: 5px; margin-bottom: 5px; }","    .locksmith-cta { text-align: left; }","  }","  @media screen and (min-width: 601px) {","    .locksmith-narrow-only { display: none !important; }","  }","</style>"].join("")+e.map(function(e){return'<div class="locksmith-message">'+e+"</div>"}).join(""),document.body.appendChild(t),document.body.style.position="relative",document.body.parentElement.style.paddingBottom=t.offsetHeight+"px",setTimeout(function(){t.style.bottom=0,t.style.opacity=1},50),s.util.on("click","locksmith-ab-toggle",function(e){e.preventDefault();for(var t=e.target.parentElement;-1===t.className.split(" ").indexOf("locksmith-ab");)t=t.parentElement;-1!==t.className.split(" ").indexOf("toggled")?t.className=t.className.replace("toggled",""):t.className=t.className+" toggled"}),s.util.enableActions(t)}}()}();</script>
5
6      
6<script data-locksmith>Locksmith.cache.cart=null</script>
6
7
8  
8<script data-locksmith>Locksmith.jsonTag="{\"version\":\"v346\",\"locked\":false,\"initialized\":true,\"scope\":\"cart\",\"access_granted\":true,\"access_denied\":false,\"requires_customer\":false,\"manual_lock\":false,\"remote_lock\":false,\"has_timeout\":false,\"remote_rendered\":null,\"hide_resource\":false,\"hide_links_to_resource\":false,\"hide_price\":false,\"hide_add_to_cart\":false,\"transparent\":true,\"locks\":{\"all\":[],\"opened\":[]},\"keys\":[],\"keys_signature\":\"a6111dc4847a5059d4622e3d27b184dd5cbae461b5d6fc459feab12efb47932d\",\"state\":{\"template\":\"cart\",\"theme\":151830298694,\"product\":null,\"collection\":null,\"page\":null,\"blog\":null,\"article\":null,\"app\":null},\"now\":1791103105,\"path\":\"\\\/cart\",\"locale_root_url\":\"\\\/\",\"canonical_url\":\"https:\\\/\\\/printroom.co\\\/cart\",\"customer_id\":null,\"customer_id_signature\":\"a6111dc4847a5059d4622e3d27b184dd5cbae461b5d6fc459feab12efb47932d\",\"cart\":null}";Locksmith.jsonTagSignature="e2e651e29dd1fb1874f2b86b720ffa803111aef2e71e8306d891ec937891e2d5"</script>
8
9<meta name="google-site-verification" content="r89mOlbEOfEjECOwEHOd5jrv5jGOJeGHPXM78LaGLXY" />
10    
11    <meta charset="utf-8">
12    <meta http-equiv="X-UA-Compatible" content="IE=edge">
13    <meta name="viewport" content="width=device-width,initial-scale=1">
14    <meta name="theme-color" content="">
15<script>
16    window.dataLayer = window.dataLayer || [];
17    window.dataLayer.push({
18      store_access: 'public',
19      store_type: 'main',
20      page_template: "cart"
21    });
22    window.prTrackLead = window.prTrackLead || function (detail) {
23      try {
24        detail = detail || {};
25        var ud = detail.user_data || {};
26        var email = (ud.email || '').toString().trim().toLowerCase();
27        var phone = (ud.phone_number || '').toString().replace(/[^0-9+]/g, '');
28        window.dataLayer.push({
29          event: 'generate_lead',
30          lead_type: detail.lead_type || 'unknown',
31          form_id: detail.form_id || null,
32          page_path: window.location.pathname,
33          /* Enhanced Conversions for Leads — GTM's user-provided-data variable reads
34             user_data.{email,phone_number}; Google hashes (SHA-256) client-side.
35             Same key shape as the quote/book-a-call pushes in global.bundle.js so ONE
36             GTM variable covers every lead type. */
37          user_data: {
38            email: email || undefined,
39            phone_number: phone || undefined
40          }
41        });
42      } catch (e) {}
43    };
44  </script>
44<script>
45    if (!window.__prGtmLoaded) {
46      window.__prGtmLoaded = true;
vendor: 455 bytes, lines 46-56
46
47      (function (w, d, s, l, i) {
48        w[l] = w[l] || [];
49        w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });
50        var f = d.getElementsByTagName(s)[0],
51          j = d.createElement(s),
52          dl = l != 'dataLayer' ? '&l=' + l : '';
53        j.async = true;
54        j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl;
55        f.parentNode.insertBefore(j, f);
56      })(window, document, 'script', 'dataLayer', '
56GTM-W9DFFGB
vendor: 8 bytes, lines 56-57
56');
57    
57}
58  </script>
58
59
60    <link rel="canonical" href="https://printroom.co/cart">
61    <meta name="robots" content="noindex, follow">
62    
63    
64
65    <link rel="preconnect" href="https://cdn.shopify.com" crossorigin>
66
67    
67<script>
68(function() {
69  'use strict';
70  var observer = new MutationObserver(function(mutations) {
71    mutations.forEach(function(mutation) {
72      mutation.addedNodes.forEach(function(node) {
73        if (node.tagName === 'SCRIPT' && node.src && node.src.includes('popt.in')) {
74          node.remove();
75        }
76      });
77    });
78  });
79  observer.observe(document.documentElement, { childList: true, subtree: true });
80})();
81</script>
81<script>
82document.addEventListener('DOMContentLoaded', function() {
83  var scripts = document.querySelectorAll('script[data-block-script]');
84  if (!scripts.length) return;
85  if (window.Shopify && window.Shopify.designMode) {
86    scripts.forEach(function(s) {
87      var real = document.createElement('script');
88      real.textContent = s.textContent;
89      s.parentNode.replaceChild(real, s);
90    });
91    return;
92  }
93  var io = new IntersectionObserver(function(entries) {
94    entries.forEach(function(entry) {
95      if (!entry.isIntersecting) return;
96      io.unobserve(entry.target);
97      var pending = entry.target.querySelector('script[data-block-script]');
98      if (pending) {
99        var real = document.createElement('script');
100        real.textContent = pending.textContent;
101        pending.parentNode.replaceChild(real, pending);
102      }
103    });
104  }, { rootMargin: '300px' });
105  scripts.forEach(function(s) {
106    var block = s.closest('[data-ai-block]') || s.parentElement;
107    io.observe(block);
108  });
109});
110</script>
110<script>
111setTimeout(function() {
112  'use strict';
113
114  // Google Tag Manager loads early + reliably via the 'gtm-head' snippet
115  // (settings.gtm_container_id). The old "remove existing GTM then re-inject after
116  // 3s" hack saved ~922ms but delayed the Ads Conversion Linker (breaking gclid
117  // attribution) and dropped fast-bounce visitors from analytics. Do NOT re-add it.
118
119  // LAZY LOAD THIRD-PARTY ANALYTICS
120  var loadThirdPartyScripts = function() {
121    if (typeof fbq === 'undefined') {
122      !function(f,b,e,v,n,t,s){
123        if(f.fbq)return;n=f.fbq=function(){n.callMethod?
124        n.callMethod.apply(n,arguments):n.queue.push(arguments)};
125        if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
126        n.queue=[];t=b.createElement(e);t.async=!0;
127        t.src=v;s=b.getElementsByTagName(e)[0];
128        s.parentNode.insertBefore(t,s)
129      }(window,document,'script','https://connect.facebook.net/en_US/fbevents.js');
130    }
131    if (typeof clarity === 'undefined' && window.clarityCode) {
132      (function(c,l,a,r,i,t,y){
133        c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
134        t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
135        y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
136      })(window,document,"clarity","script",window.clarityCode);
137    }
138  };
139  if ('requestIdleCallback' in window) {
140    requestIdleCallback(loadThirdPartyScripts, { timeout: 5000 });
141  } else {
142    setTimeout(loadThirdPartyScripts, 5000);
143  }
144
145  // LINK PREFETCH ON HOVER
146  var NO_PREFETCH = ['/cart','/checkout','/account','/admin','/password','/challenge','/apps/','/tools/','/services/'];
147  var prefetched = {};
148  var hoverTimer = null;
149
150  function shouldPrefetch(href) {
151    try {
152      var url = new URL(href, location.origin);
153      if (url.origin !== location.origin) return false;
154      if (url.pathname === location.pathname) return false;
155      if (prefetched[url.pathname]) return false;
156      if (navigator.connection && navigator.connection.saveData) return false;
157      for (var i = 0; i < NO_PREFETCH.length; i++) {
158        if (url.pathname.indexOf(NO_PREFETCH[i]) === 0) return false;
159      }
160      var ext = url.pathname.split('.').pop();
161      if (['jpg','jpeg','png','gif','svg','webp','pdf','zip','css','js'].indexOf(ext) !== -1) return false;
162      return true;
163    } catch (e) {
164      return false;
165    }
166  }
167
168  function prefetchUrl(href) {
169    var url = new URL(href, location.origin);
170    if (prefetched[url.pathname]) return;
171    prefetched[url.pathname] = true;
172    var link = document.createElement('link');
173    link.rel = 'prefetch';
174    link.href = href;
175    link.as = 'document';
176    document.head.appendChild(link);
177  }
178
179  document.addEventListener('pointerenter', function(e) {
180    var a = e.target.closest ? e.target.closest('a[href]') : null;
181    if (!a || !shouldPrefetch(a.href)) return;
182    var delay = e.pointerType === 'mouse' ? 65 : 0;
183    hoverTimer = setTimeout(function() { prefetchUrl(a.href); }, delay);
184  }, { capture: true, passive: true });
185
186  document.addEventListener('pointerleave', function() {
187    if (hoverTimer) { clearTimeout(hoverTimer); hoverTimer = null; }
188  }, { capture: true, passive: true });
189
190  if ('requestIdleCallback' in window) {
191    requestIdleCallback(function() {
192      var navLinks = document.querySelectorAll('nav a[href], [data-theme-header] a[href]');
193      var count = 0;
194      navLinks.forEach(function(a) {
195        if (count < 5 && shouldPrefetch(a.href)) {
196          prefetchUrl(a.href);
197          count++;
198        }
199      });
200    }, { timeout: 3000 });
201  }
202
203  // BFCACHE SUPPORT
204  window.addEventListener('pageshow', function(event) {
205    if (event.persisted) {
206      fetch('/cart.js').then(function(r) { return r.json(); }).then(function(data) {
207        document.querySelectorAll('[data-cart-count]').forEach(function(el) {
208          el.textContent = data.item_count;
209        });
210        if (window.Alpine && window.Alpine.store && window.Alpine.store('cartCount')) {
211          window.Alpine.store('cartCount').count = data.item_count;
212        }
213      }).catch(function() {});
214    }
215  });
216}, 0);
217</script>
217<script type="speculationrules">
218{
219  "prerender": [{
220    "where": {
221      "and": [
222        { "href_matches": "/*" },
223        { "not": { "href_matches": [
224          "/cart", "/cart/*",
225          "/checkout", "/checkout/*",
226          "/account", "/account/*",
227          "/admin/*",
228          "/password",
229          "/challenge/*",
230          "/apps/*",
231          "/tools/*",
232          "/services/*"
233        ] } },
234        { "not": { "selector_matches": "[target=_blank]" } }
235      ]
236    },
237    "eagerness": "moderate"
238  }],
239  "prefetch": [{
240    "where": {
241      "and": [
242        { "href_matches": "/*" },
243        { "not": { "href_matches": [
244          "/cart", "/cart/*",
245          "/checkout", "/checkout/*",
246          "/account", "/account/*"
247        ] } }
248      ]
249    },
250    "eagerness": "moderate"
251  }]
252}
253</script>
253
254
255
256<style>
257      .hero-image, [data-hero-image] { aspect-ratio: 16/9; width: 100%; height: auto; background-color: #f0f0f0; }
258      .product-image { aspect-ratio: 1/1; background-color: #fafafa; }
259      header, .header { min-height: 60px; }
260      main { min-height: 100vh; }
261      .skeleton { animation: skeleton-loading 1.5s infinite ease-in-out; background: linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%); background-size: 200% 100%; }
262      @keyframes skeleton-loading { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
263      @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } }
264      @media (max-width: 1023px) { .hero-image-mobile, [data-hero-image-mobile] { aspect-ratio: 9/16; } }
265    </style><link
266        rel="icon"
267        type="image/png"
268        href="//printroom.co/cdn/shop/files/pr_branding_logo_favicon_flag-01_11ede80e-5ae5-41fe-8eb2-87dee0e48e14.png?crop=center&height=32&v=1646960588&width=32"
269      ><link rel="preconnect" href="https://fonts.shopifycdn.com" crossorigin>
270    
271
272    
273
274 <!-- default to true --><!-- pageTitleTemplate: %% page_title %% -->
275  <!-- pageTitleToParse": Your Shopping Cart -->
276  <!-- pageTitleTruncateApplicable: true -->
277
278  <!-- pluginseo_pageTitleTemplateApplyToAll: true -->
279  <!-- pageTitleTruncateApplicable: true --><!-- Custom page title: Yes --><title>Your Shopping Cart | The Print Room</title> <!-- default to true --><!-- metaDescriptionTemplate: %% page_description %% -->
280  <!-- metaDescriptionToParse":  -->
281  <!-- metaDescriptionTruncateApplicable: true -->
282
283  <!-- pluginseo_metaDescriptionTemplateApplyToAll: true -->
284  <!-- metaDescriptionTruncateApplicable: true --><!-- Yes -->
284<script data-desc="seo-organization" type="application/ld+json">
285  {
286    "@context": "http://schema.org",
287    "@type": "Organization",
288    "additionalType": "https://schema.org/OnlineStore",
289    "@id": "https://printroom.co#organization",
290    "name": "The Print Room",
291    "url": "https://printroom.co",
292    "description": "NZ’s experts in custom t-shirt printing, tote bags, uniforms, and branded merchandise. Print Room offers high-quality screen printing and embroidery using eco-friendly inks. Fast turnaround, sustainable production, and trusted by leading New Zealand brands.","logo": {
293        "type": "ImageObject",
294        "url": "https://printroom.co/cdn/shop/t/59/assets/pluginseo_structuredDataLogo_small.png?v=39003"
295      },
296      "image": "https://printroom.co/cdn/shop/t/59/assets/pluginseo_structuredDataLogo_small.png?v=39003","areaServed": [{ "@type": "Country", "name": "Australia" },
297    { "@type": "Country", "name": "New Zealand" }],
298    "sameAs": ["https://www.linkedin.com/company/theprintroom"]
299  }
300</script>
300<script data-desc="seo-website" type="application/ld+json">
301  {
302    "@context": "http://schema.org",
303    "@type": "WebSite",
304    "name": "The Print Room",
305    "url": "https://printroom.co",
306    "inLanguage": "en",
307    "potentialAction": {
308      "@type": "SearchAction",
309      "target": "https://printroom.co/search?q={search_term_string}",
310      "query-input": "required name=search_term_string"
311    }
312  }
313</script>
313<meta name="pluginseo" content="Plug in SEO Plus" data-ptf="s-te_df-ap" data-mdf="s-te_df" />
314
315
316    
316<script type="esms-options">
317  {
318    "noLoadEventRetriggers": true
319  }
320</script>
320
321
322<script>
323  if (
324    !(HTMLScriptElement.supports && HTMLScriptElement.supports('importmap'))
325  ) {
326    const importMapShimScriptEl = document.createElement('script');
327    importMapShimScriptEl.src = '//printroom.co/cdn/shop/t/59/assets/es-module-shims.bundle.min.js?v=98603786603752121101787098437'
328    importMapShimScriptEl.async = true;
329
330    document.currentScript.after(importMapShimScriptEl);
331  }
332</script>
vendor: 1 bytes, line 332
332
333<script async crossorigin fetchpriority="high" src="/cdn/shopifycloud/importmap-polyfill/es-modules-shim.2.4.0.js"></script>
vendor: 1 bytes, line 333
333
334<script type="importmap">
335  {
336    "imports": {
337      "vendor": "//printroom.co/cdn/shop/t/59/assets/vendor.bundle.min.js?v=124729801276099409011787098433",
338      "deferrable-data": "//printroom.co/cdn/shop/t/59/assets/deferrable-data.bundle.js?v=160370895301608380811787098437",
339      "@supabase/supabase-js": "//printroom.co/cdn/shop/t/59/assets/supabase-js.bundle.js?v=151185893978749678631787098436",
340      "product": "//printroom.co/cdn/shop/t/59/assets/island-product.bundle.js?v=53162399053546849101790733316",
341      "quick-buy": "//printroom.co/cdn/shop/t/59/assets/island-quick-buy.bundle.js?v=147469616221971819701787098437",
342      "ai-chatbot": "//printroom.co/cdn/shop/t/59/assets/ai-chatbot.bundle.js?v=114215721854634402901788472409",
343      "leavers-quote-builder": "//printroom.co/cdn/shop/t/59/assets/leavers-quote-builder.bundle.js?v=140741536858912509621787098436",
344      "leavers-product-grid": "//printroom.co/cdn/shop/t/59/assets/leavers-product-grid.bundle.js?v=101839867699394922961787098435"
345    }
346  }
347</script>
347
348
349<script>
350      (function() {
351        var _originalAlert = window.alert;
352        window.alert = function(message) {
353          if (message && message.toLowerCase().includes('personalized text')) {
354            message = 'This field is required to place an order.';
355          }
356          _originalAlert.call(window, message);
357        };
358      })();
359    </script>
359
360
361    
361<script>window.performance && window.performance.mark && window.performance.mark('shopify.content_for_header.start');</script>
361<meta name="google-site-verification" content="r89mOlbEOfEjECOwEHOd5jrv5jGOJeGHPXM78LaGLXY">
362<meta id="shopify-digital-wallet" name="shopify-digital-wallet" content="/7054289/digital_wallets/dialog">
363<meta id="in-context-paypal-metadata" data-shop-id="7054289" data-venmo-supported="false" data-environment="production" data-locale="en_US" data-paypal-v4="true" data-currency="USD">
364<link rel="ucp" href="/.well-known/ucp" version="2026-08-25"><link rel="alternate" hreflang="x-default" href="https://theprintroom.nz/cart">
365<link rel="alternate" hreflang="en" href="https://theprintroom.nz/cart">
366<link rel="alternate" hreflang="en-AU" href="https://printroom.co/en-au/cart">
367<link rel="alternate" hreflang="en-CN" href="https://printroom.co/cart">
368<link rel="alternate" hreflang="en-FR" href="https://printroom.co/cart">
369<link rel="alternate" hreflang="en-GB" href="https://printroom.co/cart">
370<link rel="alternate" hreflang="en-US" href="https://printroom.co/cart">
371<script async="async" src="/checkouts/internal/preloads.js?locale=en-US&default_configuration_id=488013894"></script>
371
372<link rel="preconnect" href="https://shop.app" crossorigin="anonymous">
373<script async="async" src="https://shop.app/checkouts/internal/preloads.js?locale=en-US&default_configuration_id=488013894&shop_id=7054289" crossorigin="anonymous"></script>
vendor: 1 bytes, line 373
373
374<script id="apple-pay-shop-capabilities" type="application/json">{"shopId":7054289,"countryCode":"NZ","currencyCode":"USD","merchantCapabilities":["supports3DS"],"merchantId":"gid:\/\/shopify\/Shop\/7054289","merchantName":"The Print Room","requiredBillingContactFields":["postalAddress","email","phone"],"requiredShippingContactFields":["postalAddress","email","phone"],"shippingType":"shipping","supportedNetworks":["visa","masterCard","amex","jcb"],"total":{"type":"pending","label":"The Print Room","amount":"1.00"},"shopifyPaymentsEnabled":true,"supportsSubscriptions":true}</script>
vendor: 1 bytes, line 374
374
375<script id="shopify-features" type="application/json">{"accessToken":"0a03320998ce9cf7ffe404a489cfebbd","betas":["rich-media-storefront-analytics"],"domain":"printroom.co","predictiveSearch":true,"shopId":7054289,"locale":"en"}</script>
vendor: 1 bytes, line 375
375
376<script>var Shopify = Shopify || {};
377Shopify.shop = "the-print-room.myshopify.com";
378Shopify.locale = "en";
379Shopify.currency = {"active":"USD","rate":"0.57265452"};
380Shopify.country = "US";
381Shopify.theme = {"name":"Print_Room_Co","id":151830298694,"schema_name":"Baseline","schema_version":"3.3.1","theme_store_id":null,"role":"main"};
382Shopify.theme.handle = "null";
383Shopify.theme.style = {"id":null,"handle":null};
384Shopify.cdnHost = "printroom.co/cdn";
385Shopify.routes = Shopify.routes || {};
386Shopify.routes.root = "/";
387Shopify.shopJsCdnBaseUrl = "https://cdn.shopify.com/shopifycloud/shop-js";
388Shopify.SignInWithShop = Shopify.SignInWithShop || {};
389Shopify.SignInWithShop.User = Shopify.SignInWithShop.User || {};
390Shopify.SignInWithShop.User.recognized = false;</script>
vendor: 1 bytes, line 390
390
391<script type="module">!function(o){(o.Shopify=o.Shopify||{}).modules=!0}(window);</script>
vendor: 1 bytes, line 391
391
392<script>!function(o){function n(){var o=[];function n(){o.push(Array.prototype.slice.apply(arguments))}return n.q=o,n}var t=o.Shopify=o.Shopify||{};t.loadFeatures=n(),t.autoloadFeatures=n()}(window);</script>
vendor: 1 bytes, line 392
392
393<script>
394  window.ShopifyPay = window.ShopifyPay || {};
395  window.ShopifyPay.apiHost = "shop.app\/pay";
396  window.ShopifyPay.redirectState = null;
397</script>
vendor: 1 bytes, line 397
397
398<script>
399  window.Shopify = window.Shopify || {};
400  window.Shopify.SignInWithShop = window.Shopify.SignInWithShop || {};
401  window.Shopify.SignInWithShop.assetMetrics = { sampleRate: 0.25 };
402  window.Shopify.SignInWithShop.eligible = true;
403</script>
vendor: 1 bytes, line 403
403
404<script id="shop-js-analytics" type="application/json">{"pageType":"cart"}</script>
vendor: 1 bytes, line 404
404
405<script defer="defer" async type="module" src="https://cdn.shopify.com/shopifycloud/shop-js/modules/v2/loader.init-shop-cart-sync.en.esm.js"></script>
vendor: 1 bytes, line 405
405
406<script type="module">
407  await import("https://cdn.shopify.com/shopifycloud/shop-js/modules/v2/loader.init-shop-cart-sync.en.esm.js");
408
409  window.Shopify.SignInWithShop?.initShopCartSync?.({"fedCMEnabled":true,"windoidEnabled":true});
410
411</script>
vendor: 1 bytes, line 411
411
412<script>
413  window.Shopify = window.Shopify || {};
414  if (!window.Shopify.featureAssets) window.Shopify.featureAssets = {};
415  window.Shopify.featureAssets['shop-js'] = {"avatar":["modules/v2/loader.avatar.en.esm.js"],"checkout-modal":["modules/v2/loader.checkout-modal.en.esm.js"],"init-customer-accounts-sign-up":["modules/v2/loader.init-customer-accounts-sign-up.en.esm.js"],"init-customer-accounts":["modules/v2/loader.init-customer-accounts.en.esm.js"],"init-fed-cm":["modules/v2/loader.init-fed-cm.en.esm.js"],"init-shop-cart-sync":["modules/v2/loader.init-shop-cart-sync.en.esm.js"],"init-shop-email-lookup-coordinator":["modules/v2/loader.init-shop-email-lookup-coordinator.en.esm.js"],"init-shop-for-new-customer-accounts":["modules/v2/loader.init-shop-for-new-customer-accounts.en.esm.js"],"init-shop-user-recognition":["modules/v2/loader.init-shop-user-recognition.en.esm.js"],"init-windoid":["modules/v2/loader.init-windoid.en.esm.js"],"lead-capture":["modules/v2/loader.lead-capture.en.esm.js"],"listener":["modules/v2/loader.listener.en.esm.js"],"pay-button":["modules/v2/loader.pay-button.en.esm.js"],"payment-terms":["modules/v2/loader.payment-terms.en.esm.js"],"shop-button":["modules/v2/loader.shop-button.en.esm.js"],"shop-cart-sync":["modules/v2/loader.shop-cart-sync.en.esm.js"],"shop-cash-offers":["modules/v2/loader.shop-cash-offers.en.esm.js"],"shop-follow-button":["modules/v2/loader.shop-follow-button.en.esm.js"],"shop-login-button":["modules/v2/loader.shop-login-button.en.esm.js"],"shop-login":["modules/v2/loader.shop-login.en.esm.js"],"shop-toast-manager":["modules/v2/loader.shop-toast-manager.en.esm.js"],"shop-user-recognition":["modules/v2/loader.shop-user-recognition.en.esm.js"]};
416</script>
vendor: 1 bytes, line 416
416
417<script>(function() {
418  var isLoaded = false;
419  function asyncLoad() {
420    if (isLoaded) return;
421    isLoaded = true;
422    var urls = ["\/\/d1liekpayvooaz.cloudfront.net\/apps\/customizery\/customizery.js?shop=the-print-room.myshopify.com","https:\/\/app.carboncheckout.com\/assets\/api\/shopify.min.js?shop=the-print-room.myshopify.com","https:\/\/static.klaviyo.com\/onsite\/js\/klaviyo.js?company_id=WkJ8Uf\u0026shop=the-print-room.myshopify.com","https:\/\/cdn.nfcube.com\/instafeed-dfc514f941e0dbcfd9799eba509c69d2.js?shop=the-print-room.myshopify.com","\/\/d1liekpayvooaz.cloudfront.net\/apps\/uploadery\/uploadery.js?shop=the-print-room.myshopify.com","https:\/\/cdn.grw.reputon.com\/assets\/widget.js?shop=the-print-room.myshopify.com","https:\/\/chimpstatic.com\/mcjs-connected\/js\/users\/3ec9f5a684c36f6bf11dc30fc\/1a983ba3b184a8fb5b6da3882.js?shop=the-print-room.myshopify.com","https:\/\/cdn.hextom.com\/js\/quickannouncementbar.js?shop=the-print-room.myshopify.com","https:\/\/app.popt.in\/pixel.js?id=e7ff5c60e84fb\u0026shop=the-print-room.myshopify.com"];
423    for (var i = 0; i < urls.length; i++) {
424      var s = document.createElement('script');
425      s.type = 'text/javascript';
426      s.async = true;
427      s.src = urls[i];
428      var x = document.getElementsByTagName('script')[0];
429      x.parentNode.insertBefore(s, x);
430    }
431  };
432  if(window.attachEvent) {
433    window.attachEvent('onload', asyncLoad);
434  } else {
435    window.addEventListener('load', asyncLoad, false);
436  }
437})();</script>
vendor: 1 bytes, line 437
437
438<script id="__st">var __st={"a":7054289,"offset":46800,"reqid":"75a7c00c-de80-4178-96de-a80299f317cf-1791103105","pageurl":"printroom.co\/cart","u":"6d6a63147c90","p":"cart"};</script>
vendor: 1 bytes, line 438
438
439<script>window.ShopifyPaypalV4VisibilityTracking = true;</script>
vendor: 1 bytes, line 439
439
440<script id="captcha-bootstrap">!function(){'use strict';const t='contact',e='account',n='new_comment',o=[[t,t],['blogs',n],['comments',n],[t,'customer']],c=[[e,'customer_login'],[e,'guest_login'],[e,'recover_customer_password'],[e,'create_customer']],r=t=>t.map((([t,e])=>`form[action*='/${t}']:not([data-nocaptcha='true']) input[name='form_type'][value='${e}']`)).join(','),a=t=>()=>t?[...document.querySelectorAll(t)].map((t=>t.form)):[];function s(){const t=[...o],e=r(t);return a(e)}const i='password',u='form_key',d=['recaptcha-v3-token','g-recaptcha-response','h-captcha-response',i],f=()=>{try{return window.sessionStorage}catch{return}},m='__shopify_v',_=t=>t.elements[u];function p(t,e,n=!1){try{const o=window.sessionStorage,c=JSON.parse(o.getItem(e)),{data:r}=function(t){const{data:e,action:n}=t;return t[m]||n?{data:e,action:n}:{data:t,action:n}}(c);for(const[e,n]of Object.entries(r))t.elements[e]&&(t.elements[e].value=n);n&&o.removeItem(e)}catch(o){console.error('form repopulation failed',{error:o})}}const l='form_type',E='cptcha';function T(t){t.dataset[E]=!0}const w=window,h=w.document,L='Shopify',v='ce_forms',y='captcha';let A=!1;((t,e)=>{const n=(g='f06e6c50-85a8-45c8-87d0-21a2b65856fe',I='https://cdn.shopify.com/shopifycloud/storefront-forms-hcaptcha/ce_storefront_forms_captcha_hcaptcha.v1.5.3.iife.js',D={infoText:'Protected by hCaptcha',privacyText:'Privacy',termsText:'Terms'},(t,e,n)=>{const o=w[L][v],c=o.bindForm;if(c)return c(t,g,e,D).then(n);var r;o.q.push([[t,g,e,D],n]),r=I,A||(h.body.append(Object.assign(h.createElement('script'),{id:'captcha-provider',async:!0,src:r})),A=!0)});var g,I,D;w[L]=w[L]||{},w[L][v]=w[L][v]||{},w[L][v].q=[],w[L][y]=w[L][y]||{},w[L][y].protect=function(t,e){n(t,void 0,e),T(t)},Object.freeze(w[L][y]),function(t,e,n,w,h,L){const[v,y,A,g]=function(t,e,n){const i=e?o:[],u=t?c:[],d=[...i,...u],f=r(d),m=r(i),_=r(d.filter((([t,e])=>n.includes(e))));return[a(f),a(m),a(_),s()]}(w,h,L),I=t=>{const e=t.target;return e instanceof HTMLFormElement?e:e&&e.form},D=t=>v().includes(t);t.addEventListener('submit',(t=>{const e=I(t);if(!e)return;const n=D(e)&&!e.dataset.hcaptchaBound&&!e.dataset.recaptchaBound,o=_(e),c=g().includes(e)&&(!o||!o.value);(n||c)&&t.preventDefault(),c&&!n&&(function(t){try{if(!f())return;!function(t){const e=f();if(!e)return;const n=_(t);if(!n)return;const o=n.value;o&&e.removeItem(o)}(t);const e=Array.from(Array(32),(()=>Math.random().toString(36)[2])).join('');!function(t,e){_(t)||t.append(Object.assign(document.createElement('input'),{type:'hidden',name:u})),t.elements[u].value=e}(t,e),function(t,e){const n=f();if(!n)return;const o=[...t.querySelectorAll(`input[type='${i}']`)].map((({name:t})=>t)),c=[...d,...o],r={};for(const[a,s]of new FormData(t).entries())c.includes(a)||(r[a]=s);n.setItem(e,JSON.stringify({[m]:1,action:t.action,data:r}))}(t,e)}catch(e){console.error('failed to persist form',e)}}(e),e.submit())}));const S=(t,e)=>{t&&!t.dataset[E]&&(n(t,e.some((e=>e===t))),T(t))};for(const o of['focusin','change'])t.addEventListener(o,(t=>{const e=I(t);D(e)&&S(e,y())}));const B=e.get('form_key'),M=e.get(l),P=B&&M;t.addEventListener('DOMContentLoaded',(()=>{const t=y();if(P)for(const e of t)e.elements[l].value===M&&p(e,B);[...new Set([...A(),...v().filter((t=>'true'===t.dataset.shopifyCaptcha))])].forEach((e=>S(e,t)))}))}(h,new URLSearchParams(w.location.search),n,t,e,['guest_login'])})(!0,!0)}();</script>
vendor: 1 bytes, line 440
440
441<script integrity="sha256-JjoPp5ZfB1sSAs5SQaol1x1GgvveM+BgmRzyDexInEQ=" data-source-attribution="shopify.loadfeatures" defer="defer" src="//printroom.co/cdn/shopifycloud/storefront/assets/storefront/load_feature-1bd60354.js" crossorigin="anonymous"></script>
vendor: 1 bytes, line 441
441
442<script>(function () {var userAgent = navigator.userAgent;var platform = navigator.platform;var maxTouchPoints = navigator.maxTouchPoints || 0;var isIOS = /iPad|iPhone|iPod/.test(platform) || (platform === 'MacIntel' && maxTouchPoints > 1);var isMacSafari = platform.indexOf('Mac') === 0 && /Safari/.test(userAgent) && !/Chrome|Chromium|CriOS|FxiOS|Edg|OPR|Android/.test(userAgent);var isAppleSafari = isIOS || isMacSafari;if (isAppleSafari) {fetch('/sf_private_access_tokens' + location.search).catch(function () {});}function browserMajorVersion(pattern) {var match = userAgent.match(pattern);return match ? parseInt(match[1], 10) : null;}function shouldLoadAutosizesPolyfill() {if (!window.PerformanceObserver?.supportedEntryTypes?.includes('paint')) {return false;}var chromeVersion = browserMajorVersion(/Chrome\/(\d+)/);if (chromeVersion !== null) {return chromeVersion < 126;}var firefoxVersion = browserMajorVersion(/Firefox\/(\d+)/);if (firefoxVersion !== null) {return firefoxVersion < 150;}var safariVersion = isAppleSafari ? browserMajorVersion(/Version\/(\d+).*Safari\//) : null;if (safariVersion !== null) {return safariVersion < 27;}return true;}if (shouldLoadAutosizesPolyfill()) {var autosizesScript = document.createElement('script');autosizesScript.async = true;autosizesScript.crossOrigin = 'anonymous';autosizesScript.src = "//printroom.co/cdn/shopifycloud/storefront/assets/storefront/autosizes-84416378.js";(document.head || document.documentElement).appendChild(autosizesScript);}window.ShopifyAnalytics = window.ShopifyAnalytics || {};window.ShopifyAnalytics.performance = window.ShopifyAnalytics.performance || {};(function () {var LONG_FRAME_THRESHOLD = 50;var longAnimationFrames = [];var activeRafId = null;function collectLongFrames() {var previousTime = null;function rafMonitor(now) {if (activeRafId === null) {return;}var delta = now - previousTime;if (delta > LONG_FRAME_THRESHOLD) {longAnimationFrames.push({startTime: previousTime,endTime: now,});}previousTime = now;activeRafId = requestAnimationFrame(rafMonitor);}previousTime = performance.now();activeRafId = requestAnimationFrame(rafMonitor);}if (!window.PerformanceObserver?.supportedEntryTypes?.includes('long-animation-frame')) {collectLongFrames();var timeoutId = setTimeout(function () {cancelAnimationFrame(activeRafId);}, 10000);window.ShopifyAnalytics.performance.getLongAnimationFrames = function (stopCollection) {if (stopCollection === undefined) {stopCollection = false;}if (stopCollection) {clearTimeout(timeoutId);cancelAnimationFrame(activeRafId);}return longAnimationFrames;};}})();})();</script>
442<script crossorigin="anonymous" defer="defer" src="//printroom.co/cdn/shopifycloud/storefront/assets/shopify_pay/storefront-616277c7.js?v=20250812"></script>
vendor: 1 bytes, line 442
442
443<script id="shopify-origin-trials" async="async" integrity="sha256-qJbe/jEZBHtr5W/BlA2cKAz3vkXu6vJQyLjgvgCC86g=" src="//cdn.shopify.com/shopifycloud/storefront/assets/storefront/origin_trials-318ab40a.js" crossorigin="anonymous" onload="window.__shopifyOriginTrialsDone = true" onerror="window.__shopifyOriginTrialsDone = true"></script>
vendor: 1 bytes, line 443
443
444<script>
445  window.Shopify = window.Shopify || {};
446  window.Shopify.MCP = window.Shopify.MCP || {};
447  window.Shopify.MCP.enabled = true;
448  window.Shopify.MCP.shop = "the-print-room.myshopify.com";
449  window.Shopify.MCP.mcpEndpoint = "https:\/\/printroom.co\/api\/mcp";
450  window.Shopify.MCP.tools = [{"name":"search_shop_policies_and_faqs","description":"Used to get facts about the stores policies, products, or services.\nSome examples of questions you can ask are:\n  - What is your return policy?\n  - What is your shipping policy?\n  - What is your phone number?\n  - What are your hours of operation?\"\n","inputSchema":{"$schema":"https:\/\/json-schema.org\/draft\/2020-12\/schema","type":"object","properties":{"query":{"type":"string","description":"A natural language query."},"context":{"type":"string","description":"Additional information about the request such as user demographics, mood, location, or other relevant details that could help in tailoring the response appropriately."}},"required":["query"]}}];
451</script>
vendor: 1 bytes, line 451
451
452<script>(()=>{var d="shopify:webmcp_adapter_loaded",n=Symbol.for("shopify.webmcp_adapter_loading");function s(c,a,{win:r=window,doc:o=document}={}){function p(){try{return r.localStorage.getItem(d)==="true"}catch{return!1}}function l(){try{r.localStorage.setItem(d,"true")}catch{}}function u(){return typeof(o.modelContext||r.navigator?.modelContext)?.registerTool=="function"}function f(){if(r[n]||!u())return;let t=o.head||o.getElementsByTagName("head")[0];if(!t)return;let e=o.createElement("script");e.type="module",e.crossOrigin="anonymous",a&&(e.integrity=a),e.src=c,e.addEventListener("load",l,{once:!0}),e.addEventListener("error",()=>{r[n]=!1},{once:!0}),t.appendChild(e),r[n]=!0}function _(t){let e=o.getElementById("shopify-origin-trials");if(!e||r.__shopifyOriginTrialsDone){t();return}e.addEventListener("load",t,{once:!0}),e.addEventListener("error",t,{once:!0})}function i(){_(()=>r.setTimeout(f,0))}function m(){o.addEventListener("DOMContentLoaded",i,{once:!0})}p()?i():m()}s("\/\/printroom.co\/cdn\/shopifycloud\/storefront\/assets\/storefront\/webmcp-c6b62ece.js","sha256-ke4DDuBjdvea3vxLWxHc9E9nq8zihuG4IfYEGbb77ys=");})();
453</script>
vendor: 1 bytes, line 453
453
454<script data-source-attribution="shopify.dynamic_checkout.dynamic.init">var Shopify=Shopify||{};Shopify.PaymentButton=Shopify.PaymentButton||{isStorefrontPortableWallets:!0,init:function(){window.Shopify.PaymentButton.init=function(){};var t=document.createElement("script");t.src="https://printroom.co/cdn/shopifycloud/portable-wallets/latest/portable-wallets.en.js",t.type="module",document.head.appendChild(t)}};
455</script>
vendor: 1 bytes, line 455
455
456<script data-source-attribution="shopify.dynamic_checkout.buyer_consent">
457  function portableWalletsHideBuyerConsent(e){var t=document.getElementById("shopify-buyer-consent"),n=document.getElementById("shopify-subscription-policy-button");t&&n&&(t.classList.add("hidden"),t.setAttribute("aria-hidden","true"),n.removeEventListener("click",e))}function portableWalletsShowBuyerConsent(e){var t=document.getElementById("shopify-buyer-consent"),n=document.getElementById("shopify-subscription-policy-button");t&&n&&(t.classList.remove("hidden"),t.removeAttribute("aria-hidden"),n.addEventListener("click",e))}window.Shopify?.PaymentButton&&(window.Shopify.PaymentButton.hideBuyerConsent=portableWalletsHideBuyerConsent,window.Shopify.PaymentButton.showBuyerConsent=portableWalletsShowBuyerConsent);
458</script>
vendor: 1 bytes, line 458
458
459<script data-source-attribution="shopify.dynamic_checkout.cart.bootstrap">document.addEventListener("DOMContentLoaded",(function(){function t(){return document.querySelector("shopify-accelerated-checkout-cart, shopify-accelerated-checkout")}if(t())Shopify.PaymentButton.init();else{new MutationObserver((function(e,n){t()&&(Shopify.PaymentButton.init(),n.disconnect())})).observe(document.body,{childList:!0,subtree:!0})}}));
460</script>
460
461<link id="shopify-accelerated-checkout-styles" rel="stylesheet" media="screen" href="https://printroom.co/cdn/shopifycloud/portable-wallets/latest/accelerated-checkout-backwards-compat.css" crossorigin="anonymous">
462<style id="shopify-accelerated-checkout-cart">
463        #shopify-buyer-consent {
464  margin-top: 1em;
465  display: inline-block;
466  width: 100%;
467}
468
469#shopify-buyer-consent.hidden {
470  display: none;
471}
472
473#shopify-subscription-policy-button {
474  background: none;
475  border: none;
476  padding: 0;
477  text-decoration: underline;
478  font-size: inherit;
479  cursor: pointer;
480}
481
482#shopify-subscription-policy-button::before {
483  box-shadow: none;
484}
485
486      </style>
487
488<script id="shopify-cfh-end">window.performance && window.performance.mark && window.performance.mark('shopify.content_for_header.end');</script>
488
489
490      
491
492
493  <link
494    rel="preload"
495    as="font"
496    href="//printroom.co/cdn/fonts/dm_sans/dmsans_n5.8a0f1984c77eb7186ceb87c4da2173ff65eb012e.woff2"
497    type="font/woff2"
498    crossorigin
499  >
500
501
502
503  <link
504    rel="preload"
505    as="font"
506    href="//printroom.co/cdn/fonts/dm_sans/dmsans_n4.ec80bd4dd7e1a334c969c265873491ae56018d72.woff2"
507    type="font/woff2"
508    crossorigin
509  >
510
511
512
513<style data-shopify>
514  @font-face {
515  font-family: "DM Sans";
516  font-weight: 400;
517  font-style: normal;
518  font-display: swap;
519  src: url("//printroom.co/cdn/fonts/dm_sans/dmsans_n4.ec80bd4dd7e1a334c969c265873491ae56018d72.woff2") format("woff2"),
520       url("//printroom.co/cdn/fonts/dm_sans/dmsans_n4.87bdd914d8a61247b911147ae68e754d695c58a6.woff") format("woff");
521}
522
523  @font-face {
524  font-family: "DM Sans";
525  font-weight: 500;
526  font-style: normal;
527  font-display: swap;
528  src: url("//printroom.co/cdn/fonts/dm_sans/dmsans_n5.8a0f1984c77eb7186ceb87c4da2173ff65eb012e.woff2") format("woff2"),
529       url("//printroom.co/cdn/fonts/dm_sans/dmsans_n5.9ad2e755a89e15b3d6c53259daad5fc9609888e6.woff") format("woff");
530}
531
532@font-face {
533  font-family: "DM Sans";
534  font-weight: 700;
535  font-style: normal;
536  font-display: swap;
537  src: url("//printroom.co/cdn/fonts/dm_sans/dmsans_n7.97e21d81502002291ea1de8aefb79170c6946ce5.woff2") format("woff2"),
538       url("//printroom.co/cdn/fonts/dm_sans/dmsans_n7.af5c214f5116410ca1d53a2090665620e78e2e1b.woff") format("woff");
539}
540@font-face {
541  font-family: "DM Sans";
542  font-weight: 400;
543  font-style: italic;
544  font-display: swap;
545  src: url("//printroom.co/cdn/fonts/dm_sans/dmsans_i4.b8fe05e69ee95d5a53155c346957d8cbf5081c1a.woff2") format("woff2"),
546       url("//printroom.co/cdn/fonts/dm_sans/dmsans_i4.403fe28ee2ea63e142575c0aa47684d65f8c23a0.woff") format("woff");
547}
548@font-face {
549  font-family: "DM Sans";
550  font-weight: 700;
551  font-style: italic;
552  font-display: swap;
553  src: url("//printroom.co/cdn/fonts/dm_sans/dmsans_i7.52b57f7d7342eb7255084623d98ab83fd96e7f9b.woff2") format("woff2"),
554       url("//printroom.co/cdn/fonts/dm_sans/dmsans_i7.d5e14ef18a1d4a8ce78a4187580b4eb1759c2eda.woff") format("woff");
555}
556@font-face {
557  font-family: "DM Sans";
558  font-weight: 700;
559  font-style: normal;
560  font-display: swap;
561  src: url("//printroom.co/cdn/fonts/dm_sans/dmsans_n7.97e21d81502002291ea1de8aefb79170c6946ce5.woff2") format("woff2"),
562       url("//printroom.co/cdn/fonts/dm_sans/dmsans_n7.af5c214f5116410ca1d53a2090665620e78e2e1b.woff") format("woff");
563}
564</style>
565
566<style>:root {
567
568      --font-size-xs: 0.64rem;
569      --font-size-sm: 0.8rem;
570      --font-size-base: 1rem;
571      --font-size-lg: 1.25rem;
572      --font-size-xl: 1.563rem;
573      --font-size-2xl: 1.953rem;
574      --font-size-3xl: 2.441rem;
575      --font-size-4xl: 3.052rem;
576      --font-size-5xl: 3.815rem;
577      --font-size-6xl: 4.768rem;
578      --font-size-7xl: 5.96rem;
579      --font-size-8xl: 7.451rem;
580      --font-size-9xl: 9.313rem;
581
582      --type-scale-n-2: var(--font-size-xs);
583      --type-scale-n-1: var(--font-size-sm);
584      --type-scale-n0: var(--font-size-base);
585      --type-scale-n1: var(--font-size-lg);
586      --type-scale-n2: var(--font-size-xl);
587      --type-scale-n3: var(--font-size-2xl);
588      --type-scale-n4: var(--font-size-3xl);
589      --type-scale-n5: var(--font-size-4xl);
590      --type-scale-n6: var(--font-size-5xl);
591      --type-scale-n7: var(--font-size-6xl);
592      --type-scale-n8: var(--font-size-7xl);
593      --type-scale-n9: var(--font-size-8xl);
594      --type-scale-n10: var(--font-size-9xl);
595
596      --base-font-size: 93.75%;
597      --base-font-size-from-settings: 15;
598      --base-line-height: 1.2;
599      --heading-line-height: 1;
600
601      font-size: var(--base-font-size);
602      line-height: var(--base-line-height);
603
604      --heading-font-stack: "DM Sans", sans-serif;
605      --heading-font-weight: 500;
606      --heading-font-style: normal;
607
608
609      --body-font-stack: "DM Sans", sans-serif;
610      --body-font-weight: 400;
611      --body-font-bold: FontDrop;
612      --body-font-bold-italic: FontDrop;
613
614      --color-gridline: 30 35 38;
615      --gridline-width: 0px;
616
617      --text-border-width: 1px;
618      --checkbox-width: 1px;
619
620      --font-heading: "DM Sans", sans-serif;
621      --font-body: "DM Sans", sans-serif;
622      --font-body-weight: 400;
623      --font-body-style: normal;
624      --font-body-bold-weight: bold;
625
626      --heading-letterspacing: -0.025em;
627      --heading-capitalize: none;
628      --heading-decoration: none;
629
630      --standard-heading-size: var(--type-scale-n3);
631      --feature-heading-size: var(--type-scale-n4);
632      --secondary-heading-size: var(--type-scale-n2);
633
634      --body-copy-transform: none;
635
636      --wrapperWidth: 100vw;
637      --gutter: 0px;
638      --rowHeight: calc((var(--wrapperWidth) - (11 * var(--gutter))) / 12);
639
640      --global-scrolling-items-speed-multiplier: 1;
641
642      --add-to-cart-button-height: 44px;
643      --checkout-button-height: 44px;
644
645      --spacing: 1rem;
646      --spacing-double: 2rem;
647      --spacing-half: 0.5rem;
648
649      /* Equivalent to px-2 */
650      --section-horizontal-spacing-mobile: 0.5rem;
651      /* Equivalent to px-4 */
652      --section-horizontal-spacing-desktop: 1rem;
653
654      --section-horizontal-spacing: var(--section-horizontal-spacing-mobile);
655
656      --icon-thickness: 1.5;
657
658      /**
659       * Buttons
660       */
661      --button-text-transform: none;
662      --button-after-content: '\00a0\2192';
663      --button-border-radius: 9999px;
664
665      /**
666       * Links
667       */
668      --links-bottom-border-width: var(--text-border-width);
669      --links-bottom-padding: 0.25rem;
670      --links-text-transform: none;
671      --links-after-content: '\00a0\2192';
672      --links-before-content: '\2190\00a0';
673
674      background-color: rgb(var(--color-scheme-background));
675      color: rgb(var(--color-scheme-text));
676    }
677
678    @media (min-width: 1024px) {
679      :root {
680        --standard-heading-size: var(--type-scale-n5);
681        --feature-heading-size: var(--type-scale-n6);
682        --secondary-heading-size: var(--type-scale-n3);
683
684        --section-horizontal-spacing: var(--section-horizontal-spacing-desktop);
685      }
686    }
687
688    :root,
689      
690      [data-color-scheme="scheme1"] {
691        --color-scheme-text: 43 57 144;
692        --color-scheme-background: 255 255 255;
693        --color-scheme-accent: 248 250 244;
694        --color-scheme-accent-contrast:  43 57 144;
695        --color-scheme-secondary: 30 35 38;
696      }
697  
698      [data-color-scheme="scheme2"] {
699        --color-scheme-text: 30 35 38;
700        --color-scheme-background: 241 255 165;
701        --color-scheme-accent: 194 194 194;
702        --color-scheme-accent-contrast:  30 35 38;
703        --color-scheme-secondary: 30 35 38;
704      }
705  
706      [data-color-scheme="scheme3"] {
707        --color-scheme-text: 248 250 244;
708        --color-scheme-background: 43 57 144;
709        --color-scheme-accent: 248 250 244;
710        --color-scheme-accent-contrast:  241 255 165;
711        --color-scheme-secondary: 43 57 144;
712      }
713  
714      [data-color-scheme="scheme4"] {
715        --color-scheme-text: 248 250 244;
716        --color-scheme-background: 30 35 38;
717        --color-scheme-accent: 248 250 244;
718        --color-scheme-accent-contrast:  30 35 38;
719        --color-scheme-secondary: 248 250 244;
720      }
721  
722      [data-color-scheme="scheme5"] {
723        --color-scheme-text: 30 35 38;
724        --color-scheme-background: 255 255 255;
725        --color-scheme-accent: 30 35 38;
726        --color-scheme-accent-contrast:  255 255 255;
727        --color-scheme-secondary: 30 35 38;
728      }
729  
730      [data-color-scheme="scheme-62a93d7b-1ea3-42af-a18d-30461b13240a"] {
731        --color-scheme-text: 255 255 255;
732        --color-scheme-background: 255 255 255;
733        --color-scheme-accent: 255 255 255;
734        --color-scheme-accent-contrast:  255 255 255;
735        --color-scheme-secondary: 255 255 255;
736      }
737  
738      [data-color-scheme="scheme-7c315ead-1873-415d-a1a8-a7722419ef69"] {
739        --color-scheme-text: 43 57 144;
740        --color-scheme-background: 255 255 255;
741        --color-scheme-accent: 30 35 38;
742        --color-scheme-accent-contrast:  30 35 38;
743        --color-scheme-secondary: 30 35 38;
744      }
745  
746      [data-color-scheme="scheme-6641fd8c-0fdd-4ed9-bd94-b490824d6125"] {
747        --color-scheme-text: 30 35 38;
748        --color-scheme-background: 72 127 249;
749        --color-scheme-accent: 248 250 244;
750        --color-scheme-accent-contrast:  30 35 38;
751        --color-scheme-secondary: 30 35 38;
752      }
753  
754
755    [data-color-scheme] {
756      --payment-terms-background-color: rgb(var(--color-scheme-background));
757
758      --button-color-border: var(--color-scheme-text);
759      --button-color-background: var(--color-scheme-accent);
760      --button-color-text: var(--color-scheme-accent-contrast);
761      --button-color-border-hover: var(--color-scheme-text);
762      --button-color-background-hover: var(--color-scheme-text);
763      --button-color-text-hover: var(--color-scheme-background);
764    }
765
766    ::selection {
767      background-color: rgb(var(--color-scheme-accent));
768      color: rgb(var(--color-scheme-accent-contrast));
769    }
770
771    @keyframes scrolling-items {
772      0% {
773        transform: translate3d(0, 0, 0);
774      }
775
776      100% {
777        transform: translate3d(-50%, 0, 0);
778      }
779    }
780</style>
781
782<style id="generated-critical-css">
783image-with-placeholder{display:block}.theme-button,.theme-button--secondary{cursor:pointer;font-size:var(--font-size-base);line-height:var(--base-line-height);overflow-wrap:anywhere;padding:.5rem 2rem;text-transform:var(--button-text-transform);word-break:normal}.theme-button--secondary:after,.theme-button:after{--tw-content:var(--button-after-content);content:var(--tw-content)}.theme-button{--tw-border-opacity:1;--tw-bg-opacity:1;--tw-text-opacity:1;background-color:rgb(var(--button-color-background)/var(--tw-bg-opacity,1));border-color:rgb(var(--button-color-border)/var(--tw-border-opacity,1));border-radius:var(--button-border-radius);border-width:var(--text-border-width);color:rgb(var(--button-color-text)/var(--tw-text-opacity,1))}@media (hover:hover) and (pointer:fine){.theme-button:hover{--tw-border-opacity:1;--tw-bg-opacity:1;--tw-text-opacity:1;background-color:rgb(var(--button-color-background-hover)/var(--tw-bg-opacity,1));border-color:rgb(var(--button-color-border-hover)/var(--tw-border-opacity,1));color:rgb(var(--button-color-text-hover)/var(--tw-text-opacity,1))}}.theme-button--secondary{--tw-border-opacity:1;--tw-bg-opacity:1;--tw-text-opacity:1;background-color:rgb(var(--color-scheme-background)/var(--tw-bg-opacity,1));border-color:rgb(var(--color-scheme-text)/var(--tw-border-opacity,1));border-radius:var(--button-border-radius);border-width:var(--text-border-width);color:rgb(var(--color-scheme-text)/var(--tw-text-opacity,1))}[data-color-scheme] .theme-button--secondary.rte a:hover,[data-color-scheme].theme-button--secondary .rte a:hover,[data-color-scheme].theme-button--secondary.rte a:hover{color:rgb(var(--color-scheme-accent));text-decoration-color:rgb(var(--color-scheme-accent))}[data-color-scheme] .theme-button--secondary.rte blockquote,[data-color-scheme].theme-button--secondary .rte blockquote,[data-color-scheme].theme-button--secondary.rte blockquote{background:rgb(var(--color-scheme-text));color:rgb(var(--color-scheme-background))}@media (hover:hover) and (pointer:fine){.theme-button--secondary:hover{--tw-border-opacity:1;--tw-text-opacity:1;border-color:rgb(var(--color-scheme-accent)/var(--tw-border-opacity,1));color:rgb(var(--color-scheme-accent)/var(--tw-text-opacity,1))}}[data-shopify-xr-hidden]{display:none}.block{display:block}.inline-block{display:inline-block}.hidden{display:none}.shopify-payment-button__button--hidden{display:none!important}.splide:not(.is-active) .\[\.splide\:not\(\.is-active\)_\&\]\:pointer-events-none{pointer-events:none}.splide:not(.is-active) .\[\.splide\:not\(\.is-active\)_\&\]\:invisible{visibility:hidden}.splide:not(.is-active) .\[\.splide\:not\(\.is-active\)_\&\]\:\!flex{display:flex!important}.splide:not(.is-active) .\[\.splide\:not\(\.is-active\)_\&\]\:gap-gridline{gap:var(--gridline-width)}@media not all and (min-width:1024px){.splide:not(.is-active) .max-lg\:\[\.splide\:not\(\.is-active\)_\&\]\:hidden{display:none}}
784</style>
785<style id="manual-critical-css">
786  html {
787    background-color: rgb(var(--color-primary-background));
788    color: rgb(var(--color-primary-text));
789    font-size: var(--base-font-size);
790    line-height: var(--base-line-height);
791  }
792
793  [x-cloak] {
794    display: none;
795  }
796
797  data-island {
798    display: block;
799  }
800
801  html.no-js [x-cloak].no-js-undo-cloak {
802    display: revert;
803  }
804
805  body {
806    display: flex;
807    flex-direction: column;
808    min-height: 100vh;
809  }
810
811  @media (min-width: 768px) {
812    [md\:undo-x-cloak-block] {
813      display: block;
814    }
815  }
816
817  @media (max-width: 767px) {
818    [max-md\:undo-x-cloak-block] {
819      display: block;
820    }
821  }
822</style>
823
824      <style>
825  :root {
826    /* ── Colors ── */
827    --pr-blue: #2B3990;
828    --pr-blue-hover: #232e75;
829    --pr-bright-blue: #487FF9;       /* matches product-page volume-pricing table */
830    --pr-bright-blue-hover: #3D6CD4;
831    --pr-bright-blue-rgb: 72 127 249;
832    --pr-bright-blue-hover-rgb: 61 108 212;
833    --dusky-purple: #4B4D72;
834    --dusky-purple-hover: #3d3f5e;
835    --slider-green: #658a6a;
836    --off-white: #FBFBF6;
837    --pill-bg: #EEE;
838    --pill-bg-hover: #e2e2e2;
839    --cant-find-bg: #EFFE9C;
840
841    /* ── Typography ── */
842    --font-family: 'DM Sans', sans-serif;
843    --title-modal-size: 2.75rem;       /* 44px */
844    --title-modal-tracking: -0.05em;   /* -2.2px */
845    --title-drawer-size: 41px;
846    --title-drawer-tracking: -2px;
847    --body-size: 0.9375rem;            /* 15px */
848    --label-size: 0.8125rem;           /* 13px */
849    --pill-font-size: 0.66rem;         /* ~10.65px */
850    --cta-font-size: 1.5rem;           /* 24px */
851    --submit-font-size: 1.5rem;        /* 24px */
852    --input-font-size: 0.875rem;       /* 14px */
853
854    /* ── Borders ── */
855    --border-modal: 2px solid black;
856    --border-drawer-left: 2px solid black;
857    --border-pill: 0.666px solid black;
858    --border-input: 1px solid black;
859    --border-cta: 2px solid var(--dusky-purple);
860    --border-chip: 0.4px solid black;
861
862    /* ── Radii ── */
863    --radius-modal: 27px;
864    --radius-pill: 9999px;
865    --radius-input: 9999px;
866    --radius-textarea: 10px;
867    --radius-submit: 50px;
868    --radius-cta: 40px;
869    --radius-chip: 24px;
870    --radius-popover: 16px;
871
872    /* ── Shadows ── */
873    --shadow-modal: 0 4px 13px 2px rgba(0, 0, 0, 0.1);
874    --shadow-popover: 0 10px 25px rgba(0, 0, 0, 0.1);
875    --shadow-slider-thumb: 0 2px 6px rgba(0, 0, 0, 0.15);
876    --shadow-focus: 0 0 0 3px rgba(43, 57, 144, 0.1);
877
878    /* ── Sizing ── */
879    --product-image-drawer: 90px;
880    --product-image-modal: 53px;
881    --pill-height: 23px;
882    --submit-height: 70px;
883    --submit-max-width: 351px;
884    --start-quote-height: 79px;
885    --input-min-height: 2.75rem;       /* 44px */
886    --slider-thumb-size: 24px;
887    --slider-track-height: 6px;
888    --cta-width: 153px;
889    --cta-height: 47px;
890    --chip-width: 90px;
891    --chip-height: 21px;
892
893    /* ── Aliases (backward compat) ── */
894    --color-quote-accent: var(--pr-blue);
895  }
896</style>
897
898
899    <link rel="preload" href="//printroom.co/cdn/shop/t/59/assets/base.bundle.css?v=77867960145098054751787098434" as="style" onload="this.onload=null;this.rel='stylesheet'">
900    <noscript><link rel="stylesheet" href="//printroom.co/cdn/shop/t/59/assets/base.bundle.css?v=77867960145098054751787098434"></noscript>
901
902    <link rel="preload" href="//printroom.co/cdn/shop/t/59/assets/styles.css?v=1691680456440492591789529106" as="style" onload="this.onload=null;this.rel='stylesheet'">
903    <noscript><link rel="stylesheet" href="//printroom.co/cdn/shop/t/59/assets/styles.css?v=1691680456440492591789529106"></noscript>
904
905<meta property="og:site_name" content="The Print Room">
906<meta property="og:locale" content="en"><meta property="og:locale:alternate" content="en_NZ"><meta property="og:url" content="https://printroom.co/cart"><meta property="og:title" content="
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921Your Shopping Cart
922 
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937| The Print Room
938">
939<meta property="og:type" content="website">
940<meta property="og:description" content="NZ’s experts in custom t-shirt printing, tote bags, uniforms, and branded merchandise. Print Room offers high-quality screen printing and embroidery using eco-friendly inks. Fast turnaround, sustainable production, and trusted by leading New Zealand brands.">
941<meta property="og:image" content="https://printroom.co/cdn/shop/files/PrintRoomNovember2024-13_507c1311-d6fa-40ae-ae11-a74b59c4faec.jpg?v=1753319129">
942<meta
943    property="og:image:secure_url"
944    content="https://printroom.co/cdn/shop/files/PrintRoomNovember2024-13_507c1311-d6fa-40ae-ae11-a74b59c4faec.jpg?v=1753319129"
945  >
946  <meta property="og:image:width" content="2048">
947  <meta property="og:image:height" content="1367"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962Your Shopping Cart
963 
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978| The Print Room
979">
980<meta name="twitter:description" content="NZ’s experts in custom t-shirt printing, tote bags, uniforms, and branded merchandise. Print Room offers high-quality screen printing and embroidery using eco-friendly inks. Fast turnaround, sustainable production, and trusted by leading New Zealand brands.">
981<script>
982  window.THEMENAME = 'Baseline';
983  window.THEMEVERSION = '3.0.0';
984
985  document.documentElement.className = document.documentElement.className.replace('no-js', 'js');
986
987  function debounce(fn, wait) {
988    let t;
989    return (...args) => {
990      clearTimeout(t);
991      t = setTimeout(() => fn.apply(this, args), wait);
992    };
993  }
994
995  window.theme = {
996    strings: {
997      loading: "Loading",
998      itemCountOne: "{{ count }} item",
999      itemCountOther: "{{ count }} items",
1000      addToCart: "Add to cart",
1001      soldOut: "Sold out",
1002      unavailable: "Unavailable",
1003      regularPrice: "Regular price",
1004      salePrice: "Sale price",
1005      sale: "Sale",
1006      unitPrice: "Unit price",
1007      unitPriceSeparator: "per",
1008      cartEmpty: "Your cart is currently empty.",
1009      cartCookies: "Enable cookies to use the shopping cart",
1010      update: "Update",
1011      quantity: "Quantity",
1012      discountedTotal: "Discounted total",
1013      regularTotal: "Regular total",
1014      priceColumn: "See Price column for discount details.",
1015      addedToCart: "Added to Cart!",
1016      cartError: "There was an error while updating your cart. Please try again.",
1017      cartAddError: "All {{ title }} are in your cart.",
1018      shippingCalculatorResultsTitleOne: "There is 1 rate:",
1019      shippingCalculatorResultsTitleMany: "There are {{ count }} rates:",
1020    },
1021    routes: {
1022      root_url: "\/",
1023      predictive_search_url: "\/search\/suggest",
1024      cart_url: "\/cart",
1025      cart_add_url: "\/cart\/add",
1026      cart_change_url: "\/cart\/change",
1027      cart_update_url: "\/cart\/update",
1028      cart_clear_url: "\/cart\/clear",
1029    },
1030    moneyFormat: "${{amount}}",
1031    moneyWithCurrencyFormat: "${{amount}} USD",
1032    get defaultMoneyFormat() {
1033      return this.moneyFormat;
1034    },
1035    cartItemCount: 0,
1036    settings: {
1037      cartType: "page",
1038      openDrawerOnAddToCart: false
1039    },
1040    info: {
1041      name: 'Baseline',
1042    }
1043  };
1044</script>
vendor: 1 bytes, line 1044
1044
1045<script src="//printroom.co/cdn/shop/t/59/assets/utils.js?v=84782252304122448471787098437" defer></script>
1045
1046    
1046<script src="//printroom.co/cdn/shop/t/59/assets/images.js?v=56710371490645595961787098434" defer></script>
1046
1047    
1047<script>
1048      window.themeEventsDebugMode = false;
1049    </script>
1049
1050    
1050<script src="//printroom.co/cdn/shop/t/59/assets/theme-events.js?v=133344252210966700221787098437" defer></script>
1050
1051
1052    
1053
1054    
1055  
1056  <!-- "snippets/shogun-head.liquid" was not rendered, the associated app was uninstalled -->
1057  
1057<script type="text/javascript">
1058window.PunchoutSettings = {
1059            "cloud_url": "https://cloud.punchoutexpress.com",
1060            "token": "ba56ba1530c75285dc7e1f854b4ad1a1",
1061            "checkout_selector": "#main-cart-footer div.items-center",
1062            "checkout_text": "Transfer Cart",
1063            "cancel_selector": "#main-cart-footer div.items-center",
1064            "cancel_text": "Cancel",
1065            "hide_selector": "*[name=\"checkout\"],.shopify-payment-button,.additional-checkout-buttons,.additional-checkout-button, #main-cart-footer button.theme-button--secondary, #main-cart-footer button.text-button",
1066            "cart_container_selector": "#CartContainer,#CartDrawer,#ajaxifyModal"
1067        };
1068</script>
1068
1069
1070  <!-- Punchout Cloud -->
1071<script src="https://cdn.cloud.punchoutexpress.com/cloud/assets-shopify/0.2.0/punchout.min.js?v5_24_0" defer="defer"></script>
1071
1072<style type="text/css">.btn-punchout-cancel {margin-left: 10px;}</style>
1073<!-- /Punchout Cloud -->
1074
1075  
1076
1077<script>
1078(function() {
1079  console.log('[TWOA Punchout] Script loaded');
1080  
1081  // Check if we're on the Te Wananga page and Locksmith is present
1082  const isTWOAPage = window.location.pathname.includes('te-wananga-o-aotearoa');
1083  console.log('[TWOA Punchout] Is TWOA page:', isTWOAPage);
1084  console.log('[TWOA Punchout] Current path:', window.location.pathname);
1085  
1086  if (isTWOAPage) {
1087    // Check if punchout session is already active
1088    const urlParams = new URLSearchParams(window.location.search);
1089    const hasPunchoutSession = urlParams.has('punchout_sess_id');
1090    console.log('[TWOA Punchout] Has punchout session:', hasPunchoutSession);
1091    
1092    if (!hasPunchoutSession) {
1093      console.log('[TWOA Punchout] No punchout session detected, will auto-activate');
1094      
1095      // Wait for page to fully load, then activate punchout
1096      window.addEventListener('load', function() {
1097        // Check if there's a Locksmith password form visible
1098        const hasPasswordForm = document.querySelector('form[data-locksmith-form], input[type="password"][name*="lock"]');
1099        
1100        console.log('[TWOA Punchout] Page loaded - Has password form:', !!hasPasswordForm);
1101        
1102        if (!hasPasswordForm) {
1103          // No password form = user has access, activate punchout immediately
1104          console.log('[TWOA Punchout] ✓ Access granted - activating punchout session');
1105          const punchoutId = Date.now().toString() + Math.random().toString(36).substring(2, 15);
1106          const newUrl = new URL(window.location.href);
1107          newUrl.searchParams.set('punchout_sess_id', punchoutId);
1108          
1109          // Store in sessionStorage to persist across page navigation
1110          sessionStorage.setItem('twoa_punchout_active', 'true');
1111          sessionStorage.setItem('twoa_punchout_id', punchoutId);
1112          console.log('[TWOA Punchout] Session ID:', punchoutId);
1113          
1114          // Redirect with punchout parameter
1115          console.log('[TWOA Punchout] Redirecting to:', newUrl.toString());
1116          window.location.href = newUrl.toString();
1117        } else {
1118          console.log('[TWOA Punchout] Password form detected, waiting for login...');
1119          
1120          // Watch for form submission / successful login
1121          const checkForAccess = setInterval(function() {
1122            const formStillVisible = document.querySelector('form[data-locksmith-form], input[type="password"][name*="lock"]');
1123            
1124            if (!formStillVisible) {
1125              console.log('[TWOA Punchout] ✓ Password form disappeared - activating punchout');
1126              clearInterval(checkForAccess);
1127              
1128              const punchoutId = Date.now().toString() + Math.random().toString(36).substring(2, 15);
1129              sessionStorage.setItem('twoa_punchout_active', 'true');
1130              sessionStorage.setItem('twoa_punchout_id', punchoutId);
1131              
1132              const newUrl = new URL(window.location.href);
1133              newUrl.searchParams.set('punchout_sess_id', punchoutId);
1134              window.location.href = newUrl.toString();
1135            }
1136          }, 500);
1137          
1138          // Stop after 30 seconds
1139          setTimeout(() => clearInterval(checkForAccess), 30000);
1140        }
1141      });
1142    } else {
1143      // If punchout is already active, store it in session
1144      console.log('[TWOA Punchout] Punchout already active, storing in session');
1145      sessionStorage.setItem('twoa_punchout_active', 'true');
1146      sessionStorage.setItem('twoa_punchout_id', urlParams.get('punchout_sess_id'));
1147    }
1148  }
1149  
1150  // Apply punchout session to all pages if Te Wananga session is active
1151  const storedPunchoutActive = sessionStorage.getItem('twoa_punchout_active');
1152  const storedPunchoutId = sessionStorage.getItem('twoa_punchout_id');
1153  console.log('[TWOA Punchout] Session storage - Active:', storedPunchoutActive, 'ID:', storedPunchoutId);
1154  
1155  if (storedPunchoutActive === 'true' && storedPunchoutId) {
1156    const urlParams = new URLSearchParams(window.location.search);
1157    if (!urlParams.has('punchout_sess_id')) {
1158      console.log('[TWOA Punchout] Applying stored punchout session to current page');
1159      const newUrl = new URL(window.location.href);
1160      newUrl.searchParams.set('punchout_sess_id', storedPunchoutId);
1161      window.history.replaceState({}, '', newUrl.toString());
1162      console.log('[TWOA Punchout] URL updated:', newUrl.toString());
1163      
1164      // Reinitialize punchout if the script is loaded
1165      if (window.PunchoutCloud && window.PunchoutCloud.init) {
1166        console.log('[TWOA Punchout] Reinitializing PunchoutCloud');
1167        window.PunchoutCloud.init();
1168      }
1169    }
1170  }
1171})();
1172</script>
1172
1173
1174<!-- BEGIN app block: shopify://apps/one-tree-planted/blocks/index/1cbac389-d687-4afb-9e8a-26b6535fa1c2 -->
1174<script src="https://cdn.shopify.com/extensions/01a0f89b-d3f4-7fbc-a0d8-5474ae165888/reforestation-app-16/assets/script.js" defer></script>
1174
1175<!-- END app block -->
1175<script src="https://cdn.shopify.com/extensions/019d45d2-6a70-7eed-8da1-d1e8fd0fae86/fulfillment-fee-app-100/assets/fulfillment-fee-manager.js" type="text/javascript" defer="defer"></script>
1175
1176<link href="https://monorail-edge.shopifysvc.com" rel="dns-prefetch">
1177<script>(function(){if ("sendBeacon" in navigator && "performance" in window) {try {var session_token_from_headers = performance.getEntriesByType('navigation')[0].serverTiming.find(x => x.name == '_s').description;} catch {var session_token_from_headers = undefined;}var session_cookie_matches = document.cookie.match(/_shopify_s=([^;]*)/);var session_token_from_cookie = session_cookie_matches && session_cookie_matches.length === 2 ? session_cookie_matches[1] : "";var session_token = session_token_from_headers || session_token_from_cookie || "";function handle_abandonment_event(e) {var entries = performance.getEntries().filter(function(entry) {return /monorail-edge.shopifysvc.com/.test(entry.name);});if (!window.abandonment_tracked && entries.length === 0) {window.abandonment_tracked = true;var currentMs = Date.now();var navigation_start = performance.timing.navigationStart;var payload = {shop_id: 7054289,url: window.location.href,navigation_start,duration: currentMs - navigation_start,session_token,page_type: "cart"};window.navigator.sendBeacon("https://monorail-edge.shopifysvc.com/v1/produce", JSON.stringify({schema_id: "online_store_buyer_site_abandonment/1.1",payload: payload,metadata: {event_created_at_ms: currentMs,event_sent_at_ms: currentMs}}));}}window.addEventListener('pagehide', handle_abandonment_event);}}());</script>
vendor: 1 bytes, line 1177
1177
1178<script>
1179  window.__TREKKIE_SHIM_QUEUE = window.__TREKKIE_SHIM_QUEUE || [];
1180</script>
vendor: 1 bytes, line 1180
1180
1181<script>(function(){var wpmLoader=function(){"use strict";var e=/Googlebot|Storebot-Google|bingbot|Baiduspider|YandexBot|DuckDuckBot|Slurp|facebookexternalhit|Twitterbot|LinkedInBot|Applebot|AdsBot-Google|Mediapartners-Google|APIs-Google|PetalBot|SemrushBot|AhrefsBot|MJ12bot|DotBot|Acunetix|PerplexityBot|Perplexity-User/i,t=/bytedance/i;function i(){try{var e=document.cookie;if(!e||"string"!=typeof e)return;for(var t=0,i=e.split(";");t<i.length;t++){var n=i[t],r=n.indexOf("=");if(-1!==r){var o=n.slice(0,r).trim();if(o){var a=void 0;try{a=decodeURIComponent(o)}catch(e){a=o}if("_shopify_s"===a){var d=n.slice(r+1).trim();try{return decodeURIComponent(d)}catch(e){return d}}}}}return}catch(e){return}}function n(e){try{"undefined"!=typeof console&&"function"==typeof console.warn&&console.warn(e)}catch(e){}}function r(e,t){return"string"==typeof e&&e.length>0&&e.length<=t?e:void 0}function o(e){var t;switch(null==(t=null==e?void 0:e.navigation)?void 0:t.type){case 0:return"navigate";case 1:return"reload";case 2:return"back_forward";default:return}}function a(){var e,t,i;try{var n=null==(i=null==(t=null==(e=self.ShopifyAnalytics)?void 0:e.lib)?void 0:t.trekkie)?void 0:i.state;return"awaiting-consent"===n||"initialized"===n?n:void 0}catch(e){return}}return function(d,s,u,l){var c=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{};try{var p=c.trekkieShim;!0!==p&&"true"!==p||null!=window.__TREKKIE_SHIM_QUEUE||(window.__TREKKIE_SHIM_QUEUE=[])}catch(e){}var f,v,h,y,g=(v=(f={modern:/Edge?\/(1{2}[4-9]|1[2-9]\d|[2-9]\d{2}|\d{4,})\.\d+(\.\d+|)|Firefox\/(1{2}[4-9]|1[2-9]\d|[2-9]\d{2}|\d{4,})\.\d+(\.\d+|)|Chrom(ium|e)\/(9{2}|\d{3,})\.\d+(\.\d+|)|(Maci|X1{2}).+ Version\/(15\.\d+|(1[6-9]|[2-9]\d|\d{3,})\.\d+)([,.]\d+|)( \(\w+\)|)( Mobile\/\w+|) Safari\/|Chrome.+OPR\/(9{2}|\d{3,})\.\d+\.\d+|(CPU[ +]OS|iPhone[ +]OS|CPU[ +]iPhone|CPU IPhone OS|CPU iPad OS)[ +]+(15[._]\d+|(1[6-9]|[2-9]\d|\d{3,})[._]\d+)([._]\d+|)|Android:?[ /-](14[89]|1[5-9]\d|[2-9]\d{2}|\d{4,})(\.\d+|)(\.\d+|)|Android.+Firefox\/(15\d|1[6-9]\d|[2-9]\d{2}|\d{4,})\.\d+(\.\d+|)|Android.+Chrom(ium|e)\/(14[89]|1[5-9]\d|[2-9]\d{2}|\d{4,})\.\d+(\.\d+|)|SamsungBrowser\/([2-9]\d|\d{3,})\.\d+/,legacy:/Edge?\/(1[6-9]|[2-9]\d|\d{3,})\.\d+(\.\d+|)|Firefox\/(5[4-9]|[6-9]\d|\d{3,})\.\d+(\.\d+|)|Chrom(ium|e)\/(5[1-9]|[6-9]\d|\d{3,})\.\d+(\.\d+|)([\d.]+$|.*Safari\/(?![\d.]+ Edge\/[\d.]+$))|(Maci|X1{2}).+ Version\/(10\.\d+|(1[1-9]|[2-9]\d|\d{3,})\.\d+)([,.]\d+|)( \(\w+\)|)( Mobile\/\w+|) Safari\/|Chrome.+OPR\/(3[89]|[4-9]\d|\d{3,})\.\d+\.\d+|(CPU[ +]OS|iPhone[ +]OS|CPU[ +]iPhone|CPU IPhone OS|CPU iPad OS)[ +]+(10[._]\d+|(1[1-9]|[2-9]\d|\d{3,})[._]\d+)([._]\d+|)|Android:?[ /-](14[89]|1[5-9]\d|[2-9]\d{2}|\d{4,})(\.\d+|)(\.\d+|)|Mobile Safari.+OPR\/([89]\d|\d{3,})\.\d+\.\d+|Android.+Firefox\/(15\d|1[6-9]\d|[2-9]\d{2}|\d{4,})\.\d+(\.\d+|)|Android.+Chrom(ium|e)\/(14[89]|1[5-9]\d|[2-9]\d{2}|\d{4,})\.\d+(\.\d+|)|Android.+(UC? ?Browser|UCWEB|U3)[ /]?(15\.([5-9]|\d{2,})|(1[6-9]|[2-9]\d|\d{3,})\.\d+)\.\d+|SamsungBrowser\/(5\.\d+|([6-9]|\d{2,})\.\d+)|Android.+MQ{2}Browser\/(14(\.(9|\d{2,})|)|(1[5-9]|[2-9]\d|\d{3,})(\.\d+|))(\.\d+|)|K[Aa][Ii]OS\/(3\.\d+|([4-9]|\d{2,})\.\d+)(\.\d+|)/}).modern,h=f.legacy,(y=navigator.userAgent).match(e)?"bot":y.match(v)?"modern":y.match(h)?"legacy":y.match(t)?"bot":"unknown"),m=function(e){var t,i,n=r(e,128);try{var a=window.performance,d=null==(t=null==a?void 0:a.getEntriesByType)?void 0:t.call(a,"navigation")[0];if(!d)return{requestId:n,navigationType:o(a)};var s="type"in d?r(d.type,64):void 0,u="serverTiming"in d&&Array.isArray(d.serverTiming)?d.serverTiming:[];return{requestId:null!=n?n:r(null==(i=u.find(function(e){return"requestID"===e.name}))?void 0:i.description,128),navigationType:s}}catch(e){return{requestId:n}}}(c.requestId),w=function(e){var t=e.version,r=e.browserTarget,o=e.surface,a=e.shopId,d=e.monorailEndpoint,s=window.location.href;return{emit:function(e){var u=e.status,l=e.errorMsg,c=e.failureReason,p=e.useKeepaliveFallback,f=void 0!==p&&p,v=e.navigationType,h=e.pagehidePersisted,y=e.requestId,g=e.trekkieState;if(d){var m,w;try{var b=(new Date).getTime();m=JSON.stringify({metadata:{event_sent_at_ms:b},events:[{schema_id:"web_pixels_manager_load/3.3",payload:{version:t,bundle_target:r,page_url:s,status:u,surface:o,error_msg:l,failure_reason:c,navigation_type:v,pagehide_persisted:h,request_id:y,trekkie_state:g,shop_id:a,visit_token:i()},metadata:{event_created_at_ms:b}}]})}catch(e){return}try{if("function"==typeof window.navigator.sendBeacon&&-1===(w=window.navigator.userAgent).indexOf("iPhone; CPU iPhone OS 12_")&&-1===w.indexOf("iPad; CPU OS 12_")&&-1===w.indexOf("iPod touch; CPU iPhone OS 12_")&&window.navigator.sendBeacon.bind(window.navigator)(d,m))return}catch(e){}if(f)try{"function"==typeof window.fetch&&window.fetch(d,{method:"POST",headers:{"Content-Type":"text/plain"},body:m,keepalive:!0}
1181).catch(function(){})}catch(e){}else try{var _=new XMLHttpRequest;_.open("POST",d,!0),_.setRequestHeader("Content-Type","text/plain"),_.send(m)}catch(e){n("[Web Pixels Manager] Got an unhandled error while logging to Monorail.")}}else n("[Web Pixels Manager] No Monorail endpoint provided, skipping logging.")}}}({version:u,browserTarget:g,surface:d.surface,shopId:d.shopId,monorailEndpoint:d.monorailEndpoint});if(Boolean(null==(_=null==(b=window.Shopify)?void 0:b.analytics)?void 0:_.replayQueue))w.emit({status:"setup-skipped",errorMsg:"replay queue already initialized."});else{var b,_;w.emit({status:"setup-started"}),window.Shopify=window.Shopify||{};var S=window.Shopify;S.analytics=S.analytics||{};var P=S.analytics;P.replayQueue=[],P.publish=function(e,t,i){return P.replayQueue.push([e,t,i]),!0};try{self.performance.mark("wpm:start")}catch(e){}var k,C="modern"===g?"modern":"legacy",E=(null!=l?l:{modern:"",legacy:""})[C],I=[(k={baseUrl:s,hashVersion:u,buildTarget:C}).baseUrl,"/wpm","/b",k.hashVersion,"modern"===k.buildTarget?"m":"l",".js"].join(""),O=!1,T=!1;try{c.browserTarget=g,function(){O=!0;try{window.addEventListener("pagehide",M)}catch(e){O=!1}}(),R(function(){try{R(x)}catch(e){D(e)}}),w.emit({status:"loading",requestId:m.requestId,navigationType:m.navigationType,trekkieState:a()})}catch(e){D(e)}}function U(){var e;if(q(),!function(){var e,t;return Boolean(null==(t=null==(e=window.Shopify)?void 0:e.analytics)?void 0:t.initialized)}()){var t,i,n;try{if("function"!=typeof(null==(e=window.webPixelsManager)?void 0:e.init))return void A();if(!(null!==(n=i=t=window.webPixelsManager.init(d))&&"function"!=typeof n&&Object(n)===n&&"publish"in i&&"function"==typeof i.publish&&"publishCustomEvent"in i&&"function"==typeof i.publishCustomEvent&&"visitor"in i&&"function"==typeof i.visitor))return void A()}catch(e){return void A(e)}var r=window.Shopify.analytics;r.replayQueue.forEach(function(e){var i=e[0],n=e[1],r=e[2];t.publishCustomEvent(i,n,r)}),r.replayQueue=[],r.publish=t.publishCustomEvent,r.visitor=t.visitor,r.initialized=!0}}function A(e){B("manager_api_unavailable",void 0===e?void 0:Q(e))}function x(){B("script_load_failed","".concat(I," has failed to load"))}function B(e,t){T||(T=!0,q(),w.emit({status:"failed",errorMsg:t,failureReason:e,requestId:m.requestId,navigationType:m.navigationType,trekkieState:a()}))}function M(e){O&&(q(),w.emit({status:"pagehide-while-loading",useKeepaliveFallback:!0,pagehidePersisted:e.persisted,requestId:m.requestId,navigationType:m.navigationType,trekkieState:a()}))}function q(){O=!1;try{window.removeEventListener("pagehide",M)}catch(e){}}function R(e){var t;!function(e){var t=e.src,i=e.async,n=void 0===i||i,r=e.onload,o=e.onerror,a=e.sri,d=e.scriptDataAttributes,s=void 0===d?{}:d,u=document.createElement("script"),l=document.querySelector("head"),c=document.querySelector("body");if(u.async=n,u.src=t,a&&(u.integrity=a,u.crossOrigin="anonymous"),s)for(var p in s)if(Object.prototype.hasOwnProperty.call(s,p))try{u.dataset[p]=String(s[p])}catch(e){}if(r&&u.addEventListener("load",r),o&&u.addEventListener("error",o),l)l.appendChild(u);else{if(!c)throw new Error("Did not find a head or body element to append the script");c.appendChild(u)}}({src:I,async:!0,onload:U,onerror:e,sri:(t=E,"string"==typeof t&&/^sha384-[A-Za-z0-9+/=]+$/.test(t)?E:""),scriptDataAttributes:c})}function D(e){B("script_append_failed",Q(e))}function Q(e){return e instanceof Error?e.message:"Unknown error"}}}();wpmLoader({shopId: 7054289,storefrontBaseUrl: "https://printroom.co",extensionsBaseUrl: "https://extensions.shopifycdn.com/cdn/shopifycloud/web-pixels-manager",monorailEndpoint: "https://printroom.co/.well-known/shopify/monorail/unstable/produce_batch",surface: "storefront-renderer",enabledBetaFlags: ["4c64608a","16072cab","8450a54b","7ee89bf1"],webPixelsConfigList: [{"id":"2246574150","configuration":"{\"accountID\":\"SWPcHh\",\"webPixelConfig\":\"eyJlbmFibGVBZGRlZFRvQ2FydEV2ZW50cyI6IHRydWV9\"}","eventPayloadVersion":"v1","runtimeContext":"STRICT","scriptVersion":"c63c5b72c8d77be5f2d27d14c081da38","type":"APP","apiClientId":123074,"privacyPurposes":["ANALYTICS","MARKETING"],"dataSharingAdjustments":{"protectedCustomerApprovalScopes":["read_customer_address","read_customer_email","read_customer_name","read_customer_personal_data","read_customer_phone"],"dataSharingControls":[]},"dataSharingState":"optimized","enabledFlags":["9a3ed68a"]},{"id":"2207776838","configuration":"{\"tagID\":\"2612346888626\"}","eventPayloadVersion":"v1","runtimeContext":"STRICT","scriptVersion":"7ae565e198624b39e0856d352b9a6b4c","type":"APP","apiClientId":3009811,"privacyPurposes":["ANALYTICS","MARKETING","SALE_OF_DATA"],"dataSharingAdjustments":{"protectedCustomerApprovalScopes":["read_customer_address","read_customer_email","read_customer_name","read_customer_personal_data","read_customer_phone"],"dataSharingControls":["share_all_events"]},"dataSharingState":"optimized"}
1181,{"id":"1975877702","configuration":"{\"mailchimp_store_id\":\"store_sgk5l8njdgd17w61safe\", \"mailchimp_user_id\":\"33995925\",\"mailchimp_list_id\":\"ef9b0a5c04\"}","eventPayloadVersion":"v1","runtimeContext":"STRICT","scriptVersion":"e357a49eadeb6216a959d63fa3fb8f55","type":"APP","apiClientId":2585307,"privacyPurposes":["ANALYTICS","MARKETING","SALE_OF_DATA"],"dataSharingAdjustments":{"protectedCustomerApprovalScopes":["read_customer_address","read_customer_email","read_customer_name","read_customer_personal_data","read_customer_phone"],"dataSharingControls":["share_all_events"]},"dataSharingState":"optimized","enabledFlags":["9a3ed68a"]},{"id":"462651462","configuration":"{\"config\":\"{\\\"google_tag_ids\\\":[\\\"G-7N7TTE08E9\\\",\\\"GT-KD7KB7H4\\\"],\\\"target_country\\\":\\\"ZZ\\\",\\\"gtag_events\\\":[{\\\"type\\\":\\\"search\\\",\\\"action_label\\\":\\\"G-7N7TTE08E9\\\"},{\\\"type\\\":\\\"begin_checkout\\\",\\\"action_label\\\":\\\"G-7N7TTE08E9\\\"},{\\\"type\\\":\\\"remove_from_cart\\\",\\\"action_label\\\":\\\"G-7N7TTE08E9\\\"},{\\\"type\\\":\\\"view_item\\\",\\\"action_label\\\":[\\\"G-7N7TTE08E9\\\",\\\"MC-1HQ5JHVSZ0\\\"]},{\\\"type\\\":\\\"purchase\\\",\\\"action_label\\\":[\\\"G-7N7TTE08E9\\\",\\\"MC-1HQ5JHVSZ0\\\"]},{\\\"type\\\":\\\"add_shipping_info\\\",\\\"action_label\\\":\\\"G-7N7TTE08E9\\\"},{\\\"type\\\":\\\"page_view\\\",\\\"action_label\\\":[\\\"G-7N7TTE08E9\\\",\\\"MC-1HQ5JHVSZ0\\\"]},{\\\"type\\\":\\\"view_item_list\\\",\\\"action_label\\\":\\\"G-7N7TTE08E9\\\"},{\\\"type\\\":\\\"add_payment_info\\\",\\\"action_label\\\":\\\"G-7N7TTE08E9\\\"},{\\\"type\\\":\\\"add_to_cart\\\",\\\"action_label\\\":\\\"G-7N7TTE08E9\\\"},{\\\"type\\\":\\\"view_cart\\\",\\\"action_label\\\":\\\"G-7N7TTE08E9\\\"}],\\\"enable_monitoring_mode\\\":false}\"}","eventPayloadVersion":"v1","runtimeContext":"OPEN","scriptVersion":"a3321ca85cf5aaf6b57585fcd8d67b3a","type":"APP","apiClientId":1780363,"privacyPurposes":[],"dataSharingAdjustments":{"protectedCustomerApprovalScopes":["read_customer_address","read_customer_email","read_customer_name","read_customer_personal_data","read_customer_phone"],"dataSharingControls":["share_all_events"]},"dataSharingState":"optimized","enabledFlags":["9a3ed68a"]},{"id":"171573318","configuration":"{\"pixel_id\":\"1516354578649796\",\"pixel_type\":\"facebook_pixel\",\"metaapp_system_user_token\":\"-\"}","eventPayloadVersion":"v1","runtimeContext":"OPEN","scriptVersion":"96420dbe9ea96c426a1b7f364f977719","type":"APP","apiClientId":2329312,"privacyPurposes":["ANALYTICS","MARKETING","SALE_OF_DATA"],"dataSharingAdjustments":{"protectedCustomerApprovalScopes":["read_customer_address","read_customer_email","read_customer_name","read_customer_personal_data","read_customer_phone"],"dataSharingControls":["share_all_events"]},"dataSharingState":"optimized","enabledFlags":["9a3ed68a"]},{"id":"shopify-app-pixel","configuration":"{}","eventPayloadVersion":"v1","runtimeContext":"STRICT","scriptVersion":"0530","apiClientId":"shopify-pixel","type":"APP","privacyPurposes":["ANALYTICS","MARKETING"]},{"id":"shopify-custom-pixel","eventPayloadVersion":"v1","runtimeContext":"LAX","scriptVersion":"0530","apiClientId":"shopify-pixel","type":"CUSTOM","privacyPurposes":["ANALYTICS","MARKETING"]}],isMerchantRequest: false,initData: {"shop":{"name":"The Print Room","paymentSettings":{"currencyCode":"NZD"},"myshopifyDomain":"the-print-room.myshopify.com","countryCode":"NZ","storefrontUrl":"https:\/\/printroom.co"},"customer":null,"cart":null,"checkout":null,"productVariants":[],"products":[],"purchasingCompany":null},},"https://printroom.co/cdn","5982071ew7ea472e3p69b68784m2150dfea",{"modern":"","legacy":""},{"trekkieShim":true,"agentContext":true,"apiClientId":"580111","facebookCapiEnabled":"false","themeId":"151830298694","themePublished":"true","eventMetadataId":"88381ba8-5b9d-4643-8282-ab6f2c15516c","pageType":"cart","shopId":"7054289","storefrontBaseUrl":"https:\/\/printroom.co","extensionBaseUrl":"https:\/\/extensions.shopifycdn.com\/cdn\/shopifycloud\/web-pixels-manager","surface":"storefront-renderer","enabledBetaFlags":"[\"4c64608a\", \"16072cab\", \"8450a54b\", \"7ee89bf1\"]","isMerchantRequest":"false","hashVersion":"5982071ew7ea472e3p69b68784m2150dfea","publish":"custom","events":"[[\"page_viewed\",{}]]"});})();</script>
1181<script>
1182  window.ShopifyAnalytics = window.ShopifyAnalytics || {};
1183  window.ShopifyAnalytics.meta = window.ShopifyAnalytics.meta || {};
1184  window.ShopifyAnalytics.meta.currency = 'USD';
1185  var meta = {"page":{"pageType":"cart","requestId":"75a7c00c-de80-4178-96de-a80299f317cf-1791103105"}};
1186  for (var attr in meta) {
1187    window.ShopifyAnalytics.meta[attr] = meta[attr];
1188  }
1189</script>
vendor: 1 bytes, line 1189
1189
1190<script class="analytics">
1191  (function () {
1192    var customDocumentWrite = function(content) {
1193      var jquery = null;
1194
1195      if (window.jQuery) {
1196        jquery = window.jQuery;
1197      } else if (window.Checkout && window.Checkout.$) {
1198        jquery = window.Checkout.$;
1199      }
1200
1201      if (jquery) {
1202        jquery('body').append(content);
1203      }
1204    };
1205
1206    var hasLoggedConversion = function(token) {
1207      if (token) {
1208        return document.cookie.indexOf('loggedConversion=' + token) !== -1;
1209      }
1210      return false;
1211    }
1212
1213    var setCookieIfConversion = function(token) {
1214      if (token) {
1215        var twoMonthsFromNow = new Date(Date.now());
1216        twoMonthsFromNow.setMonth(twoMonthsFromNow.getMonth() + 2);
1217
1218        document.cookie = 'loggedConversion=' + token + '; expires=' + twoMonthsFromNow;
1219      }
1220    }
1221
1222    var trekkie = window.ShopifyAnalytics.lib = window.trekkie = window.trekkie || [];
1223    window.ShopifyAnalytics.lib.trekkie = window.trekkie;
1224    if (trekkie.integrations) {
1225      return;
1226    }
1227    trekkie.methods = [
1228      'identify',
1229      'page',
1230      'ready',
1231      'track',
1232      'trackForm',
1233      'trackLink'
1234    ];
1235    trekkie.factory = function(method) {
1236      return function() {
1237        var args = Array.prototype.slice.call(arguments);
1238        args.unshift(method);
1239        trekkie.push(args);
1240        if (method == 'track' || method == 'page') {
1241          var pageUrl;
1242          try {
1243            pageUrl = window.location.href;
1244          } catch (e) {}
1245          var pageReferrer;
1246          try {
1247            pageReferrer = document.referrer;
1248          } catch (e) {}
1249          try {
1250            if (window.__TREKKIE_SHIM_QUEUE == null) {
1251              window.__TREKKIE_SHIM_QUEUE = [];
1252            }
1253            window.__TREKKIE_SHIM_QUEUE.push({
1254              from: 'trekkie-stub',
1255              method: method,
1256              args: args.slice(1),
1257              pageContext: {
1258                url: pageUrl,
1259                referrer: pageReferrer
1260              }
1261            });
1262          } catch (e) {
1263            // no-op
1264          }
1265        }
1266        return trekkie;
1267      };
1268    };
1269    for (var i = 0; i < trekkie.methods.length; i++) {
1270      var key = trekkie.methods[i];
1271      trekkie[key] = trekkie.factory(key);
1272    }
1273    trekkie.load = function(config) {
1274      trekkie.config = config || {};
1275      trekkie.config.initialDocumentCookie = document.cookie;
1276      var first = document.getElementsByTagName('script')[0];
1277var script = document.createElement('script');
1278script.type = 'text/javascript';
1279script.onerror = function(e) {
1280  var scriptFallback = document.createElement('script');
1281  scriptFallback.type = 'text/javascript';
1282  scriptFallback.onerror = function(error) {
1283          var Monorail = {
1284      produce: function produce(monorailDomain, schemaId, payload) {
1285        var currentMs = new Date().getTime();
1286        var event = {
1287          schema_id: schemaId,
1288          payload: payload,
1289          metadata: {
1290            event_created_at_ms: currentMs,
1291            event_sent_at_ms: currentMs
1292          }
1293        };
1294        return Monorail.sendRequest("https://" + monorailDomain + "/v1/produce", JSON.stringify(event));
1295      },
1296      sendRequest: function sendRequest(endpointUrl, payload) {
1297        // Try the sendBeacon API
1298        if (window && window.navigator && typeof window.navigator.sendBeacon === 'function' && typeof window.Blob === 'function' && !Monorail.isIos12()) {
1299          var blobData = new window.Blob([payload], {
1300            type: 'text/plain'
1301          });
1302
1303          if (window.navigator.sendBeacon(endpointUrl, blobData)) {
1304            return true;
1305          } // sendBeacon was not successful
1306
1307        } // XHR beacon
1308
1309        var xhr = new XMLHttpRequest();
1310
1311        try {
1312          xhr.open('POST', endpointUrl);
1313          xhr.setRequestHeader('Content-Type', 'text/plain');
1314          xhr.send(payload);
1315        } catch (e) {
1316          console.log(e);
1317        }
1318
1319        return false;
1320      },
1321      isIos12: function isIos12() {
1322        return window.navigator.userAgent.lastIndexOf('iPhone; CPU iPhone OS 12_') !== -1 || window.navigator.userAgent.lastIndexOf('iPad; CPU OS 12_') !== -1;
1323      }
1324    };
1325    Monorail.produce('monorail-edge.shopifysvc.com',
1326      'trekkie_storefront_load_errors/1.1',
1327      {shop_id: 7054289,
1328      theme_id: 151830298694,
1329      app_name: "storefront",
1330      context_url: window.location.href,
1331      source_url: "//printroom.co/cdn/s/trekkie.storefront.2f6d7d7ede7d24234881a9cd5f47e679642fa1f6.min.js"});
1332
1333  };
1334  scriptFallback.async = true;
1335  scriptFallback.src = '//printroom.co/cdn/s/trekkie.storefront.2f6d7d7ede7d24234881a9cd5f47e679642fa1f6.min.js';
1336  first.parentNode.insertBefore(scriptFallback, first);
1337};
1338script.async = true;
1339script.src = '//printroom.co/cdn/s/trekkie.storefront.2f6d7d7ede7d24234881a9cd5f47e679642fa1f6.min.js';
1340first.parentNode.insertBefore(script, first);
1341
1342    };
1343    trekkie.load(
1344      {"Trekkie":{"appName":"storefront","development":false,"defaultAttributes":{"shopId":7054289,"isMerchantRequest":null,"themeId":151830298694,"themeCityHash":"18288446332362764096","contentLanguage":"en","currency":"USD","eventMetadataId":"88381ba8-5b9d-4643-8282-ab6f2c15516c"},"isServerSideCookieWritingEnabled":true,"monorailRegion":"shop_domain","enabledBetaFlags":["764d78cb","8450a54b","7ee89bf1","4c64608a"]},"Session Attribution":{},"S2S":{"facebookCapiEnabled":false,"source":"trekkie-storefront-renderer","apiClientId":580111}}
1345    );
1346
1347    var loaded = false;
1348    trekkie.ready(function() {
1349      if (loaded) return;
1350      loaded = true;
1351
1352      window.ShopifyAnalytics.lib = window.trekkie;
1353
1354      var originalDocumentWrite = document.write;
1355      document.write = customDocumentWrite;
1356      try { window.ShopifyAnalytics.merchantGoogleAnalytics.call(this); } catch(error) {};
1357      document.write = originalDocumentWrite;
1358
1359      var match = window.location.pathname.match(/checkouts\/(.+)\/(thank_you|post_purchase)/)
1360      var token = match? match[1]: undefined;
1361      if (!hasLoggedConversion(token)) {
1362        setCookieIfConversion(token);
1363        
1364      }
1365    });
1366
1367    window.ShopifyAnalytics.lib.page(null,{"pageType":"cart","requestId":"75a7c00c-de80-4178-96de-a80299f317cf-1791103105","shopifyEmitted":true});
1368
1369    var eventsListenerScript = document.createElement('script');
1370    eventsListenerScript.async = true;
1371    eventsListenerScript.src = "//printroom.co/cdn/shopifycloud/storefront/assets/shop_events_listener-4e26a9ce.js";
1372    document.getElementsByTagName('head')[0].appendChild(eventsListenerScript);
1373})();</script>
1373
1374  
1374<script>
1375  if (!window.ga || (window.ga && typeof window.ga !== 'function')) {
1376    window.ga = function ga() {
1377      (window.ga.q = window.ga.q || []).push(arguments);
1378      if (window.Shopify && window.Shopify.analytics && typeof window.Shopify.analytics.publish === 'function') {
1379        window.Shopify.analytics.publish("ga_stub_called", {}, {sendTo: "google_osp_migration"});
1380      }
1381      console.error("Shopify's Google Analytics stub called with:", Array.from(arguments), "\nSee https://help.shopify.com/manual/promoting-marketing/pixels/pixel-migration#google for more information.");
1382    };
1383    if (window.Shopify && window.Shopify.analytics && typeof window.Shopify.analytics.publish === 'function') {
1384      window.Shopify.analytics.publish("ga_stub_initialized", {}, {sendTo: "google_osp_migration"});
1385    }
1386  }
1387</script>
vendor: 1 bytes, line 1387
1387
1388<script
1389  defer
1390  src="https://printroom.co/cdn/shopifycloud/perf-kit/shopify-perf-kit-3.9.4.min.js"
1391  data-application="storefront-renderer"
1392  data-shop-id="7054289"
1393  data-render-region="gcp-us-central1"
1394  data-page-type="cart"
1395  data-theme-instance-id="151830298694"
1396  data-theme-name="Baseline"
1397  data-theme-version="3.3.1"
1398  data-monorail-region="shop_domain"
1399  data-resource-timing-sampling-rate="10"
1400  data-shs="true"
1401  data-shs-beacon="true"
1402  data-shs-export-with-fetch="true"
1403  data-shs-logs-sample-rate="1"
1404  data-shs-beacon-endpoint="https://printroom.co/api/collect"
1405></script>
1405
1406<meta name="shopify-y" content="ebfa40dd-f56d-47b8-b5ec-d07565e6bfe5" data-expiration="1822660705000"><meta name="shopify-s" content="da674f67-bf6a-409d-9c80-f5d363ce780b" data-expiration="1791104905000"><meta name="new-cookie-storage-activated" content="t">
1407</head>
1408
1409  <body>
1410<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-W9DFFGB"
1411    height="0" width="0" style="display:none;visibility:hidden" title="gtm"></iframe></noscript>
1412
1413    <a class="skip-link" href="#MainContent">Skip to content</a>
1414    
1415    <!-- BEGIN sections: header-group -->
1416<div id="shopify-section-sections--21296457187398__geo_market_banner" class="shopify-section shopify-section-group-header-group contents">
1417  <style data-shopify>
1418    #shopify-section-sections--21296457187398__geo_market_banner [data-geo-market-banner] {
1419      position: sticky;
1420      top: 0;
1421      left: 0;
1422      right: 0;
1423      z-index: 40;
1424      display: block;
1425      width: 100%;
1426      padding: 0;
1427      border-bottom: 1px solid rgba(248, 250, 244, 0.18);
1428      background: #2b3990;
1429      color: #f8faf4;
1430      box-shadow: 0 14px 30px rgba(19, 27, 68, 0.18);
1431      pointer-events: auto;
1432    }
1433
1434    #shopify-section-sections--21296457187398__geo_market_banner .geo-market-banner__inner {
1435      display: grid;
1436      grid-template-columns: minmax(0, 1fr) auto;
1437      align-items: center;
1438      gap: 1rem 1.5rem;
1439      padding: 0.95rem var(--section-horizontal-spacing);
1440    }
1441
1442    #shopify-section-sections--21296457187398__geo_market_banner .geo-market-banner__message {
1443      margin: 0;
1444      max-width: 48rem;
1445      color: inherit;
1446      font-family: var(--font-body);
1447      font-size: var(--font-size-base);
1448      font-style: var(--font-body-style);
1449      font-weight: 500;
1450      letter-spacing: -0.01em;
1451      line-height: 1.45;
1452    }
1453
1454    #shopify-section-sections--21296457187398__geo_market_banner .geo-market-banner__actions {
1455      display: flex;
1456      flex-wrap: wrap;
1457      align-items: center;
1458      justify-content: flex-end;
1459      gap: 0.75rem;
1460      justify-self: end;
1461    }
1462
1463    #shopify-section-sections--21296457187398__geo_market_banner .geo-market-banner__button,
1464    #shopify-section-sections--21296457187398__geo_market_banner .geo-market-banner__dismiss {
1465      display: inline-flex;
1466      min-height: 2.875rem;
1467      align-items: center;
1468      justify-content: center;
1469      gap: 0.45rem;
1470      border-style: solid;
1471      border-width: var(--text-border-width);
1472      border-radius: var(--button-border-radius);
1473      font-family: var(--font-body);
1474      font-size: var(--font-size-base);
1475      font-style: var(--font-body-style);
1476      font-weight: 600;
1477      line-height: 1;
1478      text-decoration: none;
1479      text-transform: var(--button-text-transform);
1480      white-space: nowrap;
1481      transition:
1482        transform 0.18s ease,
1483        box-shadow 0.18s ease,
1484        background-color 0.18s ease,
1485        border-color 0.18s ease,
1486        color 0.18s ease,
1487        opacity 0.18s ease;
1488    }
1489
1490    #shopify-section-sections--21296457187398__geo_market_banner .geo-market-banner__button {
1491      padding: 0.8rem 1.35rem;
1492      border: 1px solid rgba(255, 255, 255, 0.12);
1493      background: #fbfbf6;
1494      box-shadow: 0 12px 24px rgba(14, 21, 52, 0.14);
1495      color: #2b3990;
1496    }
1497
1498    #shopify-section-sections--21296457187398__geo_market_banner .geo-market-banner__dismiss {
1499      padding: 0.8rem 1rem;
1500      border-color: rgba(248, 250, 244, 0.32);
1501      background: rgba(248, 250, 244, 0.08);
1502      box-shadow: none;
1503      color: inherit;
1504      opacity: 0.96;
1505    }
1506
1507    #shopify-section-sections--21296457187398__geo_market_banner .geo-market-banner__dismiss-icon {
1508      font-size: 0.95rem;
1509      line-height: 1;
1510    }
1511
1512    #shopify-section-sections--21296457187398__geo_market_banner .geo-market-banner__button:focus-visible,
1513    #shopify-section-sections--21296457187398__geo_market_banner .geo-market-banner__dismiss:focus-visible {
1514      outline: 2px solid #f8faf4;
1515      outline-offset: 2px;
1516    }
1517
1518    @media (hover: hover) and (pointer: fine) {
1519      #shopify-section-sections--21296457187398__geo_market_banner .geo-market-banner__button:hover,
1520      #shopify-section-sections--21296457187398__geo_market_banner .geo-market-banner__dismiss:hover {
1521        transform: translateY(-1px);
1522      }
1523
1524      #shopify-section-sections--21296457187398__geo_market_banner .geo-market-banner__button:hover {
1525        background: #ffffff;
1526        box-shadow: 0 16px 30px rgba(14, 21, 52, 0.18);
1527      }
1528
1529      #shopify-section-sections--21296457187398__geo_market_banner .geo-market-banner__dismiss:hover {
1530        border-color: rgba(248, 250, 244, 0.56);
1531        background: rgba(248, 250, 244, 0.16);
1532        opacity: 1;
1533      }
1534    }
1535
1536    @media (max-width: 767px) {
1537      #shopify-section-sections--21296457187398__geo_market_banner .geo-market-banner__inner {
1538        grid-template-columns: 1fr;
1539        align-items: stretch;
1540        gap: 0.9rem;
1541      }
1542
1543      #shopify-section-sections--21296457187398__geo_market_banner .geo-market-banner__message {
1544        max-width: none;
1545      }
1546
1547      #shopify-section-sections--21296457187398__geo_market_banner .geo-market-banner__actions {
1548        width: 100%;
1549        display: grid;
1550        grid-template-columns: 1fr;
1551        justify-content: stretch;
1552        justify-self: stretch;
1553      }
1554
1555      #shopify-section-sections--21296457187398__geo_market_banner .geo-market-banner__button {
1556        width: 100%;
1557      }
1558
1559      #shopify-section-sections--21296457187398__geo_market_banner .geo-market-banner__dismiss {
1560        justify-self: start;
1561      }
1562    }
1563  </style>
1564
1565  <data-island
1566    data-color-scheme="scheme3"
1567    x-data="GeoMarketBanner({
1568    enabled: true,
1569    nzTargetUrl: &quot;https:\/\/theprintroom.nz&quot;,
1570    intlTargetUrl: &quot;https:\/\/printroom.co&quot;,
1571    auTargetUrl: &quot;https:\/\/www.printroom.co\/en-au&quot;,
1572    messages: {
1573      fromInternational: &quot;You&#39;re on our international site.&quot;,
1574      fromNz: &quot;You&#39;re on our New Zealand site.&quot;,
1575      fromAu: &quot;You&#39;re on our Australia site.&quot;,
1576      switchToNz: &quot;Switch to New Zealand&quot;,
1577      switchToAu: &quot;Switch to Australia&quot;,
1578      switchToInternational: &quot;Switch to international&quot;,
1579      dismiss: &quot;Dismiss&quot;
1580    }
1581  })"
1582    role="region"
1583    aria-label="Regional site selector"
1584    x-show="shown"
1585    x-transition:enter="transition duration-300 motion-reduce:duration-0 outline-0"
1586    x-transition:enter-start="-translate-y-full"
1587    x-transition:enter-end="translate-y-0"
1588    x-transition:leave="transition duration-200 motion-reduce:duration-0 outline-0"
1589    x-transition:leave-start="translate-y-0"
1590    x-transition:leave-end="-translate-y-full"
1591    @keydown.escape.window="dismiss"
1592    id="sections--21296457187398__geo_market_banner"
1593    data-geo-market-banner
1594    style="display: none;"
1595    on="idle"
1596    src="//printroom.co/cdn/shop/t/59/assets/island-geo-market-banner.bundle.js?v=76971093760605141431787098434"
1597  >
1598    <div class="geo-market-banner__inner">
1599      <p class="geo-market-banner__message">
1600        <span x-text="message"></span>
1601      </p>
1602      <div class="geo-market-banner__actions">
1603        <a
1604          class="geo-market-banner__button"
1605          :href="targetUrl"
1606          x-text="ctaLabel"
1607          @click="acceptSwitch($event)"
1608        ></a>
1609        <button
1610          class="geo-market-banner__dismiss"
1611          type="button"
1612          @click="dismiss"
1613          :aria-label="dismissLabel"
1614        >
1615          <span x-text="dismissLabel"></span>
1616          <span class="geo-market-banner__dismiss-icon" aria-hidden="true">×</span>
1617        </button>
1618      </div>
1619    </div>
1620  </data-island>
1621
1622
1623
1624</div><div id="shopify-section-sections--21296457187398__header" class="shopify-section shopify-section-group-header-group section-header relative z-20">
1625
1626
1627<style data-shopify>
1628  
1629    #shopify-section-sections--21296457187398__header {
1630      position: sticky;
1631      top: 0;
1632      z-index: 30;
1633    }
1634
1635    :root {
1636      --sticky-header-height: 66px;
1637    }
1638  
1639
1640  #shopify-section-sections--21296457187398__header {
1641    --logo-max-width: 80px;
1642  }
1643  @media (min-width: 1024px) {
1644    #shopify-section-sections--21296457187398__header {
1645      --logo-max-width: 90px;
1646    }
1647  }
1648</style>
1649
1650<data-island
1651  x-data="Header"
1652  class="block"
1653  :class="{ 'is-stuck' : isStuck }"
1654  
1655    data-sticky="true"
1656  
1657  
1658  data-color-scheme="scheme1"
1659  data-overlay-header-with-sticky="false"
1660  data-overlay-text-color-scheme="scheme1"
1661  id="sections--21296457187398__header"
1662  role="banner"
1663  data-theme-header
1664>
1665  
1666    <sticky-header-height-helper hidden></sticky-header-height-helper>
1667  
1668  <header
1669    x-ref="header"
1670    class="relative z-10 text-scheme-text header-glass"
1671    data-color-scheme="scheme1"
1672  >
1673    <nav
1674      class="relative hidden lg:block"
1675      aria-label="Primary"
1676    >
1677      <div class="flex items-stretch px-section-horizontal-spacing justify-between flex-wrap ">
1678        <div class="flex items-stretch">
1679          
1680            <div class="flex">
1681              <a
1682    href="/"
1683    class="break-word my-auto inline-block py-4"
1684  >
1685    
1686    
1687      <div class="max-w-[var(--logo-max-width)]">
1688        
1689<img
1690            src="//printroom.co/cdn/shop/files/printroom_primary_logo.svg?v=1704916358&width=90"
1691            srcset="//printroom.co/cdn/shop/files/printroom_primary_logo.svg?v=1704916358&width=80 80w,//printroom.co/cdn/shop/files/printroom_primary_logo.svg?v=1704916358&width=160 160w,//printroom.co/cdn/shop/files/printroom_primary_logo.svg?v=1704916358&width=240 240w,//printroom.co/cdn/shop/files/printroom_primary_logo.svg?v=1704916358&width=90 90w,//printroom.co/cdn/shop/files/printroom_primary_logo.svg?v=1704916358&width=180 180w,//printroom.co/cdn/shop/files/printroom_primary_logo.svg?v=1704916358&width=270 270w
1692            "
1693            width="543"
1694            height="397"
1695            loading="eager"
1696            
1697              sizes="(min-width: 1024px) 90px, 80px"
1698            
1699            alt="The Print Room"
1700            
1701          >
1702        
1703
1704        
1705      </div>
1706    
1707    
1708  </a>
1709            </div>
1710          
1711          
1712        </div>
1713
1714        
1715          
1716
1717
1718        <a
1719          
1720          class="flex py-4 relative self-stretch inline-flex flex-col"
1721          href="/collections/product-library"
1722        >
1723          <span class="m-auto inline-block">Products</span></a>
1724      
1725    
1726<data-island
1727        x-data="{
1728          expanded: false,
1729          hoverTimeout: null,
1730          openDropdown() {
1731            clearTimeout(this.hoverTimeout);
1732            this.expanded = true;
1733            this.$nextTick(() => {
1734              const header = this.$el.closest('header');
1735              const dd = this.$el.querySelector('.dropdown-glass');
1736              if (header && dd) {
1737                header.style.setProperty('--dropdown-h', dd.offsetHeight + 'px');
1738              }
1739            });
1740          },
1741          closeDropdown() {
1742            this.hoverTimeout = setTimeout(() => {
1743              this.expanded = false;
1744            }, 150);
1745          }
1746        }"
1747        @mouseenter="openDropdown()"
1748        @mouseleave="closeDropdown()"
1749        @focusin="openDropdown()"
1750        @focusout="if ($event.relatedTarget && !$el.contains($event.relatedTarget)) closeDropdown()"
1751        class="no-js-focus-wrapper flex self-stretch header-dropdown"
1752        
1753      >
1754        <button
1755          class="inline-flex py-4 items-center header-menu-item"
1756          @click="expanded = !expanded"
1757          :aria-expanded="expanded ? true : 'false'"
1758          aria-controls="menu0"
1759        >
1760          <span class="inline-block pr-1">Services</span><span
1761              class="mr-1 inline-block h-3 w-3 origin-center align-middle"
1762              x-show="!expanded"
1763            ><svg
1764  class="theme-icon"
1765  xmlns="http://www.w3.org/2000/svg"
1766  fill="none"
1767  viewBox="0 0 24 24"
1768>
1769  <path stroke="currentColor" d="M12 1v22M1 12h22" vector-effect="non-scaling-stroke"/>
1770</svg>
1771</span>
1772            <span
1773              class="mr-1 inline-block h-3 w-3 origin-center align-middle"
1774              x-show="expanded"
1775              style="display: none;"
1776            ><svg
1777  class="theme-icon"
1778  xmlns="http://www.w3.org/2000/svg"
1779  fill="none"
1780  viewBox="0 0 24 24"
1781>
1782  <path stroke="currentColor" d="M1 12h22" vector-effect="non-scaling-stroke"/>
1783</svg>
1784</span></button>
1785        <div
1786          id="menu0"
1787          class="no-js-focus-container absolute top-full z-20 dropdown-glass text-scheme-text bottom-auto left-0 w-full"
1788          x-cloak
1789          x-show="expanded"
1790          x-transition:enter="transition ease-out duration-300 motion-reduce:duration-0"
1791          x-transition:enter-start="opacity-0 -translate-y-2 scale-[0.98]"
1792          x-transition:enter-end="opacity-100 translate-y-0 scale-100"
1793          x-transition:leave="transition ease-in duration-200 motion-reduce:duration-0"
1794          x-transition:leave-start="opacity-100 translate-y-0 scale-100"
1795          x-transition:leave-end="opacity-0 -translate-y-1 scale-[0.99]"
1796          style="transform-origin: top center;"
1797          data-color-scheme=""
1798        ><div class=" text-left"><div class="grid gap-gutter bg-gridline-color grid-cols-4">
1799                
1800        <div class="bg-scheme-background px-section-horizontal-spacing py-section-vertical-spacing text-scheme-text">
1801          <a
1802            
1803            class="font-heading inline-block py-1"
1804            href="/pages/services"
1805          >
1806            Services
1807          </a>
1808        </div>
1809      
1810                
1811
1812
1813<div class="bg-scheme-background px-section-horizontal-spacing py-section-vertical-spacing text-scheme-text">
1814              <h2 class="font-heading mb-2">
1815                
1816                  <a
1817                    
1818                    class="inline-block py-1"
1819                    href="/pages/product-capabilities"
1820                    
1821                  >
1822                    Production capabilities
1823                  </a>
1824                
1825              </h2>
1826              <ul><li class="">
1827                    <a
1828                      
1829                      class="inline-block py-1"
1830                      href="/pages/custom-manufactured"
1831                    >Custom-manufactured</a>
1832                  </li><li class="">
1833                    <a
1834                      
1835                      class="inline-block py-1"
1836                      href="/pages/screen-printing"
1837                    >Screen printing</a>
1838                  </li><li class="">
1839                    <a
1840                      
1841                      class="inline-block py-1"
1842                      href="/pages/embroidery"
1843                    >Embroidery</a>
1844                  </li><li class="">
1845                    <a
1846                      
1847                      class="inline-block py-1"
1848                      href="/pages/heat-transfers"
1849                    >Heat transfers</a>
1850                  </li><li class="">
1851                    <a
1852                      
1853                      class="inline-block py-1"
1854                      href="/pages/finishing"
1855                    >Finishing</a>
1856                  </li></ul>
1857            </div><div class="bg-scheme-background px-section-horizontal-spacing py-section-vertical-spacing text-scheme-text">
1858              <h2 class="font-heading mb-2">
1859                
1860                  <a
1861                    
1862                    class="inline-block py-1"
1863                    href="/pages/partner-services"
1864                    
1865                  >
1866                    Partner services
1867                  </a>
1868                
1869              </h2>
1870              <ul><li class="">
1871                    <a
1872                      
1873                      class="inline-block py-1"
1874                      href="/pages/client-portal"
1875                    >Client portal</a>
1876                  </li><li class="">
1877                    <a
1878                      
1879                      class="inline-block py-1"
1880                      href="/pages/fundraising-pre-orders"
1881                    >Fundraise & pre-order</a>
1882                  </li><li class="">
1883                    <a
1884                      
1885                      class="inline-block py-1"
1886                      href="/pages/repurpose-initiative"
1887                    >Repurpose initiative</a>
1888                  </li></ul>
1889            </div><div class="bg-scheme-background px-section-horizontal-spacing py-section-vertical-spacing text-scheme-text">
1890              <h2 class="font-heading mb-2">
1891                
1892                  <a
1893                    
1894                    class="inline-block py-1"
1895                    href="/pages/popular-services"
1896                    
1897                  >
1898                    Popular services
1899                  </a>
1900                
1901              </h2>
1902              <ul><li class="">
1903                    <a
1904                      
1905                      class="inline-block py-1"
1906                      href="/pages/school-leavers-gear"
1907                    >School leavers gear</a>
1908                  </li><li class="">
1909                    <a
1910                      
1911                      class="inline-block py-1"
1912                      href="/pages/tshirt-printing"
1913                    >Custom t-shirt printing</a>
1914                  </li></ul>
1915            </div>
1916</div></div></div>
1917      </data-island>
1918
1919
1920
1921
1922        <a
1923          
1924          class="flex py-4 relative self-stretch inline-flex flex-col"
1925          href="/pages/responsibility"
1926        >
1927          <span class="m-auto inline-block">Responsibility</span></a>
1928      
1929    
1930<data-island
1931        x-data="{
1932          expanded: false,
1933          hoverTimeout: null,
1934          openDropdown() {
1935            clearTimeout(this.hoverTimeout);
1936            this.expanded = true;
1937            this.$nextTick(() => {
1938              const header = this.$el.closest('header');
1939              const dd = this.$el.querySelector('.dropdown-glass');
1940              if (header && dd) {
1941                header.style.setProperty('--dropdown-h', dd.offsetHeight + 'px');
1942              }
1943            });
1944          },
1945          closeDropdown() {
1946            this.hoverTimeout = setTimeout(() => {
1947              this.expanded = false;
1948            }, 150);
1949          }
1950        }"
1951        @mouseenter="openDropdown()"
1952        @mouseleave="closeDropdown()"
1953        @focusin="openDropdown()"
1954        @focusout="if ($event.relatedTarget && !$el.contains($event.relatedTarget)) closeDropdown()"
1955        class="no-js-focus-wrapper flex self-stretch header-dropdown"
1956        style="position: relative;"
1957      >
1958        <button
1959          class="inline-flex py-4 items-center header-menu-item"
1960          @click="expanded = !expanded"
1961          :aria-expanded="expanded ? true : 'false'"
1962          aria-controls="menu1"
1963        >
1964          <span class="inline-block pr-1">Our story</span><span
1965              class="mr-1 inline-block h-3 w-3 origin-center align-middle"
1966              x-show="!expanded"
1967            ><svg
1968  class="theme-icon"
1969  xmlns="http://www.w3.org/2000/svg"
1970  fill="none"
1971  viewBox="0 0 24 24"
1972>
1973  <path stroke="currentColor" d="M12 1v22M1 12h22" vector-effect="non-scaling-stroke"/>
1974</svg>
1975</span>
1976            <span
1977              class="mr-1 inline-block h-3 w-3 origin-center align-middle"
1978              x-show="expanded"
1979              style="display: none;"
1980            ><svg
1981  class="theme-icon"
1982  xmlns="http://www.w3.org/2000/svg"
1983  fill="none"
1984  viewBox="0 0 24 24"
1985>
1986  <path stroke="currentColor" d="M1 12h22" vector-effect="non-scaling-stroke"/>
1987</svg>
1988</span></button>
1989        <div
1990          id="menu1"
1991          class="no-js-focus-container absolute top-full z-20 dropdown-glass text-scheme-text gs-dropdown-content nav-dropdown-content"
1992          x-cloak
1993          x-show="expanded"
1994          x-transition:enter="transition ease-out duration-300 motion-reduce:duration-0"
1995          x-transition:enter-start="opacity-0 -translate-y-2 scale-[0.98]"
1996          x-transition:enter-end="opacity-100 translate-y-0 scale-100"
1997          x-transition:leave="transition ease-in duration-200 motion-reduce:duration-0"
1998          x-transition:leave-start="opacity-100 translate-y-0 scale-100"
1999          x-transition:leave-end="opacity-0 -translate-y-1 scale-[0.99]"
2000          style="transform-origin: top left;"
2001          data-color-scheme=""
2002        ><a
2003                href="/pages/in-good-company-with"
2004                
2005              >In good company with…</a><a
2006                href="/pages/about-print-room"
2007                
2008              >Our origins</a></div>
2009      </data-island>
2010
2011<data-island
2012          x-data="{
2013            expanded: false,
2014            hoverTimeout: null,
2015            openDropdown() {
2016              clearTimeout(this.hoverTimeout);
2017              this.expanded = true;
2018              this.$nextTick(() => {
2019                const header = this.$el.closest('header');
2020                const dd = this.$el.querySelector('.dropdown-glass');
2021                if (header && dd) {
2022                  header.style.setProperty('--dropdown-h', dd.offsetHeight + 'px');
2023                }
2024              });
2025            },
2026            closeDropdown() {
2027              this.hoverTimeout = setTimeout(() => {
2028                this.expanded = false;
2029              }, 150);
2030            }
2031          }"
2032          @mouseenter="openDropdown()"
2033          @mouseleave="closeDropdown()"
2034          @focusin="openDropdown()"
2035          @focusout="if ($event.relatedTarget && !$el.contains($event.relatedTarget)) closeDropdown()"
2036          class="no-js-focus-wrapper flex items-center self-stretch header-dropdown"
2037          style="position: relative;"
2038        >
2039          <button
2040            class="gs-pill"
2041            :class="{ 'is-active': expanded }"
2042            @click="expanded = !expanded"
2043            :aria-expanded="expanded ? 'true' : 'false'"
2044          >
2045            <span>Get started +</span>
2046          </button>
2047          <div
2048            class="no-js-focus-container absolute top-full z-20 dropdown-glass text-scheme-text gs-dropdown-content"
2049            x-cloak
2050            x-show="expanded"
2051            x-transition:enter="transition ease-out duration-300 motion-reduce:duration-0"
2052            x-transition:enter-start="opacity-0 -translate-y-2"
2053            x-transition:enter-end="opacity-100 translate-y-0"
2054            x-transition:leave="transition ease-in duration-200 motion-reduce:duration-0"
2055            x-transition:leave-start="opacity-100 translate-y-0"
2056            x-transition:leave-end="opacity-0 -translate-y-1"
2057            style="transform-origin: top left;"
2058            data-color-scheme=""
2059          ><a href="/collections/product-library">Start a project</a><a href="/pages/book-a-call">Book a call</a></div>
2060        </data-island>
2061
2062        
2063<div class="flex items-stretch justify-end gap-x-4 text-right "><div class="ml-4 my-auto shrink-0"><form method="post" action="/localization" id="header-localization-form" accept-charset="UTF-8" class="shopify-localization-form" enctype="multipart/form-data"><input type="hidden" name="form_type" value="localization" /><input type="hidden" name="utf8" value="✓" /><input type="hidden" name="_method" value="put" /><input type="hidden" name="return_to" value="/cart" /><div class="flex gap-4 justify-end max-lg:hidden"><div class="inline-block shrink-0 select-none">
2064        <h2 class="sr-only" id="country-heading-header">
2065          Country/region
2066        </h2>
2067        <data-island
2068          class="relative"
2069          x-data="{ expanded: false }"
2070          @keydown.escape.prevent.stop="expanded = false"
2071          @click.outside="expanded = false"
2072        >
2073          <button
2074            type="button"
2075            class="text-base py-4"
2076            :aria-expanded="expanded"
2077            aria-controls="country-list-header"
2078            aria-describedby="country-heading-header"
2079            @click.prevent="expanded = ! expanded"
2080          >
2081            United States (USD
2082            $)
2083            <span
2084              class="rotate ml-1 inline-block w-3 origin-center transform fill-current transition"
2085              :class="{ 'rotate-180': expanded }"
2086            >
2087              <svg
2088  class="theme-icon"
2089  xmlns="http://www.w3.org/2000/svg"
2090  fill="none"
2091  viewBox="0 0 24 24"
2092>
2093  <path stroke="currentColor" d="M1.5 7 12 17.5 22.5 7" vector-effect="non-scaling-stroke"/>
2094</svg>
2095
2096            </span>
2097          </button>
2098          <div
2099            class="absolute top-full left-0 right-auto"
2100            x-show="expanded"
2101            style="display: none;"
2102          >
2103            <ul
2104              id="country-list-header"
2105              class="relative z-10 flex max-h-[30vh] w-max max-w-[theme(spacing.64)] snap-y snap-mandatory flex-col gap-[--text-border-width] overflow-y-auto border-text border-gridline-color bg-gridline-color text-base"
2106              x-transition:enter="transition ease duration-300"
2107              x-transition:enter-start="opacity-0"
2108              x-transition:enter-end="opacity-100"
2109              x-transition:leave="transition ease duration-300"
2110              x-transition:leave-start="opacity-100"
2111              x-transition:leave-end="opacity-0"
2112              :aria-hidden="! expanded"
2113            >
2114              
2115                <li class="flex items-center bg-scheme-background px-4 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
2116                  <button
2117                    class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
2118                    type="button"
2119                    
2120                    @click.prevent="$refs.input.value = 'AU'; $root.closest('form').submit();"
2121                  >
2122                    <span class="border-transparent border-b-text">Australia (AUD
2123                      $)</span
2124                    >
2125                  </button>
2126                </li>
2127                <li class="flex items-center bg-scheme-background px-4 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
2128                  <button
2129                    class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
2130                    type="button"
2131                    
2132                    @click.prevent="$refs.input.value = 'CN'; $root.closest('form').submit();"
2133                  >
2134                    <span class="border-transparent border-b-text">China (CNY
2135                      ¥)</span
2136                    >
2137                  </button>
2138                </li>
2139                <li class="flex items-center bg-scheme-background px-4 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
2140                  <button
2141                    class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
2142                    type="button"
2143                    
2144                    @click.prevent="$refs.input.value = 'FR'; $root.closest('form').submit();"
2145                  >
2146                    <span class="border-transparent border-b-text">France (EUR
2147                      €)</span
2148                    >
2149                  </button>
2150                </li>
2151                <li class="flex items-center bg-scheme-background px-4 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
2152                  <button
2153                    class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
2154                    type="button"
2155                    
2156                    @click.prevent="$refs.input.value = 'NZ'; $root.closest('form').submit();"
2157                  >
2158                    <span class="border-transparent border-b-text">New Zealand (NZD
2159                      $)</span
2160                    >
2161                  </button>
2162                </li>
2163                <li class="flex items-center bg-scheme-background px-4 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
2164                  <button
2165                    class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
2166                    type="button"
2167                    
2168                    @click.prevent="$refs.input.value = 'GB'; $root.closest('form').submit();"
2169                  >
2170                    <span class="border-transparent border-b-text">United Kingdom (GBP
2171                      £)</span
2172                    >
2173                  </button>
2174                </li>
2175                <li class="flex items-center bg-scheme-background px-4 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
2176                  <button
2177                    class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
2178                    type="button"
2179                    
2180                      aria-current="true"
2181                    
2182                    @click.prevent="$refs.input.value = 'US'; $root.closest('form').submit();"
2183                  >
2184                    <span class="border-scheme-text border-b-text">United States (USD
2185                      $)</span
2186                    >
2187                  </button>
2188                </li></ul>
2189          </div>
2190
2191          <input
2192            x-ref="input"
2193            type="hidden"
2194            name="country_code"
2195            id="CountrySelector"
2196            value="US"
2197          >
2198        </data-island>
2199      </div></div></form></div>
2200            <div class="flex items-stretch whitespace-nowrap">
2201              <data-island
2202  x-data="{ searchOpen: false }"
2203  class="contents"
2204>
2205  <a
2206    x-ref="searchToggle"
2207    @click.prevent="searchOpen = true"
2208    @keydown.space.prevent="searchOpen = true"
2209    class="inline-flex py-4 h-full"
2210    href="/search"
2211    :role="`button`"
2212  ><span class="sr-only">Search</span>
2213      <span class="my-auto inline-block h-6 w-6 align-middle"><svg
2214  class="theme-icon"
2215  xmlns="http://www.w3.org/2000/svg"
2216  fill="none"
2217  viewBox="0 0 24 24"
2218>
2219  <path stroke="currentColor" d="M2 11a9 9 0 1 0 18 0 9 9 0 0 0-18 0Zm15.364 6.364L22 22" vector-effect="non-scaling-stroke"/>
2220</svg>
2221</span></a>
2222
2223  <data-island
2224    class="absolute z-20 border-y-gridline border-gridline-color bg-scheme-background px-section-horizontal-spacing py-2 text-scheme-text  w-full top-full bottom-auto left-0"
2225    x-cloak
2226    x-show="searchOpen"
2227    x-transition:enter="ease duration-200"
2228    x-transition:enter-start="opacity-0"
2229    x-transition:enter-end="opacity-100"
2230    x-transition:leave="ease duration-200"
2231    x-transition:leave-start="opacity-100"
2232    x-transition:leave-end="opacity-0"
2233    
2234      x-data="PredictiveSearch('product,collection,article,page,query')"
2235      x-trap.inert.noscroll="resultsOpen"
2236      @keyup="onKeyup"
2237      @keydown="onKeydown"
2238      @click.outside.prevent="close()"
2239      @keyup.escape.prevent.stop="close(true, $refs.searchToggle)"
2240      @focusin.window="( searchOpen && ! $root.contains($event.target) ) && close()"
2241      style="--results-height: calc(100vh - var(--header-group-height) - var(--search-bar-height) + var(--gridline-width));"
2242      src="//printroom.co/cdn/shop/t/59/assets/island-predictive-search.bundle.js?v=181601895277339900721787098435"
2243    
2244    x-ref="searchComponent"
2245    data-color-scheme="scheme1"
2246    on="idle"
2247  >
2248    <div
2249      class="w-full whitespace-normal"
2250    >
2251      <form
2252        action="/search"
2253        method="get"
2254        class="predictive-search-form input-group search"
2255        role="search"
2256      >
2257        <input type="hidden" name="options[prefix]" value="last"><label
2258          for="search-logo_left_menu_spread-desktop"
2259          class="hidden"
2260        >Submit</label>
2261
2262        <div
2263          class="flex items-center justify-between"
2264        >
2265          <button
2266            class="mr-4 py-2"
2267            aria-label="Submit"
2268            type="submit"
2269          >
2270            <span class="inline-block h-6 w-6 align-middle"><svg
2271  class="theme-icon"
2272  xmlns="http://www.w3.org/2000/svg"
2273  fill="none"
2274  viewBox="0 0 24 24"
2275>
2276  <path stroke="currentColor" d="M2 11a9 9 0 1 0 18 0 9 9 0 0 0-18 0Zm15.364 6.364L22 22" vector-effect="non-scaling-stroke"/>
2277</svg>
2278</span>
2279            <span class="sr-only">Submit</span>
2280          </button>
2281          <input
2282            id="search-logo_left_menu_spread-desktop"
2283            type="search"
2284            name="q"
2285            value=""
2286            placeholder="Search"
2287            class="font-body block w-full bg-transparent placeholder-current"
2288            aria-label="Search"
2289            data-search-input
2290            
2291              :aria-expanded="resultsOpen"
2292              :aria-activedescendant="resultsOpen ? 'predictive-search-results' : false"
2293              aria-owns="predictive-search-results"
2294              aria-controls="predictive-search-results"
2295              aria-autocomplete="list"
2296              autocorrect="off"
2297              autocomplete="off"
2298              autocapitalize="off"
2299              spellcheck="false"
2300              x-ref="input"
2301              x-model.debounce.300="rawQuery"
2302              @focus="onFocus"
2303            
2304          >
2305          <button
2306            class="ml-4 py-2"
2307            
2308              @click="close()"
2309            
2310            type="button"
2311          >
2312            <span class="sr-only">Close</span>
2313            <span class="inline-block h-6 w-6 align-middle"><svg
2314  class="theme-icon"
2315  xmlns="http://www.w3.org/2000/svg"
2316  fill="none"
2317  viewBox="0 0 24 24"
2318>
2319  <path stroke="currentColor" d="m1.5 1.5 21 21m0-21-21 21" vector-effect="non-scaling-stroke"/>
2320</svg>
2321</span>
2322          </button>
2323        </div><div
2324            tabindex="-1"
2325            x-cloak
2326            class="predictive-search-results absolute left-0 right-0 top-[calc(100%_+_var(--gridline-width))] z-50 h-screen text-scheme-text transition-colors duration-300 ease-out"
2327          >
2328            <template x-if="loading">
2329              <div class="border-b-gridline border-gridline-color bg-scheme-background">
2330                <div
2331                  class="mx-auto py-6 text-center"
2332                >
2333                  <div>Loading&hellip;</div>
2334                </div>
2335              </div>
2336            </template>
2337            <template x-if="resultsOpen">
2338              <div
2339                x-show="!loading && resultsHTML && resultsOpen"
2340                class="px-section max-h-[--results-height] scroll-py-5 overflow-hidden overflow-y-auto border-b-gridline border-gridline-color bg-scheme-background"
2341                x-html-if-set="resultsHTML"
2342              ></div>
2343            </template>
2344          </div>
2345          <span
2346            class="predictive-search-status sr-only"
2347            role="status"
2348            aria-hidden="true"
2349          ></span></form>
2350    </div>
2351  </data-island>
2352</data-island>
2353
2354            </div>
2355          
2356
2357          <div class="flex items-stretch whitespace-nowrap gap-4"><style>
2358  @keyframes quote-badge-pulse {
2359    0% { transform: scale(1); }
2360    50% { transform: scale(1.22); }
2361    100% { transform: scale(1); }
2362  }
2363
2364  @keyframes quote-icon-pulse {
2365    0% { transform: scale(1); }
2366    50% { transform: scale(1.12); }
2367    100% { transform: scale(1); }
2368  }
2369
2370  .quote-badge-animate {
2371    animation: quote-badge-pulse 0.4s ease-in-out;
2372  }
2373  .quote-icon-animate {
2374    animation: quote-icon-pulse 0.4s ease-in-out;
2375  }
2376  .quote-badge {
2377    min-width: 1.3rem;
2378    padding-inline: 0.22rem;
2379    box-shadow: 0 10px 24px rgba(43, 57, 144, 0.22);
2380  }
2381  .quote-tooltip {
2382    position: absolute;
2383    top: calc(100% + 8px);
2384    right: -10px;
2385    width: 152px;
2386    padding: 15px 16px;
2387    border-radius: 20px;
2388    font-size: 14px;
2389    font-style: italic;
2390    line-height: 17px;
2391    color: #000;
2392    background: #FBFBF6;
2393    border: 1px solid #000;
2394    box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.15);
2395    z-index: 1000;
2396    cursor: pointer;
2397    white-space: normal;
2398    text-align: left;
2399  }
2400  .quote-tooltip::before {
2401    content: '';
2402    position: absolute;
2403    top: -7px;
2404    right: 24px;
2405    width: 14px;
2406    height: 14px;
2407    background: #FBFBF6;
2408    border-top: 1px solid #000;
2409    border-left: 1px solid #000;
2410    transform: rotate(45deg);
2411  }
2412  @media (max-width: 640px) {
2413    .quote-tooltip {
2414      right: -10px;
2415    }
2416  }
2417</style>
2418
2419<div
2420  class="relative"
2421  x-data="{
2422    showTooltip: false,
2423    tooltipDismissed: false,
2424    animating: false,
2425    tooltipTimer: null,
2426    dismissTooltip() {
2427      this.showTooltip = false;
2428      this.tooltipDismissed = true;
2429      if (this.tooltipTimer) clearTimeout(this.tooltipTimer);
2430      if (this.tooltipDelayTimer) clearTimeout(this.tooltipDelayTimer);
2431    },
2432    tooltipDelayTimer: null,
2433    triggerTooltip() {
2434      try {
2435        if (this.tooltipDismissed || sessionStorage.getItem('psstShown')) return;
2436      } catch (error) {
2437        if (this.tooltipDismissed) return;
2438      }
2439      if (this.tooltipDelayTimer) clearTimeout(this.tooltipDelayTimer);
2440      this.tooltipDelayTimer = setTimeout(() => {
2441        if (this.tooltipDismissed) return;
2442        try { sessionStorage.setItem('psstShown', '1'); } catch(e) {}
2443        this.showTooltip = true;
2444        if (this.tooltipTimer) clearTimeout(this.tooltipTimer);
2445        this.tooltipTimer = setTimeout(() => { this.showTooltip = false; }, 15000);
2446      }, 5000);
2447    },
2448    pulseIcon() {
2449      this.animating = true;
2450      setTimeout(() => { this.animating = false; }, 450);
2451    }
2452  }"
2453  @quote-item-added.document="pulseIcon(); triggerTooltip()"
2454>
2455  <a
2456    href="/pages/general-quote"
2457    class="inline-flex min-h-10 items-center py-4 h-full"
2458    :role="`button`"
2459    :aria-expanded="$store.modals.rightDrawer.contents === 'favorites'"
2460    @click.prevent="$store.modals.open('favorites'); dismissTooltip(); window.dataLayer = window.dataLayer || []; window.dataLayer.push({ event: 'quote_drawer_opened', quote_count: $store.favorites.count, page_path: window.location.pathname })"
2461    @keydown.space.prevent="$store.modals.open('favorites'); dismissTooltip()"
2462    aria-label="Open your quote"
2463  ><div class="pointer-events-none relative my-auto align-middle" :class="{ 'quote-icon-animate': animating }"><span class="inline-block h-6 w-6 align-top [&_*]:pointer-events-none"><span class="h-full w-full">
2464  <svg
2465    aria-hidden="true"
2466    focusable="false"
2467    role="presentation"
2468    class="icon icon-quote-list-outline"
2469    viewBox="0 0 24 24"
2470    fill="none"
2471  ><rect x="3" y="1" width="18" height="22" rx="2.5" ry="2.5" stroke="currentColor" stroke-width="1.5"></rect><circle cx="7.5" cy="7.5" r="1" fill="currentColor"></circle>
2472    <line x1="10" y1="7.5" x2="17.5" y2="7.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></line>
2473    <circle cx="7.5" cy="11" r="1" fill="currentColor"></circle>
2474    <line x1="10" y1="11" x2="17.5" y2="11" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></line>
2475    <circle cx="7.5" cy="14.5" r="1" fill="currentColor"></circle>
2476    <line x1="10" y1="14.5" x2="17.5" y2="14.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></line>
2477    <circle cx="7.5" cy="18" r="1" fill="currentColor"></circle>
2478    <line x1="10" y1="18" x2="17.5" y2="18" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></line>
2479  </svg>
2480</span>
2481</span><span
2482          x-show="$store.favorites.count > 0"
2483          x-cloak
2484          class="quote-badge absolute flex items-center justify-center rounded-full text-[10px] font-bold"
2485          style="background-color: #4B4D72; color: #fff; width: 18px; height: 18px; top: -7px; right: -8px;"
2486          :class="{ 'quote-badge-animate': animating }"
2487          x-text="$store.favorites.count"
2488        ></span>
2489        <span class="sr-only" x-text="'Your Quote: ' + $store.favorites.countWithText()">
2490          Your Quote: 0 items
2491        </span>
2492      </div></a><div
2493    x-show="showTooltip"
2494    x-transition:enter="transition ease-out duration-200"
2495    x-transition:enter-start="opacity-0 translate-y-1"
2496    x-transition:enter-end="opacity-100 translate-y-0"
2497    x-transition:leave="transition ease-in duration-150"
2498    x-transition:leave-start="opacity-100"
2499    x-transition:leave-end="opacity-0"
2500    x-cloak
2501    class="quote-tooltip"
2502    @click="dismissTooltip()"
2503  >
2504    Hi, your favourite products are here.
2505  </div>
2506</div>
2507
2508  <a
2509    href="/cart"
2510    class="inline-flex py-4 h-full"
2511    
2512  ><div class="pointer-events-none relative my-auto align-middle">
2513        <span
2514          x-show="$store.cartCount.count > 0"
2515          class="absolute right-0 top-1 h-2 w-2 rounded-full"
2516          style="background-color: #f1ffa5;"
2517        ></span>
2518        <span class="inline-block h-6 w-6 fill-current align-top [&_*]:pointer-events-none"><svg
2519  class="theme-icon"
2520  xmlns="http://www.w3.org/2000/svg"
2521  fill="none"
2522  viewBox="0 0 24 24"
2523>
2524  <path stroke="currentColor" d="M2 7h20v15H2V7Zm15 0v-.2A4.8 4.8 0 0 0 12.2 2h-.4A4.8 4.8 0 0 0 7 6.8V7" vector-effect="non-scaling-stroke"/>
2525</svg>
2526</span>
2527        <span class="sr-only" x-text="$store.cartCount.countWithText()">
2528          
25290 items
2530        </span>
2531      </div></a>
2532          </div>
2533        </div>
2534      </div>
2535
2536      
2537    </nav>
2538
2539    
2540    <nav
2541      aria-label="Header"
2542      class="lg:hidden"
2543    >
2544      <div class="flex items-center justify-between px-section-horizontal-spacing lg:relative">
2545        <div class="flex gap-2 items-center">
2546          
2547            <div>
2548              <a
2549    href="/"
2550    class="break-word my-auto inline-block py-4"
2551  >
2552    
2553    
2554      <div class="max-w-[var(--logo-max-width)]">
2555        
2556<img
2557            src="//printroom.co/cdn/shop/files/printroom_primary_logo.svg?v=1704916358&width=90"
2558            srcset="//printroom.co/cdn/shop/files/printroom_primary_logo.svg?v=1704916358&width=80 80w,//printroom.co/cdn/shop/files/printroom_primary_logo.svg?v=1704916358&width=160 160w,//printroom.co/cdn/shop/files/printroom_primary_logo.svg?v=1704916358&width=240 240w,//printroom.co/cdn/shop/files/printroom_primary_logo.svg?v=1704916358&width=90 90w,//printroom.co/cdn/shop/files/printroom_primary_logo.svg?v=1704916358&width=180 180w,//printroom.co/cdn/shop/files/printroom_primary_logo.svg?v=1704916358&width=270 270w
2559            "
2560            width="543"
2561            height="397"
2562            loading="eager"
2563            
2564              sizes="(min-width: 1024px) 90px, 80px"
2565            
2566            alt="The Print Room"
2567            
2568          >
2569        
2570
2571        
2572      </div>
2573    
2574    
2575  </a>
2576            </div>
2577          
2578          
2579        </div>
2580
2581        
2582
2583        <div class="flex justify-end gap-2 text-right">
2584          
2585            <button
2586    class="inline-block no-js:hidden py-4"
2587    :aria-expanded="$store.modals.leftDrawer.contents === 'sidebar'"
2588    @click="$store.modals.open('sidebar')"
2589  ><span class="sr-only pointer-events-none">Menu</span>
2590      <span class="pointer-events-none inline-block h-6 w-6 align-middle"><svg
2591  class="theme-icon"
2592  xmlns="http://www.w3.org/2000/svg"
2593  fill="none"
2594  viewBox="0 0 24 24"
2595>
2596  <path stroke="currentColor" d="M1 7.364h22M1 15.636h22" vector-effect="non-scaling-stroke"/>
2597</svg>
2598</span></button>
2599          
2600
2601          
2602
2603          
2604            <div class="whitespace-nowrap lg:ml-4">
2605              <data-island
2606  x-data="{ searchOpen: false }"
2607  class="contents"
2608>
2609  <a
2610    x-ref="searchToggle"
2611    @click.prevent="searchOpen = true"
2612    @keydown.space.prevent="searchOpen = true"
2613    class="inline-flex py-4 h-full"
2614    href="/search"
2615    :role="`button`"
2616  ><span class="sr-only">Search</span>
2617      <span class="my-auto inline-block h-6 w-6 align-middle"><svg
2618  class="theme-icon"
2619  xmlns="http://www.w3.org/2000/svg"
2620  fill="none"
2621  viewBox="0 0 24 24"
2622>
2623  <path stroke="currentColor" d="M2 11a9 9 0 1 0 18 0 9 9 0 0 0-18 0Zm15.364 6.364L22 22" vector-effect="non-scaling-stroke"/>
2624</svg>
2625</span></a>
2626
2627  <data-island
2628    class="absolute z-20 border-y-gridline border-gridline-color bg-scheme-background px-section-horizontal-spacing py-2 text-scheme-text  w-full top-full bottom-auto left-0"
2629    x-cloak
2630    x-show="searchOpen"
2631    x-transition:enter="ease duration-200"
2632    x-transition:enter-start="opacity-0"
2633    x-transition:enter-end="opacity-100"
2634    x-transition:leave="ease duration-200"
2635    x-transition:leave-start="opacity-100"
2636    x-transition:leave-end="opacity-0"
2637    
2638      x-data="PredictiveSearch('product,collection,article,page,query')"
2639      x-trap.inert.noscroll="resultsOpen"
2640      @keyup="onKeyup"
2641      @keydown="onKeydown"
2642      @click.outside.prevent="close()"
2643      @keyup.escape.prevent.stop="close(true, $refs.searchToggle)"
2644      @focusin.window="( searchOpen && ! $root.contains($event.target) ) && close()"
2645      style="--results-height: calc(100vh - var(--header-group-height) - var(--search-bar-height) + var(--gridline-width));"
2646      src="//printroom.co/cdn/shop/t/59/assets/island-predictive-search.bundle.js?v=181601895277339900721787098435"
2647    
2648    x-ref="searchComponent"
2649    data-color-scheme="scheme1"
2650    on="idle"
2651  >
2652    <div
2653      class="w-full whitespace-normal"
2654    >
2655      <form
2656        action="/search"
2657        method="get"
2658        class="predictive-search-form input-group search"
2659        role="search"
2660      >
2661        <input type="hidden" name="options[prefix]" value="last"><label
2662          for="search-logo_left_menu_spread-mobile"
2663          class="hidden"
2664        >Submit</label>
2665
2666        <div
2667          class="flex items-center justify-between"
2668        >
2669          <button
2670            class="mr-4 py-2"
2671            aria-label="Submit"
2672            type="submit"
2673          >
2674            <span class="inline-block h-6 w-6 align-middle"><svg
2675  class="theme-icon"
2676  xmlns="http://www.w3.org/2000/svg"
2677  fill="none"
2678  viewBox="0 0 24 24"
2679>
2680  <path stroke="currentColor" d="M2 11a9 9 0 1 0 18 0 9 9 0 0 0-18 0Zm15.364 6.364L22 22" vector-effect="non-scaling-stroke"/>
2681</svg>
2682</span>
2683            <span class="sr-only">Submit</span>
2684          </button>
2685          <input
2686            id="search-logo_left_menu_spread-mobile"
2687            type="search"
2688            name="q"
2689            value=""
2690            placeholder="Search"
2691            class="font-body block w-full bg-transparent placeholder-current"
2692            aria-label="Search"
2693            data-search-input
2694            
2695              :aria-expanded="resultsOpen"
2696              :aria-activedescendant="resultsOpen ? 'predictive-search-results' : false"
2697              aria-owns="predictive-search-results"
2698              aria-controls="predictive-search-results"
2699              aria-autocomplete="list"
2700              autocorrect="off"
2701              autocomplete="off"
2702              autocapitalize="off"
2703              spellcheck="false"
2704              x-ref="input"
2705              x-model.debounce.300="rawQuery"
2706              @focus="onFocus"
2707            
2708          >
2709          <button
2710            class="ml-4 py-2"
2711            
2712              @click="close()"
2713            
2714            type="button"
2715          >
2716            <span class="sr-only">Close</span>
2717            <span class="inline-block h-6 w-6 align-middle"><svg
2718  class="theme-icon"
2719  xmlns="http://www.w3.org/2000/svg"
2720  fill="none"
2721  viewBox="0 0 24 24"
2722>
2723  <path stroke="currentColor" d="m1.5 1.5 21 21m0-21-21 21" vector-effect="non-scaling-stroke"/>
2724</svg>
2725</span>
2726          </button>
2727        </div><div
2728            tabindex="-1"
2729            x-cloak
2730            class="predictive-search-results absolute left-0 right-0 top-[calc(100%_+_var(--gridline-width))] z-50 h-screen text-scheme-text transition-colors duration-300 ease-out"
2731          >
2732            <template x-if="loading">
2733              <div class="border-b-gridline border-gridline-color bg-scheme-background">
2734                <div
2735                  class="mx-auto py-6 text-center"
2736                >
2737                  <div>Loading&hellip;</div>
2738                </div>
2739              </div>
2740            </template>
2741            <template x-if="resultsOpen">
2742              <div
2743                x-show="!loading && resultsHTML && resultsOpen"
2744                class="px-section max-h-[--results-height] scroll-py-5 overflow-hidden overflow-y-auto border-b-gridline border-gridline-color bg-scheme-background"
2745                x-html-if-set="resultsHTML"
2746              ></div>
2747            </template>
2748          </div>
2749          <span
2750            class="predictive-search-status sr-only"
2751            role="status"
2752            aria-hidden="true"
2753          ></span></form>
2754    </div>
2755  </data-island>
2756</data-island>
2757
2758            </div>
2759          
2760<div class="inline-block shrink-0 select-none whitespace-nowrap lg:ml-4">
2761            <data-island
2762              class="relative"
2763              x-data="{ expanded: false }"
2764              @keydown.escape.prevent.stop="expanded = false"
2765              @click.outside="expanded = false"
2766            >
2767              <button
2768                type="button"
2769                class="inline-flex py-4 h-full"
2770                :aria-expanded="expanded"
2771                aria-controls="currency-list-header"
2772                @click.prevent="expanded = ! expanded"
2773                aria-label="Currency selector"
2774              >
2775                <span class="my-auto inline-flex items-center gap-1">
2776                  <span class="inline-block h-6 w-6 align-middle">
2777                    <svg class="theme-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
2778  <circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="1.5" vector-effect="non-scaling-stroke" fill="none"/>
2779  <path stroke="currentColor" stroke-width="1.5" d="M12 6v12M8 10h8M8 14h8" vector-effect="non-scaling-stroke"/>
2780</svg>
2781                  </span>
2782                  <span class="text-xs font-medium">USD</span>
2783                </span>
2784                <span
2785                  class="rotate ml-1 inline-block w-3 origin-center transform fill-current transition my-auto"
2786                  :class="{ 'rotate-180': expanded }"
2787                >
2788                  <svg
2789  class="theme-icon"
2790  xmlns="http://www.w3.org/2000/svg"
2791  fill="none"
2792  viewBox="0 0 24 24"
2793>
2794  <path stroke="currentColor" d="M1.5 7 12 17.5 22.5 7" vector-effect="non-scaling-stroke"/>
2795</svg>
2796
2797                </span>
2798              </button>
2799              <div
2800                class="absolute top-full right-0"
2801                x-show="expanded"
2802                style="display: none;"
2803              >
2804                <form method="post" action="/localization" accept-charset="UTF-8" enctype="multipart/form-data">
2805                  <input type="hidden" name="form_type" value="localization">
2806                  <input type="hidden" name="utf8" value="✓">
2807                  <input type="hidden" name="_method" value="put">
2808                  <input type="hidden" name="return_to" value="/cart">
2809                  <ul
2810                    id="currency-list-header"
2811                    class="relative z-50 flex max-h-[30vh] w-max max-w-[theme(spacing.64)] snap-y snap-mandatory flex-col gap-[--text-border-width] overflow-y-auto border-text border-gridline-color bg-gridline-color text-base"
2812                    x-transition:enter="transition ease duration-300"
2813                    x-transition:enter-start="opacity-0"
2814                    x-transition:enter-end="opacity-100"
2815                    x-transition:leave="transition ease duration-300"
2816                    x-transition:leave-start="opacity-100"
2817                    x-transition:leave-end="opacity-0"
2818                    :aria-hidden="! expanded"
2819                  >
2820                    
2821                      <li class="flex items-center bg-scheme-background px-4 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
2822                        <button
2823                          class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
2824                          type="submit"
2825                          name="country_code"
2826                          value="AU"
2827                          
2828                        >
2829                          <span class="border-transparent border-b-text">AUD $<span class="ml-2 text-xs opacity-70">Australia</span></span
2830                          >
2831                        </button>
2832                      </li>
2833                      <li class="flex items-center bg-scheme-background px-4 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
2834                        <button
2835                          class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
2836                          type="submit"
2837                          name="country_code"
2838                          value="CN"
2839                          
2840                        >
2841                          <span class="border-transparent border-b-text">CNY ¥<span class="ml-2 text-xs opacity-70">China</span></span
2842                          >
2843                        </button>
2844                      </li>
2845                      <li class="flex items-center bg-scheme-background px-4 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
2846                        <button
2847                          class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
2848                          type="submit"
2849                          name="country_code"
2850                          value="FR"
2851                          
2852                        >
2853                          <span class="border-transparent border-b-text">EUR €<span class="ml-2 text-xs opacity-70">France</span></span
2854                          >
2855                        </button>
2856                      </li>
2857                      <li class="flex items-center bg-scheme-background px-4 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
2858                        <button
2859                          class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
2860                          type="submit"
2861                          name="country_code"
2862                          value="NZ"
2863                          
2864                        >
2865                          <span class="border-transparent border-b-text">NZD $<span class="ml-2 text-xs opacity-70">New Zealand</span></span
2866                          >
2867                        </button>
2868                      </li>
2869                      <li class="flex items-center bg-scheme-background px-4 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
2870                        <button
2871                          class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
2872                          type="submit"
2873                          name="country_code"
2874                          value="GB"
2875                          
2876                        >
2877                          <span class="border-transparent border-b-text">GBP £<span class="ml-2 text-xs opacity-70">United Kingdom</span></span
2878                          >
2879                        </button>
2880                      </li>
2881                      <li class="flex items-center bg-scheme-background px-4 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
2882                        <button
2883                          class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
2884                          type="submit"
2885                          name="country_code"
2886                          value="US"
2887                          
2888                            aria-current="true"
2889                          
2890                        >
2891                          <span class="border-scheme-text border-b-text">USD $<span class="ml-2 text-xs opacity-70">United States</span></span
2892                          >
2893                        </button>
2894                      </li></ul>
2895                </form>
2896              </div>
2897            </data-island>
2898          </div><div class="flex items-center whitespace-nowrap gap-2 lg:ml-4"><style>
2899  @keyframes quote-badge-pulse {
2900    0% { transform: scale(1); }
2901    50% { transform: scale(1.22); }
2902    100% { transform: scale(1); }
2903  }
2904
2905  @keyframes quote-icon-pulse {
2906    0% { transform: scale(1); }
2907    50% { transform: scale(1.12); }
2908    100% { transform: scale(1); }
2909  }
2910
2911  .quote-badge-animate {
2912    animation: quote-badge-pulse 0.4s ease-in-out;
2913  }
2914  .quote-icon-animate {
2915    animation: quote-icon-pulse 0.4s ease-in-out;
2916  }
2917  .quote-badge {
2918    min-width: 1.3rem;
2919    padding-inline: 0.22rem;
2920    box-shadow: 0 10px 24px rgba(43, 57, 144, 0.22);
2921  }
2922  .quote-tooltip {
2923    position: absolute;
2924    top: calc(100% + 8px);
2925    right: -10px;
2926    width: 152px;
2927    padding: 15px 16px;
2928    border-radius: 20px;
2929    font-size: 14px;
2930    font-style: italic;
2931    line-height: 17px;
2932    color: #000;
2933    background: #FBFBF6;
2934    border: 1px solid #000;
2935    box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.15);
2936    z-index: 1000;
2937    cursor: pointer;
2938    white-space: normal;
2939    text-align: left;
2940  }
2941  .quote-tooltip::before {
2942    content: '';
2943    position: absolute;
2944    top: -7px;
2945    right: 24px;
2946    width: 14px;
2947    height: 14px;
2948    background: #FBFBF6;
2949    border-top: 1px solid #000;
2950    border-left: 1px solid #000;
2951    transform: rotate(45deg);
2952  }
2953  @media (max-width: 640px) {
2954    .quote-tooltip {
2955      right: -10px;
2956    }
2957  }
2958</style>
2959
2960<div
2961  class="relative"
2962  x-data="{
2963    showTooltip: false,
2964    tooltipDismissed: false,
2965    animating: false,
2966    tooltipTimer: null,
2967    dismissTooltip() {
2968      this.showTooltip = false;
2969      this.tooltipDismissed = true;
2970      if (this.tooltipTimer) clearTimeout(this.tooltipTimer);
2971      if (this.tooltipDelayTimer) clearTimeout(this.tooltipDelayTimer);
2972    },
2973    tooltipDelayTimer: null,
2974    triggerTooltip() {
2975      try {
2976        if (this.tooltipDismissed || sessionStorage.getItem('psstShown')) return;
2977      } catch (error) {
2978        if (this.tooltipDismissed) return;
2979      }
2980      if (this.tooltipDelayTimer) clearTimeout(this.tooltipDelayTimer);
2981      this.tooltipDelayTimer = setTimeout(() => {
2982        if (this.tooltipDismissed) return;
2983        try { sessionStorage.setItem('psstShown', '1'); } catch(e) {}
2984        this.showTooltip = true;
2985        if (this.tooltipTimer) clearTimeout(this.tooltipTimer);
2986        this.tooltipTimer = setTimeout(() => { this.showTooltip = false; }, 15000);
2987      }, 5000);
2988    },
2989    pulseIcon() {
2990      this.animating = true;
2991      setTimeout(() => { this.animating = false; }, 450);
2992    }
2993  }"
2994  @quote-item-added.document="pulseIcon(); triggerTooltip()"
2995>
2996  <a
2997    href="/pages/general-quote"
2998    class="inline-flex min-h-10 items-center py-4 h-full"
2999    :role="`button`"
3000    :aria-expanded="$store.modals.rightDrawer.contents === 'favorites'"
3001    @click.prevent="$store.modals.open('favorites'); dismissTooltip(); window.dataLayer = window.dataLayer || []; window.dataLayer.push({ event: 'quote_drawer_opened', quote_count: $store.favorites.count, page_path: window.location.pathname })"
3002    @keydown.space.prevent="$store.modals.open('favorites'); dismissTooltip()"
3003    aria-label="Open your quote"
3004  ><div class="pointer-events-none relative my-auto align-middle" :class="{ 'quote-icon-animate': animating }"><span class="inline-block h-6 w-6 align-top [&_*]:pointer-events-none"><span class="h-full w-full">
3005  <svg
3006    aria-hidden="true"
3007    focusable="false"
3008    role="presentation"
3009    class="icon icon-quote-list-outline"
3010    viewBox="0 0 24 24"
3011    fill="none"
3012  ><rect x="3" y="1" width="18" height="22" rx="2.5" ry="2.5" stroke="currentColor" stroke-width="1.5"></rect><circle cx="7.5" cy="7.5" r="1" fill="currentColor"></circle>
3013    <line x1="10" y1="7.5" x2="17.5" y2="7.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></line>
3014    <circle cx="7.5" cy="11" r="1" fill="currentColor"></circle>
3015    <line x1="10" y1="11" x2="17.5" y2="11" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></line>
3016    <circle cx="7.5" cy="14.5" r="1" fill="currentColor"></circle>
3017    <line x1="10" y1="14.5" x2="17.5" y2="14.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></line>
3018    <circle cx="7.5" cy="18" r="1" fill="currentColor"></circle>
3019    <line x1="10" y1="18" x2="17.5" y2="18" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></line>
3020  </svg>
3021</span>
3022</span><span
3023          x-show="$store.favorites.count > 0"
3024          x-cloak
3025          class="quote-badge absolute flex items-center justify-center rounded-full text-[10px] font-bold"
3026          style="background-color: #4B4D72; color: #fff; width: 18px; height: 18px; top: -7px; right: -8px;"
3027          :class="{ 'quote-badge-animate': animating }"
3028          x-text="$store.favorites.count"
3029        ></span>
3030        <span class="sr-only" x-text="'Your Quote: ' + $store.favorites.countWithText()">
3031          Your Quote: 0 items
3032        </span>
3033      </div></a><div
3034    x-show="showTooltip"
3035    x-transition:enter="transition ease-out duration-200"
3036    x-transition:enter-start="opacity-0 translate-y-1"
3037    x-transition:enter-end="opacity-100 translate-y-0"
3038    x-transition:leave="transition ease-in duration-150"
3039    x-transition:leave-start="opacity-100"
3040    x-transition:leave-end="opacity-0"
3041    x-cloak
3042    class="quote-tooltip"
3043    @click="dismissTooltip()"
3044  >
3045    Hi, your favourite products are here.
3046  </div>
3047</div>
3048
3049  <a
3050    href="/cart"
3051    class="inline-flex py-4 h-full"
3052    
3053  ><div class="pointer-events-none relative my-auto align-middle">
3054        <span
3055          x-show="$store.cartCount.count > 0"
3056          class="absolute right-0 top-1 h-2 w-2 rounded-full"
3057          style="background-color: #f1ffa5;"
3058        ></span>
3059        <span class="inline-block h-6 w-6 fill-current align-top [&_*]:pointer-events-none"><svg
3060  class="theme-icon"
3061  xmlns="http://www.w3.org/2000/svg"
3062  fill="none"
3063  viewBox="0 0 24 24"
3064>
3065  <path stroke="currentColor" d="M2 7h20v15H2V7Zm15 0v-.2A4.8 4.8 0 0 0 12.2 2h-.4A4.8 4.8 0 0 0 7 6.8V7" vector-effect="non-scaling-stroke"/>
3066</svg>
3067</span>
3068        <span class="sr-only" x-text="$store.cartCount.countWithText()">
3069          
30700 items
3071        </span>
3072      </div></a>
3073          </div>
3074        </div>
3075      </div>
3076    </nav>
3077  </header>
3078</data-island><noscript>
3079  <style data-shopify>
3080    .no-js-focus-wrapper:focus-within .no-js-focus-container {
3081      display: block !important;
3082    }
3083
3084    </style>
3085</noscript>
3086
3087<style>
3088  /* ── Get Started pill + dropdown ── */
3089  .gs-pill {
3090    display: inline-flex;
3091    align-items: center;
3092    padding: 0 20px;
3093    height: 39px;
3094    border: 1px solid #2a3a8e;
3095    border-radius: 40px;
3096    background: transparent;
3097    color: #2a3a8e;
3098    font-size: 17.3px;
3099    font-family: 'DM Sans', sans-serif;
3100    font-weight: 400;
3101    line-height: 24px;
3102    cursor: pointer;
3103    white-space: nowrap;
3104    transition: background-color 0.25s ease, color 0.25s ease;
3105  }
3106
3107  .gs-pill:hover,
3108  .gs-pill.is-active {
3109    background-color: #2b3990;
3110    color: #f9fafb;
3111  }
3112
3113  .gs-dropdown-content {
3114    display: flex;
3115    flex-direction: column;
3116    gap: 6px;
3117    padding: 10px 20px 14px;
3118    left: 0;
3119  }
3120
3121  .gs-dropdown-content a {
3122    color: #2a3a8e;
3123    font-size: 17.3px;
3124    font-family: 'DM Sans', sans-serif;
3125    font-weight: 400;
3126    text-decoration: none;
3127    white-space: nowrap;
3128    line-height: 32px;
3129  }
3130
3131  .gs-dropdown-content a:hover {
3132    opacity: 0.7;
3133  }
3134
3135  /* Nav dropdowns (e.g. "Our story") nudged left to sit under the menu label */
3136  .nav-dropdown-content {
3137    left: -12px;
3138  }
3139
3140  .quote-pill-button {
3141    display: inline-block;
3142    padding: 1rem 2rem;
3143    border-radius: 9999px;
3144    cursor: pointer;
3145    border: 0;
3146    background-color: #f1ffa5;
3147    transition: all 0.5s ease;
3148    color: #1F2937;
3149    text-decoration: none;
3150    font-weight: 600;
3151    font-size: 1.1em;
3152  }
3153
3154  .quote-pill-button:hover {
3155    transform: scale(1.2);
3156  }
3157
3158  .quote-pill-button:active {
3159    transform: scale(1.07);
3160    transition: 100ms;
3161  }
3162
3163  .start-design-button {
3164    display: inline-block;
3165    padding: 1rem 2rem;
3166    border-radius: 9999px;
3167    cursor: pointer;
3168    border: 0;
3169    background-color: #2b3990;
3170    transition: all 0.5s ease;
3171    color: #ffffff;
3172    text-decoration: none;
3173    font-weight: 600;
3174    font-size: 1.1em;
3175  }
3176
3177  .start-design-button:hover {
3178    transform: scale(1.2);
3179  }
3180
3181  .start-design-button:active {
3182    transform: scale(1.07);
3183    transition: 100ms;
3184  }
3185
3186  @keyframes float {
3187    0%, 100% {
3188      transform: translateY(0px);
3189    }
3190    50% {
3191      transform: translateY(-6px);
3192    }
3193  }
3194
3195  .beta-badge {
3196    position: absolute;
3197    top: -8px;
3198    right: -8px;
3199    background-color: #f1ffa5;
3200    color: #1e2326;
3201    font-size: 0.65em;
3202    font-weight: 700;
3203    padding: 0.25rem 0.5rem;
3204    border-radius: 9999px;
3205    text-transform: uppercase;
3206    letter-spacing: 0.5px;
3207    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
3208    z-index: 10;
3209    animation: float 2s ease-in-out infinite;
3210  }
3211</style>
3212
3213
3214
3215  
3215<script>
3216  if (!customElements.get('sticky-header-height-helper')) {
3217    class StickyHeaderHeightHelper extends HTMLElement {
3218      constructor() {
3219        super();
3220      }
3221
3222      connectedCallback() {
3223        const headerEl = this.closest('[data-theme-header]');
3224
3225        if (headerEl && headerEl.getAttribute('data-sticky')) {
3226          document.documentElement.style.setProperty(
3227            '--sticky-header-height',
3228            `${headerEl.getBoundingClientRect().height}px`
3229          );
3230        } else {
3231          
3232          document.documentElement.style.setProperty(
3233            '--sticky-header-height',
3234            '0px'
3235          );
3236        }
3237      }
3238    }
3239
3240    customElements.define(
3241      'sticky-header-height-helper',
3242      StickyHeaderHeightHelper
3243    );
3244  }
3245  </script>
3245
3246
3247
3248<style> #shopify-section-sections--21296457187398__header .bg-scheme-background {border-bottom: 1px solid #2b3990;} </style></div>
3249<!-- END sections: header-group -->
3250<div id="shopify-section-menu-drawer" class="shopify-section">
3251
3252<data-island
3253  
3254    x-data
3255  
3256  x-init="initTeleport($root); $store.modals.register('sidebar', 'leftDrawer');"
3257  on="idle"
3258>
3259  <template data-should-teleport="#left-drawer-slot">
3260    <template
3261      id="sidebar"
3262      x-if="$store.modals.leftDrawer.contents === 'sidebar'"
3263    >
3264      
3265  <div
3266    
3267    data-modal-label="Menu"
3268  >
3269    <div class="sticky top-0 z-1 flex items-center justify-between border-b-gridline border-gridline-color px-section-horizontal-spacing py-4">
3270      <div aria-hidden="true">&nbsp;</div>
3271      <button
3272        @click.prevent="$store.modals.close('sidebar')"
3273        class="absolute right-0 top-0 block h-full"
3274        type="button"
3275      >
3276        <span class="sr-only">Close</span>
3277        <div class="my-auto mr-section-horizontal-spacing h-6 w-6"><svg
3278  class="theme-icon"
3279  xmlns="http://www.w3.org/2000/svg"
3280  fill="none"
3281  viewBox="0 0 24 24"
3282>
3283  <path stroke="currentColor" d="m1.5 1.5 21 21m0-21-21 21" vector-effect="non-scaling-stroke"/>
3284</svg>
3285</div>
3286      </button>
3287    </div>
3288    <nav
3289      
3290      aria-label="Primary"
3291    >
3292      <ul><li
3293            class="no-js-focus-wrapper break-word px-section-horizontal-spacing border-t-gridline border-gridline-color first-of-type:border-t-0"
3294          ><a class="inline-block py-4 w-full text-heading-standard" href="/collections/product-library">
3295                Products
3296              </a></li><li
3297            class="no-js-focus-wrapper break-word px-section-horizontal-spacing border-t-gridline border-gridline-color first-of-type:border-t-0"
3298          ><data-island class="contents" x-data="{ expanded: false }"><button
3299                  class="relative block w-full text-left inline-block py-4 w-full text-heading-standard ease pr-10 transition font-body"
3300                  x-bind:aria-expanded="expanded ? true : 'false'"
3301                  @click="expanded = ! expanded"
3302                  aria-controls="accordion0"
3303                >
3304                  Services
3305                  <span class="absolute right-0 top-1/2 flex h-6 w-6 -translate-y-1/2 transform items-center"><span
3306                        class="inline-block w-full origin-center"
3307                        x-show="!expanded"
3308                      ><svg
3309  class="theme-icon"
3310  xmlns="http://www.w3.org/2000/svg"
3311  fill="none"
3312  viewBox="0 0 24 24"
3313>
3314  <path stroke="currentColor" d="M12 1v22M1 12h22" vector-effect="non-scaling-stroke"/>
3315</svg>
3316</span>
3317                      <span
3318                        class="inline-block w-full origin-center"
3319                        x-show="expanded"
3320                        style="display: none;"
3321                      ><svg
3322  class="theme-icon"
3323  xmlns="http://www.w3.org/2000/svg"
3324  fill="none"
3325  viewBox="0 0 24 24"
3326>
3327  <path stroke="currentColor" d="M1 12h22" vector-effect="non-scaling-stroke"/>
3328</svg>
3329</span></span>
3330                </button>
3331                <ul
3332                  id="accordion0"
3333                  class="no-js-focus-container pb-2 pl-4"
3334                  x-show="expanded"
3335                  x-cloak
3336                ><li class="no-js-focus-wrapper"><data-island class="contents" x-data="{ expanded: false }" >
3337                          <button
3338                            class="relative w-full text-left inline-block py-1  pr-10"
3339                            x-bind:aria-expanded="expanded ? true : 'false'"
3340                            @click="expanded = ! expanded"
3341                            aria-controls="accordion1"
3342                          >
3343                            Production capabilities
3344                            <span class="absolute right-0 top-1/2 flex h-6 w-6 -translate-y-1/2 transform items-center"><span
3345                                  class="inline-block w-full origin-center"
3346                                  x-show="!expanded"
3347                                ><svg
3348  class="theme-icon"
3349  xmlns="http://www.w3.org/2000/svg"
3350  fill="none"
3351  viewBox="0 0 24 24"
3352>
3353  <path stroke="currentColor" d="M12 1v22M1 12h22" vector-effect="non-scaling-stroke"/>
3354</svg>
3355</span>
3356                                <span
3357                                  class="inline-block w-full origin-center"
3358                                  x-show="expanded"
3359                                  style="display: none;"
3360                                ><svg
3361  class="theme-icon"
3362  xmlns="http://www.w3.org/2000/svg"
3363  fill="none"
3364  viewBox="0 0 24 24"
3365>
3366  <path stroke="currentColor" d="M1 12h22" vector-effect="non-scaling-stroke"/>
3367</svg>
3368</span></span>
3369                          </button>
3370                          <ul
3371                            id="accordion1"
3372                            class="no-js-focus-container px-2 pb-2 pt-1"
3373                            x-show="expanded"
3374                            x-cloak
3375                          ><li>
3376                                <a
3377                                  class="inline-block py-1 "
3378                                  href="/pages/custom-manufactured"
3379                                >
3380                                  Custom-manufactured
3381                                </a>
3382                              </li><li>
3383                                <a
3384                                  class="inline-block py-1 "
3385                                  href="/pages/screen-printing"
3386                                >
3387                                  Screen printing
3388                                </a>
3389                              </li><li>
3390                                <a
3391                                  class="inline-block py-1 "
3392                                  href="/pages/embroidery"
3393                                >
3394                                  Embroidery
3395                                </a>
3396                              </li><li>
3397                                <a
3398                                  class="inline-block py-1 "
3399                                  href="/pages/heat-transfers"
3400                                >
3401                                  Heat transfers
3402                                </a>
3403                              </li><li>
3404                                <a
3405                                  class="inline-block py-1 "
3406                                  href="/pages/finishing"
3407                                >
3408                                  Finishing
3409                                </a>
3410                              </li></ul>
3411                        </data-island></li><li class="no-js-focus-wrapper"><data-island class="contents" x-data="{ expanded: false }" >
3412                          <button
3413                            class="relative w-full text-left inline-block py-1  pr-10"
3414                            x-bind:aria-expanded="expanded ? true : 'false'"
3415                            @click="expanded = ! expanded"
3416                            aria-controls="accordion2"
3417                          >
3418                            Partner services
3419                            <span class="absolute right-0 top-1/2 flex h-6 w-6 -translate-y-1/2 transform items-center"><span
3420                                  class="inline-block w-full origin-center"
3421                                  x-show="!expanded"
3422                                ><svg
3423  class="theme-icon"
3424  xmlns="http://www.w3.org/2000/svg"
3425  fill="none"
3426  viewBox="0 0 24 24"
3427>
3428  <path stroke="currentColor" d="M12 1v22M1 12h22" vector-effect="non-scaling-stroke"/>
3429</svg>
3430</span>
3431                                <span
3432                                  class="inline-block w-full origin-center"
3433                                  x-show="expanded"
3434                                  style="display: none;"
3435                                ><svg
3436  class="theme-icon"
3437  xmlns="http://www.w3.org/2000/svg"
3438  fill="none"
3439  viewBox="0 0 24 24"
3440>
3441  <path stroke="currentColor" d="M1 12h22" vector-effect="non-scaling-stroke"/>
3442</svg>
3443</span></span>
3444                          </button>
3445                          <ul
3446                            id="accordion2"
3447                            class="no-js-focus-container px-2 pb-2 pt-1"
3448                            x-show="expanded"
3449                            x-cloak
3450                          ><li>
3451                                <a
3452                                  class="inline-block py-1 "
3453                                  href="/pages/client-portal"
3454                                >
3455                                  Client portal
3456                                </a>
3457                              </li><li>
3458                                <a
3459                                  class="inline-block py-1 "
3460                                  href="/pages/fundraising-pre-orders"
3461                                >
3462                                  Fundraise & pre-order
3463                                </a>
3464                              </li><li>
3465                                <a
3466                                  class="inline-block py-1 "
3467                                  href="/pages/repurpose-initiative"
3468                                >
3469                                  Repurpose initiative
3470                                </a>
3471                              </li></ul>
3472                        </data-island></li><li class="no-js-focus-wrapper"><data-island class="contents" x-data="{ expanded: false }" >
3473                          <button
3474                            class="relative w-full text-left inline-block py-1  pr-10"
3475                            x-bind:aria-expanded="expanded ? true : 'false'"
3476                            @click="expanded = ! expanded"
3477                            aria-controls="accordion3"
3478                          >
3479                            Popular services
3480                            <span class="absolute right-0 top-1/2 flex h-6 w-6 -translate-y-1/2 transform items-center"><span
3481                                  class="inline-block w-full origin-center"
3482                                  x-show="!expanded"
3483                                ><svg
3484  class="theme-icon"
3485  xmlns="http://www.w3.org/2000/svg"
3486  fill="none"
3487  viewBox="0 0 24 24"
3488>
3489  <path stroke="currentColor" d="M12 1v22M1 12h22" vector-effect="non-scaling-stroke"/>
3490</svg>
3491</span>
3492                                <span
3493                                  class="inline-block w-full origin-center"
3494                                  x-show="expanded"
3495                                  style="display: none;"
3496                                ><svg
3497  class="theme-icon"
3498  xmlns="http://www.w3.org/2000/svg"
3499  fill="none"
3500  viewBox="0 0 24 24"
3501>
3502  <path stroke="currentColor" d="M1 12h22" vector-effect="non-scaling-stroke"/>
3503</svg>
3504</span></span>
3505                          </button>
3506                          <ul
3507                            id="accordion3"
3508                            class="no-js-focus-container px-2 pb-2 pt-1"
3509                            x-show="expanded"
3510                            x-cloak
3511                          ><li>
3512                                <a
3513                                  class="inline-block py-1 "
3514                                  href="/pages/school-leavers-gear"
3515                                >
3516                                  School leavers gear
3517                                </a>
3518                              </li><li>
3519                                <a
3520                                  class="inline-block py-1 "
3521                                  href="/pages/tshirt-printing"
3522                                >
3523                                  Custom t-shirt printing
3524                                </a>
3525                              </li></ul>
3526                        </data-island></li></ul>
3527              </data-island></li><li
3528            class="no-js-focus-wrapper break-word px-section-horizontal-spacing border-t-gridline border-gridline-color first-of-type:border-t-0"
3529          ><a class="inline-block py-4 w-full text-heading-standard" href="/pages/responsibility">
3530                Responsibility
3531              </a></li><li
3532            class="no-js-focus-wrapper break-word px-section-horizontal-spacing border-t-gridline border-gridline-color first-of-type:border-t-0"
3533          ><data-island class="contents" x-data="{ expanded: false }"><button
3534                  class="relative block w-full text-left inline-block py-4 w-full text-heading-standard ease pr-10 transition font-body"
3535                  x-bind:aria-expanded="expanded ? true : 'false'"
3536                  @click="expanded = ! expanded"
3537                  aria-controls="accordion4"
3538                >
3539                  Our story
3540                  <span class="absolute right-0 top-1/2 flex h-6 w-6 -translate-y-1/2 transform items-center"><span
3541                        class="inline-block w-full origin-center"
3542                        x-show="!expanded"
3543                      ><svg
3544  class="theme-icon"
3545  xmlns="http://www.w3.org/2000/svg"
3546  fill="none"
3547  viewBox="0 0 24 24"
3548>
3549  <path stroke="currentColor" d="M12 1v22M1 12h22" vector-effect="non-scaling-stroke"/>
3550</svg>
3551</span>
3552                      <span
3553                        class="inline-block w-full origin-center"
3554                        x-show="expanded"
3555                        style="display: none;"
3556                      ><svg
3557  class="theme-icon"
3558  xmlns="http://www.w3.org/2000/svg"
3559  fill="none"
3560  viewBox="0 0 24 24"
3561>
3562  <path stroke="currentColor" d="M1 12h22" vector-effect="non-scaling-stroke"/>
3563</svg>
3564</span></span>
3565                </button>
3566                <ul
3567                  id="accordion4"
3568                  class="no-js-focus-container pb-2 pl-4"
3569                  x-show="expanded"
3570                  x-cloak
3571                ><li class="no-js-focus-wrapper"><a
3572                          class="inline-block py-1 "
3573                          href="/pages/in-good-company-with"
3574                        >
3575                          In good company with…
3576                        </a></li><li class="no-js-focus-wrapper"><a
3577                          class="inline-block py-1 "
3578                          href="/pages/about-print-room"
3579                        >
3580                          Our origins
3581                        </a></li></ul>
3582              </data-island></li><li
3583            class="no-js-focus-wrapper break-word px-section-horizontal-spacing border-t-gridline border-gr
3583idline-color first-of-type:border-t-0"
3584          ><data-island class="contents" x-data="{ expanded: false }"><button
3585                  class="relative block w-full text-left inline-block py-4 w-full text-heading-standard ease pr-10 transition font-body"
3586                  x-bind:aria-expanded="expanded ? true : 'false'"
3587                  @click="expanded = ! expanded"
3588                  aria-controls="accordion5"
3589                >
3590                  Get started
3591                  <span class="absolute right-0 top-1/2 flex h-6 w-6 -translate-y-1/2 transform items-center"><span
3592                        class="inline-block w-full origin-center"
3593                        x-show="!expanded"
3594                      ><svg
3595  class="theme-icon"
3596  xmlns="http://www.w3.org/2000/svg"
3597  fill="none"
3598  viewBox="0 0 24 24"
3599>
3600  <path stroke="currentColor" d="M12 1v22M1 12h22" vector-effect="non-scaling-stroke"/>
3601</svg>
3602</span>
3603                      <span
3604                        class="inline-block w-full origin-center"
3605                        x-show="expanded"
3606                        style="display: none;"
3607                      ><svg
3608  class="theme-icon"
3609  xmlns="http://www.w3.org/2000/svg"
3610  fill="none"
3611  viewBox="0 0 24 24"
3612>
3613  <path stroke="currentColor" d="M1 12h22" vector-effect="non-scaling-stroke"/>
3614</svg>
3615</span></span>
3616                </button>
3617                <ul
3618                  id="accordion5"
3619                  class="no-js-focus-container pb-2 pl-4"
3620                  x-show="expanded"
3621                  x-cloak
3622                ><li class="no-js-focus-wrapper"><a
3623                          class="inline-block py-1 "
3624                          href="/collections/product-library"
3625                        >
3626                          Start a project
3627                        </a></li><li class="no-js-focus-wrapper"><a
3628                          class="inline-block py-1 "
3629                          href="/pages/book-a-call"
3630                        >
3631                          Book a call
3632                        </a></li></ul>
3633              </data-island></li></ul>
3634    </nav>
3635    <div class="border-t-gridline border-gridline-color">
3636      <nav class="my-6" aria-label="Secondary">
3637        <ul></ul>
3638      </nav>
3639
3640      
3641        <div class="my-6 px-section-horizontal-spacing">
3642          <form method="post" action="/localization" id="sidebar-localization-form" accept-charset="UTF-8" class="shopify-localization-form" enctype="multipart/form-data"><input type="hidden" name="form_type" value="localization" /><input type="hidden" name="utf8" value="✓" /><input type="hidden" name="_method" value="put" /><input type="hidden" name="return_to" value="/cart" /><div class="flex gap-4 flex-col gap-y-0"><div class="inline-block shrink-0 select-none">
3643        <h2 class="sr-only" id="country-heading-sidebar">
3644          Country/region
3645        </h2>
3646        <data-island
3647          class="relative"
3648          x-data="{ expanded: false }"
3649          @keydown.escape.prevent.stop="expanded = false"
3650          @click.outside="expanded = false"
3651        >
3652          <button
3653            type="button"
3654            class="text-base py-2"
3655            :aria-expanded="expanded"
3656            aria-controls="country-list-sidebar"
3657            aria-describedby="country-heading-sidebar"
3658            @click.prevent="expanded = ! expanded"
3659          >
3660            United States (USD
3661            $)
3662            <span
3663              class="rotate ml-1 inline-block w-3 origin-center transform fill-current transition"
3664              :class="{ 'rotate-180': expanded }"
3665            >
3666              <svg
3667  class="theme-icon"
3668  xmlns="http://www.w3.org/2000/svg"
3669  fill="none"
3670  viewBox="0 0 24 24"
3671>
3672  <path stroke="currentColor" d="M1.5 7 12 17.5 22.5 7" vector-effect="non-scaling-stroke"/>
3673</svg>
3674
3675            </span>
3676          </button>
3677          <div
3678            class="absolute bottom-[calc(100%_+_0.5rem)] right-auto left-0"
3679            x-show="expanded"
3680            style="display: none;"
3681          >
3682            <ul
3683              id="country-list-sidebar"
3684              class="relative z-10 flex max-h-[30vh] w-max max-w-[theme(spacing.52)] snap-y snap-mandatory flex-col gap-[--text-border-width] overflow-y-auto border-text border-gr
3684idline-color bg-gridline-color text-base"
3685              x-transition:enter="transition ease duration-300"
3686              x-transition:enter-start="opacity-0"
3687              x-transition:enter-end="opacity-100"
3688              x-transition:leave="transition ease duration-300"
3689              x-transition:leave-start="opacity-100"
3690              x-transition:leave-end="opacity-0"
3691              :aria-hidden="! expanded"
3692            >
3693              
3694                <li class="flex items-center bg-scheme-background px-2 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
3695                  <button
3696                    class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
3697                    type="button"
3698                    
3699                    @click.prevent="$refs.input.value = 'AU'; $root.closest('form').submit();"
3700                  >
3701                    <span class="border-transparent border-b-text">Australia (AUD
3702                      $)</span
3703                    >
3704                  </button>
3705                </li>
3706                <li class="flex items-center bg-scheme-background px-2 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
3707                  <button
3708                    class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
3709                    type="button"
3710                    
3711                    @click.prevent="$refs.input.value = 'CN'; $root.closest('form').submit();"
3712                  >
3713                    <span class="border-transparent border-b-text">China (CNY
3714                      ¥)</span
3715                    >
3716                  </button>
3717                </li>
3718                <li class="flex items-center bg-scheme-background px-2 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
3719                  <button
3720                    class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
3721                    type="button"
3722                    
3723                    @click.prevent="$refs.input.value = 'FR'; $root.closest('form').submit();"
3724                  >
3725                    <span class="border-transparent border-b-text">France (EUR
3726                      €)</span
3727                    >
3728                  </button>
3729                </li>
3730                <li class="flex items-center bg-scheme-background px-2 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
3731                  <button
3732                    class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
3733                    type="button"
3734                    
3735                    @click.prevent="$refs.input.value = 'NZ'; $root.closest('form').submit();"
3736                  >
3737                    <span class="border-transparent border-b-text">New Zealand (NZD
3738                      $)</span
3739                    >
3740                  </button>
3741                </li>
3742                <li class="flex items-center bg-scheme-background px-2 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
3743                  <button
3744                    class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
3745                    type="button"
3746                    
3747                    @click.prevent="$refs.input.value = 'GB'; $root.closest('form').submit();"
3748                  >
3749                    <span class="border-transparent border-b-text">United Kingdom (GBP
3750                      £)</span
3751                    >
3752                  </button>
3753                </li>
3754                <li class="flex items-center bg-scheme-background px-2 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
3755                  <button
3756                    class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
3757                    type="button"
3758                    
3759                      aria-current="true"
3760                    
3761                    @click.prevent="$refs.input.value = 'US'; $root.closest('form').submit();"
3762                  >
3763                    <span class="border-scheme-text border-b-text">United States (USD
3764                      $)</span
3765                    >
3766                  </button>
3767                </li></ul>
3768          </div>
3769
3770          <input
3771            x-ref="input"
3772            type="hidden"
3773            name="country_code"
3774            id="CountrySelector"
3775            value="US"
3776          >
3777        </data-island>
3778      </div></div></form>
3779        </div>
3780      
3781
3782      
3783<form
3784          class="my-6 px-section-horizontal-spacing"
3785          action="/search"
3786          method="get"
3787          role="search"
3788        >
3789          <div class="flex w-full max-w-xs items-end">
3790            <label for="menu-drawer-search" class="sr-only">Search</label>
3791            <input
3792              class="min-w-0 flex-auto border-b-text border-current bg-transparent py-1.5 placeholder-current"
3793              id="menu-drawer-search"
3794              type="text"
3795              name="q"
3796              placeholder="Search"
3797            >
3798            <button
3799              class="px-1"
3800              type="submit"
3801            >
3802              <span class="inline-block h-6 w-6"><svg
3803  class="theme-icon"
3804  xmlns="http://www.w3.org/2000/svg"
3805  fill="none"
3806  viewBox="0 0 24 24"
3807>
3808  <path stroke="currentColor" d="M2 11a9 9 0 1 0 18 0 9 9 0 0 0-18 0Zm15.364 6.364L22 22" vector-effect="non-scaling-stroke"/>
3809</svg>
3810</span>
3811              <span class="sr-only">Submit</span>
3812            </button>
3813          </div>
3814        </form>
3815    </div>
3816  </div>
3817
3818    </template>
3819  </template>
3820</data-island>
3821
3822<noscript>
3823  <section class="section-sidebar">
3824    <div class="px-section-horizontal-spacing py-2 text-right">
3825      <button
3826        class="inline-flex items-center justify-center py-2 "
3827        data-menu-drawer-toggle
3828      >
3829        <span class="mr-2 inline-block h-6 w-6 align-middle"><svg
3830  class="theme-icon"
3831  xmlns="http://www.w3.org/2000/svg"
3832  fill="none"
3833  viewBox="0 0 24 24"
3834>
3835  <path stroke="currentColor" d="M1 4.545h22M1 12h22M1 19.455h22" vector-effect="non-scaling-stroke"/>
3836</svg>
3837</span>
3838        <span>Menu</span>
3839      </button>
3840    </div>
3841    <div class="sidebar-container z-80 border-r-grid border-grid-color fixed bottom-0 left-0 top-0 w-11/12 max-w-xl transform overflow-y-auto bg-scheme-background text-scheme-text transition-transform">
3842      
3843  <div
3844    
3845    data-modal-label="Menu"
3846  >
3847    <div class="sticky top-0 z-1 flex items-center justify-between border-b-gridline border-gridline-color px-section-horizontal-spacing py-4">
3848      <div aria-hidden="true">&nbsp;</div>
3849      <button
3850        @click.prevent="$store.modals.close('sidebar')"
3851        class="absolute right-0 top-0 block h-full"
3852        type="button"
3853      >
3854        <span class="sr-only">Close</span>
3855        <div class="my-auto mr-section-horizontal-spacing h-6 w-6"><svg
3856  class="theme-icon"
3857  xmlns="http://www.w3.org/2000/svg"
3858  fill="none"
3859  viewBox="0 0 24 24"
3860>
3861  <path stroke="currentColor" d="m1.5 1.5 21 21m0-21-21 21" vector-effect="non-scaling-stroke"/>
3862</svg>
3863</div>
3864      </button>
3865    </div>
3866    <nav
3867      
3868      aria-label="Primary"
3869    >
3870      <ul><li
3871            class="no-js-focus-wrapper break-word px-section-horizontal-spacing border-t-gridline border-gridline-color first-of-type:border-t-0"
3872          ><a class="inline-block py-4 w-full text-heading-standard" href="/collections/product-library">
3873                Products
3874              </a></li><li
3875            class="no-js-focus-wrapper break-word px-section-horizontal-spacing border-t-gridline border-gridline-color first-of-type:border-t-0"
3876          ><data-island class="contents" x-data="{ expanded: false }"><button
3877                  class="relative block w-full text-left inline-block py-4 w-full text-heading-standard ease pr-10 transition font-body"
3878                  x-bind:aria-expanded="expanded ? true : 'false'"
3879                  @click="expanded = ! expanded"
3880                  aria-controls="accordion0"
3881                >
3882                  Services
3883                  <span class="absolute right-0 top-1/2 flex h-6 w-6 -translate-y-1/2 transform items-center"><span
3884                        class="inline-block w-full origin-center"
3885                        x-show="!expanded"
3886                      ><svg
3887  class="theme-icon"
3888  xmlns="http://www.w3.org/2000/svg"
3889  fill="none"
3890  viewBox="0 0 24 24"
3891>
3892  <path stroke="currentColor" d="M12 1v22M1 12h22" vector-effect="non-scaling-stroke"/>
3893</svg>
3894</span>
3895                      <span
3896                        class="inline-block w-full origin-center"
3897                        x-show="expanded"
3898                        style="display: none;"
3899                      ><svg
3900  class="theme-icon"
3901  xmlns="http://www.w3.org/2000/svg"
3902  fill="none"
3903  viewBox="0 0 24 24"
3904>
3905  <path stroke="currentColor" d="M1 12h22" vector-effect="non-scaling-stroke"/>
3906</svg>
3907</span></span>
3908                </button>
3909                <ul
3910                  id="accordion0"
3911                  class="no-js-focus-container pb-2 pl-4"
3912                  x-show="expanded"
3913                  x-cloak
3914                ><li class="no-js-focus-wrapper"><data-island class="contents" x-data="{ expanded: false }" >
3915                          <button
3916                            class="relative w-full text-left inline-block py-1  pr-10"
3917                            x-bind:aria-expanded="expanded ? true : 'false'"
3918                            @click="expanded = ! expanded"
3919                            aria-controls="accordion1"
3920                          >
3921                            Production capabilities
3922                            <span class="absolute right-0 top-1/2 flex h-6 w-6 -translate-y-1/2 transform items-center"><span
3923                                  class="inline-block w-full origin-center"
3924                                  x-show="!expanded"
3925                                ><svg
3926  class="theme-icon"
3927  xmlns="http://www.w3.org/2000/svg"
3928  fill="none"
3929  viewBox="0 0 24 24"
3930>
3931  <path stroke="currentColor" d="M12 1v22M1 12h22" vector-effect="non-scaling-stroke"/>
3932</svg>
3933</span>
3934                                <span
3935                                  class="inline-block w-full origin-center"
3936                                  x-show="expanded"
3937                                  style="display: none;"
3938                                ><svg
3939  class="theme-icon"
3940  xmlns="http://www.w3.org/2000/svg"
3941  fill="none"
3942  viewBox="0 0 24 24"
3943>
3944  <path stroke="currentColor" d="M1 12h22" vector-effect="non-scaling-stroke"/>
3945</svg>
3946</span></span>
3947                          </button>
3948                          <ul
3949                            id="accordion1"
3950                            class="no-js-focus-container px-2 pb-2 pt-1"
3951                            x-show="expanded"
3952                            x-cloak
3953                          ><li>
3954                                <a
3955                                  class="inline-block py-1 "
3956                                  href="/pages/custom-manufactured"
3957                                >
3958                                  Custom-manufactured
3959                                </a>
3960                              </li><li>
3961                                <a
3962                                  class="inline-block py-1 "
3963                                  href="/pages/screen-printing"
3964                                >
3965                                  Screen printing
3966                                </a>
3967                              </li><li>
3968                                <a
3969                                  class="inline-block py-1 "
3970                                  href="/pages/embroidery"
3971                                >
3972                                  Embroidery
3973                                </a>
3974                              </li><li>
3975                                <a
3976                                  class="inline-block py-1 "
3977                                  href="/pages/heat-transfers"
3978                                >
3979                                  Heat transfers
3980                                </a>
3981                              </li><li>
3982                                <a
3983                                  class="inline-block py-1 "
3984                                  href="/pages/finishing"
3985                                >
3986                                  Finishing
3987                                </a>
3988                              </li></ul>
3989                        </data-island></li><li class="no-js-focus-wrapper"><data-island class="contents" x-data="{ expanded: false }" >
3990                          <button
3991                            class="relative w-full text-left inline-block py-1  pr-10"
3992                            x-bind:aria-expanded="expanded ? true : 'false'"
3993                            @click="expanded = ! expanded"
3994                            aria-controls="accordion2"
3995                          >
3996                            Partner services
3997                            <span class="absolute right-0 top-1/2 flex h-6 w-6 -translate-y-1/2 transform items-center"><span
3998                                  class="inline-block w-full origin-center"
3999                                  x-show="!expanded"
4000                                ><svg
4001  class="theme-icon"
4002  xmlns="http://www.w3.org/2000/svg"
4003  fill="none"
4004  viewBox="0 0 24 24"
4005>
4006  <path stroke="currentColor" d="M12 1v22M1 12h22" vector-effect="non-scaling-stroke"/>
4007</svg>
4008</span>
4009                                <span
4010                                  class="inline-block w-full origin-center"
4011                                  x-show="expanded"
4012                                  style="display: none;"
4013                                ><svg
4014  class="theme-icon"
4015  xmlns="http://www.w3.org/2000/svg"
4016  fill="none"
4017  viewBox="0 0 24 24"
4018>
4019  <path stroke="currentColor" d="M1 12h22" vector-effect="non-scaling-stroke"/>
4020</svg>
4021</span></span>
4022                          </button>
4023                          <ul
4024                            id="accordion2"
4025                            class="no-js-focus-container px-2 pb-2 pt-1"
4026                            x-show="expanded"
4027                            x-cloak
4028                          ><li>
4029                                <a
4030                                  class="inline-block py-1 "
4031                                  href="/pages/client-portal"
4032                                >
4033                                  Client portal
4034                                </a>
4035                              </li><li>
4036                                <a
4037                                  class="inline-block py-1 "
4038                                  href="/pages/fundraising-pre-orders"
4039                                >
4040                                  Fundraise & pre-order
4041                                </a>
4042                              </li><li>
4043                                <a
4044                                  class="inline-block py-1 "
4045                                  href="/pages/repurpose-initiative"
4046                                >
4047                                  Repurpose initiative
4048                                </a>
4049                              </li></ul>
4050                        </data-island></li><li class="no-js-focus-wrapper"><data-island class="contents" x-data="{ expanded: false }" >
4051                          <button
4052                            class="relative w-full text-left inline-block py-1  pr-10"
4053                            x-bind:aria-expanded="expanded ? true : 'false'"
4054                            @click="expanded = ! expanded"
4055                            aria-controls="accordion3"
4056                          >
4057                            Popular services
4058                            <span class="absolute right-0 top-1/2 flex h-6 w-6 -translate-y-1/2 transform items-center"><span
4059                                  class="inline-block w-full origin-center"
4060                                  x-show="!expanded"
4061                                ><svg
4062  class="theme-icon"
4063  xmlns="http://www.w3.org/2000/svg"
4064  fill="none"
4065  viewBox="0 0 24 24"
4066>
4067  <path stroke="currentColor" d="M12 1v22M1 12h22" vector-effect="non-scaling-stroke"/>
4068</svg>
4069</span>
4070                                <span
4071                                  class="inline-block w-full origin-center"
4072                                  x-show="expanded"
4073                                  style="display: none;"
4074                                ><svg
4075  class="theme-icon"
4076  xmlns="http://www.w3.org/2000/svg"
4077  fill="none"
4078  viewBox="0 0 24 24"
4079>
4080  <path stroke="currentColor" d="M1 12h22" vector-effect="non-scaling-stroke"/>
4081</svg>
4082</span></span>
4083                          </button>
4084                          <ul
4085                            id="accordion3"
4086                            class="no-js-focus-container px-2 pb-2 pt-1"
4087                            x-show="expanded"
4088                            x-cloak
4089                          ><li>
4090                                <a
4091                                  class="inline-block py-1 "
4092                                  href="/pages/school-leavers-gear"
4093                                >
4094                                  School leavers gear
4095                                </a>
4096                              </li><li>
4097                                <a
4098                                  class="inline-block py-1 "
4099                                  href="/pages/tshirt-printing"
4100                                >
4101                                  Custom t-shirt printing
4102                                </a>
4103                              </li></ul>
4104                        </data-island></li></ul>
4105              </data-island></li><li
4106            class="no-js-focus-wrapper break-word px-section-horizontal-spacing border-t-gridline border-gridline-color first-of-type:border-t-0"
4107          ><a class="inline-block py-4 w-full text-heading-standard" href="/pages/responsibility">
4108                Responsibility
4109              </a></li><li
4110            class="no-js-focus-wrapper break-word px-section-horizontal-spacing border-t-gridline border-gridline-color first-of-type:border-t-0"
4111          ><data-island class="contents" x-data="{ expanded: false }"><button
4112                  class="relative block w-full text-left inline-block py-4 w-full text-heading-standard ease pr-10 transition font-body"
4113                  x-bind:aria-expanded="expanded ? true : 'false'"
4114                  @click="expanded = ! expanded"
4115                  aria-controls="accordion4"
4116                >
4117                  Our story
4118                  <span class="absolute right-0 top-1/2 flex h-6 w-6 -translate-y-1/2 transform items-center"><span
4119                        class="inline-block w-full origin-center"
4120                        x-show="!expanded"
4121                      ><svg
4122  class="theme-icon"
4123  xmlns="http://www.w3.org/2000/svg"
4124  fill="none"
4125  viewBox="0 0 24 24"
4126>
4127  <path stroke="currentColor" d="M12 1v22M1 12h22" vector-effect="non-scaling-stroke"/>
4128</svg>
4129</span>
4130                      <span
4131                        class="inline-block w-full origin-center"
4132                        x-show="expanded"
4133                        style="display: none;"
4134                      ><svg
4135  class="theme-icon"
4136  xmlns="http://www.w3.org/2000/svg"
4137  fill="none"
4138  viewBox="0 0 24 24"
4139>
4140  <path stroke="currentColor" d="M1 12h22" vector-effect="non-scaling-stroke"/>
4141</svg>
4142</span></span>
4143                </button>
4144                <ul
4145                  id="accordion4"
4146                  class="no-js-focus-container pb-2 pl-4"
4147                  x-show="expanded"
4148                  x-cloak
4149                ><li class="no-js-focus-wrapper"><a
4150                          class="inline-block py-1 "
4151                          href="/pages/in-good-company-with"
4152                        >
4153                          In good company with…
4154                        </a></li><li class="no-js-focus-wrapper"><a
4155                          class="inline-block py-1 "
4156                          href="/pages/about-print-room"
4157                        >
4158                          Our origins
4159                        </a></li></ul>
4160              </data-island></li><li
4161            class="no-js-focus-wrapper break-word px-section-horizontal-spacing border-t-gridline border-gr
4161idline-color first-of-type:border-t-0"
4162          ><data-island class="contents" x-data="{ expanded: false }"><button
4163                  class="relative block w-full text-left inline-block py-4 w-full text-heading-standard ease pr-10 transition font-body"
4164                  x-bind:aria-expanded="expanded ? true : 'false'"
4165                  @click="expanded = ! expanded"
4166                  aria-controls="accordion5"
4167                >
4168                  Get started
4169                  <span class="absolute right-0 top-1/2 flex h-6 w-6 -translate-y-1/2 transform items-center"><span
4170                        class="inline-block w-full origin-center"
4171                        x-show="!expanded"
4172                      ><svg
4173  class="theme-icon"
4174  xmlns="http://www.w3.org/2000/svg"
4175  fill="none"
4176  viewBox="0 0 24 24"
4177>
4178  <path stroke="currentColor" d="M12 1v22M1 12h22" vector-effect="non-scaling-stroke"/>
4179</svg>
4180</span>
4181                      <span
4182                        class="inline-block w-full origin-center"
4183                        x-show="expanded"
4184                        style="display: none;"
4185                      ><svg
4186  class="theme-icon"
4187  xmlns="http://www.w3.org/2000/svg"
4188  fill="none"
4189  viewBox="0 0 24 24"
4190>
4191  <path stroke="currentColor" d="M1 12h22" vector-effect="non-scaling-stroke"/>
4192</svg>
4193</span></span>
4194                </button>
4195                <ul
4196                  id="accordion5"
4197                  class="no-js-focus-container pb-2 pl-4"
4198                  x-show="expanded"
4199                  x-cloak
4200                ><li class="no-js-focus-wrapper"><a
4201                          class="inline-block py-1 "
4202                          href="/collections/product-library"
4203                        >
4204                          Start a project
4205                        </a></li><li class="no-js-focus-wrapper"><a
4206                          class="inline-block py-1 "
4207                          href="/pages/book-a-call"
4208                        >
4209                          Book a call
4210                        </a></li></ul>
4211              </data-island></li></ul>
4212    </nav>
4213    <div class="border-t-gridline border-gridline-color">
4214      <nav class="my-6" aria-label="Secondary">
4215        <ul></ul>
4216      </nav>
4217
4218      
4219        <div class="my-6 px-section-horizontal-spacing">
4220          <form method="post" action="/localization" id="sidebar-localization-form" accept-charset="UTF-8" class="shopify-localization-form" enctype="multipart/form-data"><input type="hidden" name="form_type" value="localization" /><input type="hidden" name="utf8" value="✓" /><input type="hidden" name="_method" value="put" /><input type="hidden" name="return_to" value="/cart" /><div class="flex gap-4 flex-col gap-y-0"><div class="inline-block shrink-0 select-none">
4221        <h2 class="sr-only" id="country-heading-sidebar">
4222          Country/region
4223        </h2>
4224        <data-island
4225          class="relative"
4226          x-data="{ expanded: false }"
4227          @keydown.escape.prevent.stop="expanded = false"
4228          @click.outside="expanded = false"
4229        >
4230          <button
4231            type="button"
4232            class="text-base py-2"
4233            :aria-expanded="expanded"
4234            aria-controls="country-list-sidebar"
4235            aria-describedby="country-heading-sidebar"
4236            @click.prevent="expanded = ! expanded"
4237          >
4238            United States (USD
4239            $)
4240            <span
4241              class="rotate ml-1 inline-block w-3 origin-center transform fill-current transition"
4242              :class="{ 'rotate-180': expanded }"
4243            >
4244              <svg
4245  class="theme-icon"
4246  xmlns="http://www.w3.org/2000/svg"
4247  fill="none"
4248  viewBox="0 0 24 24"
4249>
4250  <path stroke="currentColor" d="M1.5 7 12 17.5 22.5 7" vector-effect="non-scaling-stroke"/>
4251</svg>
4252
4253            </span>
4254          </button>
4255          <div
4256            class="absolute bottom-[calc(100%_+_0.5rem)] right-auto left-0"
4257            x-show="expanded"
4258            style="display: none;"
4259          >
4260            <ul
4261              id="country-list-sidebar"
4262              class="relative z-10 flex max-h-[30vh] w-max max-w-[theme(spacing.52)] snap-y snap-mandatory flex-col gap-[--text-border-width] overflow-y-auto border-text border-gr
4262idline-color bg-gridline-color text-base"
4263              x-transition:enter="transition ease duration-300"
4264              x-transition:enter-start="opacity-0"
4265              x-transition:enter-end="opacity-100"
4266              x-transition:leave="transition ease duration-300"
4267              x-transition:leave-start="opacity-100"
4268              x-transition:leave-end="opacity-0"
4269              :aria-hidden="! expanded"
4270            >
4271              
4272                <li class="flex items-center bg-scheme-background px-2 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
4273                  <button
4274                    class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
4275                    type="button"
4276                    
4277                    @click.prevent="$refs.input.value = 'AU'; $root.closest('form').submit();"
4278                  >
4279                    <span class="border-transparent border-b-text">Australia (AUD
4280                      $)</span
4281                    >
4282                  </button>
4283                </li>
4284                <li class="flex items-center bg-scheme-background px-2 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
4285                  <button
4286                    class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
4287                    type="button"
4288                    
4289                    @click.prevent="$refs.input.value = 'CN'; $root.closest('form').submit();"
4290                  >
4291                    <span class="border-transparent border-b-text">China (CNY
4292                      ¥)</span
4293                    >
4294                  </button>
4295                </li>
4296                <li class="flex items-center bg-scheme-background px-2 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
4297                  <button
4298                    class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
4299                    type="button"
4300                    
4301                    @click.prevent="$refs.input.value = 'FR'; $root.closest('form').submit();"
4302                  >
4303                    <span class="border-transparent border-b-text">France (EUR
4304                      €)</span
4305                    >
4306                  </button>
4307                </li>
4308                <li class="flex items-center bg-scheme-background px-2 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
4309                  <button
4310                    class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
4311                    type="button"
4312                    
4313                    @click.prevent="$refs.input.value = 'NZ'; $root.closest('form').submit();"
4314                  >
4315                    <span class="border-transparent border-b-text">New Zealand (NZD
4316                      $)</span
4317                    >
4318                  </button>
4319                </li>
4320                <li class="flex items-center bg-scheme-background px-2 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
4321                  <button
4322                    class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
4323                    type="button"
4324                    
4325                    @click.prevent="$refs.input.value = 'GB'; $root.closest('form').submit();"
4326                  >
4327                    <span class="border-transparent border-b-text">United Kingdom (GBP
4328                      £)</span
4329                    >
4330                  </button>
4331                </li>
4332                <li class="flex items-center bg-scheme-background px-2 py-2 coarse-pointer:min-h-[44px] coarse-pointer:min-w-[44px]">
4333                  <button
4334                    class="break-word text-left [text-wrap:balance] hover:text-scheme-accent"
4335                    type="button"
4336                    
4337                      aria-current="true"
4338                    
4339                    @click.prevent="$refs.input.value = 'US'; $root.closest('form').submit();"
4340                  >
4341                    <span class="border-scheme-text border-b-text">United States (USD
4342                      $)</span
4343                    >
4344                  </button>
4345                </li></ul>
4346          </div>
4347
4348          <input
4349            x-ref="input"
4350            type="hidden"
4351            name="country_code"
4352            id="CountrySelector"
4353            value="US"
4354          >
4355        </data-island>
4356      </div></div></form>
4357        </div>
4358      
4359
4360      
4361<form
4362          class="my-6 px-section-horizontal-spacing"
4363          action="/search"
4364          method="get"
4365          role="search"
4366        >
4367          <div class="flex w-full max-w-xs items-end">
4368            <label for="menu-drawer-search" class="sr-only">Search</label>
4369            <input
4370              class="min-w-0 flex-auto border-b-text border-current bg-transparent py-1.5 placeholder-current"
4371              id="menu-drawer-search"
4372              type="text"
4373              name="q"
4374              placeholder="Search"
4375            >
4376            <button
4377              class="px-1"
4378              type="submit"
4379            >
4380              <span class="inline-block h-6 w-6"><svg
4381  class="theme-icon"
4382  xmlns="http://www.w3.org/2000/svg"
4383  fill="none"
4384  viewBox="0 0 24 24"
4385>
4386  <path stroke="currentColor" d="M2 11a9 9 0 1 0 18 0 9 9 0 0 0-18 0Zm15.364 6.364L22 22" vector-effect="non-scaling-stroke"/>
4387</svg>
4388</span>
4389              <span class="sr-only">Submit</span>
4390            </button>
4391          </div>
4392        </form>
4393    </div>
4394  </div>
4395
4396    </div>
4397  </section>
4398
4399  <style>
4400    .section-sidebar {
4401      display: block !important;
4402    }
4403
4404    @media (min-width: 1024px) {
4405      .section-sidebar {
4406        display: none !important;
4407      }
4408    }
4409
4410    .sidebar-container {
4411      position: static;
4412      width: 100%;
4413      max-width: 100%;
4414      border-right: 0;
4415      display: none;
4416    }
4417
4418    .section-sidebar:focus-within .sidebar-container {
4419      display: block !important;
4420    }
4421  </style>
4422</noscript>
4423
4424
4425</div>
4425<script>
4426  const calculateHeaderHeights = () => {
4427    const headerGroupHeights = [];
4428
4429    document
4430      .querySelectorAll('.shopify-section-group-header-group')
4431      .forEach((headerGroupSectionEl) => {
4432        headerGroupHeights.push(
4433          headerGroupSectionEl.getBoundingClientRect().height
4434        );
4435      });
4436
4437    document.documentElement.style.setProperty(
4438      '--header-group-height',
4439      `${headerGroupHeights.reduce((subtotal, a) => subtotal + a, 0)}px`
4440    );
4441  };
4442
4443  calculateHeaderHeights();
4444
4445  if (document.readyState === 'loading') {
4446    document.addEventListener('DOMContentLoaded', calculateHeaderHeights);
4447  }
4448  window.addEventListener('load', calculateHeaderHeights);
4449
4450  const debouncedCalculateHeaderHeights = debounce(calculateHeaderHeights, 300);
4451
4452  window.addEventListener('resize', debouncedCalculateHeaderHeights);
4453</script>
4453
4454
4455
4456
4457<style>
4458  #MainContent
4459    > .shopify-section.banner-section:first-child
4460    [data-media-container].h-screen {
4461    height: calc(100vh - var(--header-group-height));
4462  }
4463
4464  @media (min-width: 990px) {
4465    #MainContent
4466      > .shopify-section.banner-section:first-child
4467      [data-media-container].lg\:h-auto {
4468      height: auto;
4469    }
4470
4471    #MainContent
4472      > .shopify-section.banner-section:first-child
4473      [data-media-container].lg\:h-screen {
4474      height: calc(100vh - var(--header-group-height));
4475    }
4476  }
4477</style>
4478
4479    
4480
4481    <main id="MainContent">
4482      <div id="shopify-section-template--21296461119558__cart-items" class="shopify-section"><section
4483  id="main-cart-items"
4484  class="border-b-gridline border-gridline-color bg-scheme-background text-scheme-text"
4485  data-color-scheme=""
4486>
4487  
4488<data-island
4489  x-data="CartItems"
4490  data-cart-items
4491  on="idle"
4492>
4493  
4494  
4495    <div class="py-section-vertical-spacing px-section-horizontal-spacing">
4496      <h1 class="font-heading text-heading-standard">
4497        Your cart
4498      </h1>
4499      
4500      <div class="mt-8">
4501        <p class="mb-8">Your cart is currently empty.</p>
4502        <a
4503          class="theme-link inline-block text-scheme-text hover:text-scheme-accent"
4504          href="/"
4505        >Continue shopping</a>
4506      </div>
4507    </div>
4508  
4509  <p
4510    class="sr-only"
4511    id="cart-live-region-text"
4512    aria-live="polite"
4513    role="status"
4514  ></p>
4515  <p
4516    class="sr-only"
4517    id="shopping-cart-line-item-status"
4518    aria-live="polite"
4519    aria-hidden="true"
4520    role="status"
4521  >
4522    Loading...
4523  </p>
4524</data-island>
4525
4526</section>
4527
4528
4529</div><div id="shopify-section-template--21296461119558__custom_liquid_jM7V3F" class="shopify-section"><section
4530  class="gap-gutter overflow-hidden border-b-gridline border-gridline-color bg-gridline-color text-scheme-text"
4531  data-color-scheme="scheme1"
4532>
4533  <div class="bg-scheme-background">
4534    <div class="px-section-horizontal-spacing py-section-vertical-spacing"><h2 class="font-heading mb-4 text-2xl"></h2><!DOCTYPE html>
4535<html lang="en">
4536<head>
4537    <meta charset="UTF-8">
4538    <meta name="viewport" content="width=device-width, initial-scale=1.0">
4539    <title>Go Back Example</title>
4540    <style>
4541        /* Add any custom styles here */
4542        .goback-link {
4543            text-decoration: underline;
4544            cursor: pointer; /* Ensures pointer cursor on hover */
4545            color: #; /* Replace with your Shopify theme's primary color variable */
4546        }
4547    </style>
4548</head>
4549<body>
4550    <!-- Your Shopify page content here -->
4551
4552    <span class="goback-link" onclick="goBack()">Go Back</span>
4553
4554    <!-- Your Shopify page content continues here -->
4555
4556    
4556<script>
4557        function goBack() {
4558            window.history.back();
4559        }
4560    </script>
4560
4561<div id="shopify-block-AWDJwL3lGQkF3Zitrd__39280165312039977" class="shopify-block shopify-app-block">
4562
4563�
4563<script>
4564  console.log('[FulfillmentFee] Namespace: app--313853968385--fulfillment_fee');
4565  console.log('[FulfillmentFee] Key: config');
4566  console.log('[FulfillmentFee] Config value:', {"vendorFees":{"Wētā FX Crew":5.75},"feeProductVariantId":"gid:\/\/shopify\/ProductVariant\/44486403227718","isEnabled":true});
4567</script>
4567<script>
4568  (function() {
4569    // The metafield .value is already a parsed JSON object
4570    var configData = {"vendorFees":{"Wētā FX Crew":5.75},"feeProductVariantId":"gid:\/\/shopify\/ProductVariant\/44486403227718","isEnabled":true};
4571    if (configData && typeof configData === 'object') {
4572      window.__FULFILLMENT_FEE_CONFIG__ = configData;
4573      console.log('[FulfillmentFee] Config loaded:', window.__FULFILLMENT_FEE_CONFIG__);
4574    } else {
4575      console.error('[FulfillmentFee] Invalid config data:', configData);
4576      window.__FULFILLMENT_FEE_CONFIG__ = null;
4577    }
4578  })();
4579</script>
vendor: 2 bytes, line 4579
4579
4580<script src="https://cdn.shopify.com/extensions/019d45d2-6a70-7eed-8da1-d1e8fd0fae86/fulfillment-fee-app-100/assets/fulfillment-fee-manager.js" defer></script>
4580
4581</div><div id="shopify-block-AWitpMC8rZDJCSlg4R__15573056287721514228" class="shopify-block shopify-app-block json-ld-for-seo"><!-- generated: 2026-10-04 21:38:25 +1300 -->
4582<!-- BEGIN app snippet: json_ld_for_seo_web_page -->
4582<script type="application/ld+json">
4583 {
4584   "@context": "https://schema.org",
4585   "@type": "WebPage",
4586   "@id": "https:\/\/printroom.co\/cart#json-ld-for-seo-webpage",
4587   "url": "https:\/\/printroom.co\/cart",
4588   "image": null,
4589   "primaryImageOfPage": null,
4590   "dateCreated": null,
4591   "datePublished": null
4592 }
4593</script>
4593
4594<!-- END app snippet -->
4595<!-- wp 1 --><!-- BEGIN app snippet: json_ld_for_seo_organization -->
4596<script type="application/ld+json">
4597{
4598    "@context": "https://schema.org",
4599    "@type": "Organization","@id": "https:\/\/printroom.co\/#org",
4600    "name": "The Print Room",
4601    "url": "https:\/\/printroom.co",
4602    "description": "NZ’s experts in custom t-shirt printing, tote bags, uniforms, and branded merchandise. Print Room offers high-quality screen printing and embroidery using eco-friendly inks. Fast turnaround, sustainable production, and trusted by leading New Zealand brands.",
4603    "telephone": "+6434259694",
4604    "logo": "https:\/\/cdn.shopify.com\/s\/images\/admin\/no-image-large.gif",
4605    "image": "https:\/\/cdn.shopify.com\/s\/images\/admin\/no-image-large.gif",
4606    "sameAs": ["","https:\/\/www.instagram.com\/printroomnz\/"],
4607    "address": {
4608        "@type": "PostalAddress",
4609        "streetAddress": "21 Grosvenor Street, 21",
4610        "addressLocality": "Dunedin",
4611        "addressRegion": "Otago",
4612        "postalCode": "9011",
4613        "addressCountry": "NZ"
4614    },
4615   "contactPoint": [
4616     {
4617       "@type": "ContactPoint",
4618       "telephone": "+6434259694",
4619       "email": ""
4620     }
4621    ]}
4622</script>
4622
4623<!-- END app snippet --> <!-- o 6 --><!-- BEGIN app snippet: json_ld_for_seo_product_group --><!-- END app snippet -->
4624<!-- p 1 --><!-- A 10 -->
4625
4626
4627</div></body>
4628</html>
4629    </div>
4630  </div>
4631</section>
4632
4633
4634</div><div id="shopify-section-template--21296461119558__cart-footer" class="shopify-section"><section
4635  id="main-cart-footer"
4636  class="text-scheme-text bg-scheme-background border-b-gridline border-gridline-color"
4637  data-color-scheme="scheme1"
4638>
4639  
4640
4641<data-island
4642  x-data="CartFooter"
4643  data-cart-footer
4644  on="idle"
4645>
4646  <div class="hidden md:grid md:grid-cols-12 px-section-horizontal-spacing pb-theme">
4647    
4648      <div class="mt-4 md:col-span-5">
4649        <label class="block" for="CartSpecialInstructions">Add a note to your order</label>
4650        <textarea
4651          class="mt-1 block w-full border-text border-current bg-transparent p-2 text-sm"
4652          name="note"
4653          id="CartSpecialInstructions"
4654          form="cart"
4655          :class="{ 'opacity-50 cursor-progress' : updating }"
4656          :readonly="updating"
4657          x-data="CartNote"
4658          x-model.debounce.750ms="note"
4659        ></textarea>
4660      </div>
4661    
4662    <div class="mt-4 text-center md:col-span-5 md:col-start-8 lg:col-span-4 lg:col-start-9">
4663      <dl class="grid grid-cols-2 text-right"><dt>Subtotal</dt>
4664        <dd>$0.00 USD</dd>
4665      </dl><p class="has-theme-links mt-4 text-right">
4666        Tax included. <a href="/policies/shipping-policy">Shipping</a> calculated at checkout.
4667
4668      </p>
4669
4670      <div class="no-js:lg:grid no-js:lg:grid-cols-2 no-js:lg:gap-2 mt-4 w-full items-center justify-between">
4671        <button
4672          class="theme-button--secondary hidden no-js:block"
4673          type="submit"
4674          name="update"
4675          form="cart"
4676        >Update</button><button
4677          class="mt-2 block w-full cursor-pointer rounded-button p-2 [text-transform:var(--button-text-transform)] after:content-[var(--button-after-content)] lg:mt-0 border-text border-button bg-button text-button hover:border-button-hover hover:bg-button-hover hover:text-button-hover"
4678          type="submit"
4679          name="checkout"
4680          form="cart"
4681        >Check out</button>
4682      </div>
4683
4684      
4685
4686      <div
4687        class="mt-4 lg:text-right text-scheme-accent"
4688        id="cart-errors"
4689      ></div>
4690    </div>
4691  </div>
4692
4693  
4694</data-island>
4695
4696
4697</section>
4698
4699
4700</div>
4700<script data-locksmith>
4701    var load = function () {
4702
4703          if (document.querySelectorAll('.locksmith-manual-trigger').length > 0) {
4704            Locksmith.ping();
4705          }
4706
4707
4708      Locksmith.util.on('submit', 'locksmith-resource-form', function (event) {
4709        event.preventDefault();
4710        var data = Locksmith.util.serializeForm(event.target);
4711        var options = { spinner: false, container: 'locksmith-content' };
4712        // a form rendered inline (section replacement) must keep that context
4713        // on resubmit: same enclosing container (there may be several on the
4714        // page), and no layout classes or cancel affordance in the re-render
4715        var inlineContainer = event.target.closest && event.target.closest('[id^="locksmith-content"]');
4716        if (inlineContainer) {
4717          options.container = inlineContainer;
4718        }
4719        if (event.target.getAttribute('data-locksmith-inline') === 'true') {
4720          options.include_layout_classes = false;
4721        }
4722        Locksmith.postResource(data, options);
4723      });
4724
4725      Locksmith.util.on('click', 'locksmith-manual-trigger', function (event) {
4726        event.preventDefault();
4727        Locksmith.postResource({}, { spinner: true, container: document });
4728      });
4729
4730      Locksmith.submitPasscode = function (passcode) {
4731        Locksmith.postResource(
4732          { passcode: passcode },
4733          { spinner: false, container: 'locksmith-content' }
4734        );
4735      };
4736    };
4737
4738    if (typeof Locksmith !== 'undefined') {
4739      load();
4740    } else {
4741      window.addEventListener('load', load);
4742    }
4743  </script>
4743
4744    </main>
4745
4746    <!-- BEGIN sections: footer-group -->
4747<div id="shopify-section-sections--21296457154630__176903720293717250" class="shopify-section shopify-section-group-footer-group">
4748
4749
4750
4751</div><div id="shopify-section-sections--21296457154630__footer" class="shopify-section shopify-section-group-footer-group"><footer
4752  class="bg-scheme-background text-scheme-text"
4753  data-color-scheme="scheme2"
4754  data-theme-footer
4755>
4756  
4757    <section
4758  class="border-b-gridline border-gridline-color bg-scheme-background py-section-vertical-spacing text-scheme-text"
4759  data-color-scheme="scheme2"
4760>
4761  <div class="justify-center px-section-horizontal-spacing lg:flex lg:items-center lg:justify-between">
4762    <div class="text-base">
4763      
4764
4765      
4766        <div class="[&_a[href]]:underline [&_a[href]]:hover:text-scheme-accent">
4767          <h2>We occasionally send out <strong>newsletters</strong>. You should sign up →</h2>
4768        </div>
4769      
4770    </div>
4771
4772    <div class="mt-theme-half lg:mt-0">
4773      <form method="post" action="/contact#Contact-sections--21296457154630__footer" id="Contact-sections--21296457154630__footer" accept-charset="UTF-8" class="contact-form"><input type="hidden" name="form_type" value="customer" /><input type="hidden" name="utf8" value="✓" />
4774        
4775
4776        
4777          <input type="hidden" name="contact[tags]" value="newsletter">
4778          <div class="items-end lg:ml-4 lg:flex">
4779            <label class="sr-only" for="Email-sections--21296457154630__footer">Email address</label>
4780            <input
4781              type="email"
4782              class="font-body block w-full border-b-text border-current bg-transparent pb-1 leading-[inherit] placeholder-current"
4783              name="contact[email]"
4784              id="Email-sections--21296457154630__footer"
4785              value=""
4786              placeholder="Email address"
4787              autocorrect="off"
4788              autocapitalize="off"
4789            >
4790            <button
4791              class="theme-link mt-2 shrink-0 py-1 leading-[inherit] hover:text-scheme-accent lg:ml-2 lg:mt-0"
4792              type="submit"
4793              name="commit"
4794              id="Subscribe"
4795            >Subscribe</button>
4796          </div>
4797        
4798      </form>
4799    </div>
4800  </div>
4801</section>
4802
4803  
4804  
4805    <div class="border-b-gridline border-gridline-color">
4806      <div
4807        class="grid lg:grid-cols-var bg-gridline-color"
4808        style="--grid-cols: 12;"
4809      ><div
4810            class="break-word bg-scheme-background px-section-horizontal-spacing py-section-vertical-spacing text-scheme-text lg:col-span-var"
4811            style="--col-span: 3;"
4812            
4813          ><div class="inline-block text-left">
4814                  
4815                  
4816                    <h2 class="font-heading mb-4 text-base">
4817                      Explore
4818                    </h2>
4819                  
4820                  <ul class="list-none space-y-1">
4821                    
4822<li>
4823                        <a
4824                          href="/pages/all-products"
4825                          class="hover:text-scheme-accent"
4826                        >
4827                          Products
4828                        </a>
4829                      </li>
4830                    
4831<li>
4832                        <a
4833                          href="/pages/services"
4834                          class="hover:text-scheme-accent"
4835                        >
4836                          Services
4837                        </a>
4838                      </li>
4839                    
4840<li>
4841                        <a
4842                          href="https://www.theprintroom.nz/apps/order-tracker"
4843                          class="hover:text-scheme-accent"
4844                        >
4845                          Track your order
4846                        </a>
4847                      </li>
4848                    
4849<li>
4850                        <a
4851                          href="/pages/responsibility"
4852                          class="hover:text-scheme-accent"
4853                        >
4854                          Responsibility
4855                        </a>
4856                      </li>
4857                    
4858<li>
4859                        <a
4860                          href="/pages/about-print-room"
4861                          class="hover:text-scheme-accent"
4862                        >
4863                          About us
4864                        </a>
4865                      </li>
4866                    
4867                  </ul>
4868                </div></div><div
4869            class="break-word bg-scheme-background px-section-horizontal-spacing py-section-vertical-spacing text-scheme-text lg:col-span-var"
4870            style="--col-span: 3;"
4871            
4872          ><div class="inline-block text-left">
4873                  
4874                  
4875                    <h2 class="font-heading mb-4 text-base">
4876                      Helpful stuff
4877                    </h2>
4878                  
4879                  <ul class="list-none space-y-1">
4880                    
4881<li>
4882                        <a
4883                          href="/pages/screen-printing-faqs-the-print-room-quality-screen-printing-garment-design-blank-clothing"
4884                          class="hover:text-scheme-accent"
4885                        >
4886                          FAQs
4887                        </a>
4888                      </li>
4889                    
4890<li>
4891                        <a
4892                          href="https://help.theprintroom.nz/"
4893                          class="hover:text-scheme-accent"
4894                        >
4895                          Resource hub
4896                        </a>
4897                      </li>
4898                    
4899<li>
4900                        <a
4901                          href="/pages/catalogue"
4902                          class="hover:text-scheme-accent"
4903                        >
4904                          Catalogues
4905                        </a>
4906                      </li>
4907                    
4908<li>
4909                        <a
4910                          href="/blogs/the-print-room-nz"
4911                          class="hover:text-scheme-accent"
4912                        >
4913                          Blogs
4914                        </a>
4915                      </li>
4916                    
4917<li>
4918                        <a
4919                          href="/pages/policies"
4920                          class="hover:text-scheme-accent"
4921                        >
4922                          Policies & T&Cs
4923                        </a>
4924                      </li>
4925                    
4926                  </ul>
4927                </div></div><div
4928            class="break-word bg-scheme-background px-section-horizontal-spacing py-section-vertical-spacing text-scheme-text lg:col-span-var"
4929            style="--col-span: 3;"
4930            
4931          >
4932                  <h2 class="font-heading break-word mb-4 text-base">
4933                    Get in touch - NZ
4934                  </h2>
4935                
4936<div class="rte">
4937                  <p>21 Grosvenor St, Kensington, Dunedin,<br/>9012<br/>[email protected]<br/>NZ: 03 425 9694</p>
4938                </div></div><div
4939            class="break-word bg-scheme-background px-section-horizontal-spacing py-section-vertical-spacing text-scheme-text lg:col-span-var"
4940            style="--col-span: 3;"
4941            
4942          >
4943                  <h2 class="font-heading break-word mb-4 text-base">
4944                    Get in touch - AUS
4945                  </h2>
4946                
4947<div class="rte">
4948                  <p>The Commons, 10–20 Gwynne St, Cremorne VIC 3121<br/>[email protected]<br/>+61 (0) 451 701 385</p>
4949                </div></div></div>
4950    </div>
4951  
4952
4953  <div>
4954    <div class="px-section-horizontal-spacing py-section-vertical-spacing lg:flex lg:flex-wrap lg:items-center lg:justify-between">
4955      <div class="mb-4 space-y-2 text-sm lg:mb-0 lg:flex-1">
4956        <p>
4957          &copy; 2026,
4958          <a href="/" title="">The Print Room</a>.
4959        </p>
4960        <ul class="flex flex-wrap gap-1 text-sm [&>li:last-child]:after:content-none [&>li]:after:content-['\00B7']">
4961          <li>
4962            
4963          </li></ul>
4964      </div>
4965      
4966</div>
4967  </div>
4968</footer>
4969
4970
4971  <style>
4972    .footer-logo-image {
4973      display: block;
4974      max-width: px;
4975    }
4976  </style>
4977
4978
4979
4980<style> #shopify-section-sections--21296457154630__footer .text-base {font-size: 20px;} #shopify-section-sections--21296457154630__footer .font-heading {text-decoration: underline;} #shopify-section-sections--21296457154630__footer .inline-block {line-height: 1.7;} #shopify-section-sections--21296457154630__footer /*.bg-scheme-background {border-top: 1px solid black;}*/.text-scheme-text {border-bottom: 1px solid black;} </style></div>
4981<!-- END sections: footer-group --><!-- BEGIN sections: overlay-group -->
4982<div id="shopify-section-sections--21296457220166__promo-popup" class="shopify-section shopify-section-group-overlay-group contents">
4983
4984
4985</div><div id="shopify-section-sections--21296457220166__age-check" class="shopify-section shopify-section-group-overlay-group contents">
4986</div><div id="shopify-section-sections--21296457220166__privacy-banner" class="shopify-section shopify-section-group-overlay-group contents">
4987
4988
4989</div>
4990<!-- END sections: overlay-group -->
4991
4992    <div
4993      id="screenreader-announce"
4994      class="sr-only"
4995      aria-live="polite"
4996      role="status"
4997    ></div>
4998
4999    <ul hidden>
5000      <li id="a11y-refresh-page-message">
5001        Choosing a selection results in a full page refresh.
5002      </li>
5003      <li id="a11y-selection-message">
5004        Press the space key then arrow keys to make a selection.
5005      </li>
5006    </ul>
5007
5008    
5009    <data-island
5010  role="complementary"
5011  aria-labelledby="left-drawer-slot"
5012  x-data
5013  on="load"
5014>
5015  <template x-teleport="body">
5016    <div
5017      x-show="$store.modals.leftDrawer.open"
5018      @keydown.escape.prevent.stop="$store.modals.close('leftDrawer')"
5019      @click="$store.modals.close('leftDrawer')"
5020      class="fixed inset-0 z-110"
5021      data-color-scheme="scheme1"
5022      id="modals-leftDrawer"
5023    >
5024      <div
5025        @click.stop
5026        x-show="$store.modals.leftDrawer.open"
5027        x-transition:enter="duration-300 motion-reduce:duration-0 outline-0"
5028        x-transition:enter-start="opacity-0 -translate-x-full"
5029        x-transition:leave="duration-300 motion-reduce:duration-0 outline-0"
5030        x-transition:leave-end="-translate-x-full"
5031        x-trap.noscroll.inert="$store.modals.leftDrawer.open"
5032        class="mr-auto h-full w-11/12 max-w-md transform overflow-y-auto border-r-gridline border-gr
5032idline-color bg-scheme-background text-scheme-text transition-transform"
5033        id="left-drawer-slot"
5034        role="dialog"
5035        @left-drawer-is-open.window="setTimeout(() => { $el.setAttribute('aria-modal', 'true') }, 120)"
5036        @left-drawer-is-closed.window="setTimeout(() => { $el.removeAttribute('aria-modal') }, 120)"
5037        :aria-label="getModalLabel('leftDrawer', $el)"
5038        tabindex="-1"
5039      >
5040        <!-- Modal content is teleported here -->
5041      </div>
5042    </div>
5043  </template>
5044</data-island>
5045<data-island
5046  role="complementary"
5047  aria-labelledby="right-drawer-slot"
5048  x-data
5049  on="load"
5050>
5051  <template x-teleport="body">
5052    <div
5053      x-show="$store.modals.rightDrawer.open"
5054      @keydown.escape.prevent.stop="$store.modals.close('rightDrawer')"
5055      @click="$store.modals.close('rightDrawer')"
5056      class="fixed inset-0 z-110"
5057      style="background: rgba(208,208,208,0.2); backdrop-filter: blur(1.5px); -webkit-backdrop-filter: blur(1.5px);"
5058      data-color-scheme="scheme1"
5059      id="modals-rightDrawer"
5060    >
5061      <div
5062        @click.stop
5063        x-show="$store.modals.rightDrawer.open"
5064        x-transition:enter="duration-300 motion-reduce:duration-0 outline-0"
5065        x-transition:enter-start="translate-x-full"
5066        x-transition:leave="duration-300 motion-reduce:duration-0 outline-0"
5067        x-transition:leave-end="translate-x-full"
5068        x-trap.noscroll.inert="$store.modals.rightDrawer.open"
5069        class="ml-auto h-full w-11/12 max-w-lg transform overflow-y-auto bg-scheme-background text-scheme-text"
5070        style="border-left: 2px solid black;"
5071        id="right-drawer-slot"
5072        role="dialog"
5073        @right-drawer-is-open.window="setTimeout(() => { $el.setAttribute('aria-modal', 'true') }, 120)"
5074        @right-drawer-is-closed.window="setTimeout(() => { $el.removeAttribute('aria-modal') }, 120)"
5075        :aria-label="getModalLabel('rightDrawer', $el)"
5076        tabindex="-1"
5077      >
5078        <!-- Modal content is teleported here -->
5079      </div>
5080    </div>
5081  </template>
5082</data-island>
5083<data-island
5084  role="complementary"
5085  aria-labelledby="quick-buy-drawer-slot-container"
5086  x-data
5087  on="load"
5088>
5089  <template x-teleport="body">
5090    <div
5091      x-show="$store.modals.quickBuyDrawer.open"
5092      @keydown.escape.prevent.stop="$store.modals.close('quickBuyDrawer')"
5093      @click="$store.modals.close('quickBuyDrawer')"
5094      class="fixed inset-0 z-110 flex lg:block"
5095      data-color-scheme="scheme1"
5096      id="modals-quickBuyDrawer"
5097    >
5098      <div
5099        @click.stop
5100        id="quick-buy-drawer-slot-container"
5101        x-show="$store.modals.quickBuyDrawer.open"
5102        x-transition:enter="duration-300 motion-reduce:duration-0 outline-0"
5103        x-transition:enter-start="max-lg:translate-y-full lg:translate-x-full"
5104        x-transition:leave="duration-300 motion-reduce:duration-0 outline-0"
5105        x-transition:leave-end="max-lg:translate-y-full lg:translate-x-full"
5106        x-trap.noscroll.inert="$store.modals.quickBuyDrawer.open"
5107        class="mt-auto h-auto w-full transform border-gridline-color bg-scheme-background text-scheme-text lg:ml-auto lg:h-full lg:w-11/12 lg:max-w-md lg:overflow-y-auto lg:border-l-gridline"
5108        role="dialog"
5109        @quick-buy-drawer-is-open.window="setTimeout(() => { $el.setAttribute('aria-modal', 'true') }, 120)"
5110        @quick-buy-drawer-is-closed.window="setTimeout(() => { $el.removeAttribute('aria-modal') }, 120)"
5111        :aria-label="getModalLabel('quickBuyDrawer', document.getElementById('quick-buy-drawer-slot'))"
5112        tabindex="-1"
5113      >
5114        <div class="sticky top-0 z-1 flex items-center justify-between border-y-gridline border-gridline-color bg-scheme-background px-section-horizontal-spacing py-4 lg:border-t-0">
5115          <div>
5116            Choose options
5117          </div>
5118          <button
5119            @click.prevent="$store.modals.close('quickBuyDrawer')"
5120            class="absolute right-0 top-0 block h-full"
5121            type="button"
5122          >
5123            <span class="sr-only">Close</span>
5124            <div class="my-auto mr-section-horizontal-spacing h-6 w-6">
5125              <svg
5126  class="theme-icon"
5127  xmlns="http://www.w3.org/2000/svg"
5128  fill="none"
5129  viewBox="0 0 24 24"
5130>
5131  <path stroke="currentColor" d="m1.5 1.5 21 21m0-21-21 21" vector-effect="non-scaling-stroke"/>
5132</svg>
5133
5134            </div>
5135          </button>
5136        </div>
5137        <div
5138          id="quick-buy-drawer-slot"
5139          class="max-lg:h-fit max-lg:max-h-[65vh] max-lg:overflow-y-auto"
5140        ></div>
5141      </div>
5142    </div>
5143  </template>
5144</data-island>
5145<data-island
5146  x-data
5147  on="load"
5148>
5149  <template x-teleport="body">
5150    <div
5151      x-show="$store.modals.promo.open"
5152      class="pointer-events-none fixed inset-0 z-110"
5153      id="modals-promo"
5154    >
5155      <div
5156        x-show="$store.modals.promo.open"
5157        class="flex h-full w-full"
5158      >
5159        <div
5160          x-show="$store.modals.promo.open"
5161          x-transition:enter="transition duration-300 motion-reduce:duration-0 delay-75 outline-0"
5162          x-transition:enter-start="translate-y-full"
5163          x-transition:enter-end="translate-y-0"
5164          x-transition:leave="transition duration-300 motion-reduce:duration-0 outline-0"
5165          x-transition:leave-start="translate-y-0"
5166          x-transition:leave-end="translate-y-full"
5167          class="pointer-events-auto relative bottom-0 left-0 right-0 top-auto mt-auto w-full overflow-y-auto"
5168          id="promo-slot"
5169          role="dialog"
5170          @promo-is-open.window="setTimeout(() => { $el.setAttribute('aria-modal', 'true') }, 120)"
5171          @promo-is-closed.window="setTimeout(() => { $el.removeAttribute('aria-modal') }, 120)"
5172          :aria-label="getModalLabel('promo', $el)"
5173          tabindex="-1"
5174        >
5175          <!-- Modal content is teleported here -->
5176        </div>
5177      </div>
5178    </div>
5179  </template>
5180</data-island>
5181<data-island x-data on="load">
5182  <template x-teleport="body">
5183    <div
5184      x-show="$store.modals.popup.open"
5185      @keydown.escape.prevent.stop="$store.modals.close('popup')"
5186      @click="$store.modals.close('popup')"
5187      class="fixed inset-0 z-110 p-8 lg:p-24"
5188      data-color-scheme="scheme1"
5189      id="modals-popup"
5190    >
5191      <div
5192        x-show="$store.modals.popup.open"
5193        class="fixed inset-0 bg-transparent"
5194      >
5195        <!-- Overlay -->
5196      </div>
5197      <div
5198        x-show="$store.modals.popup.open"
5199        class="flex h-full w-full"
5200      >
5201        <div
5202          @click.stop
5203          x-show="$store.modals.popup.open"
5204          x-trap.noscroll.inert="$store.modals.popup.open"
5205          class="relative m-auto max-h-full w-full max-w-2xl overflow-y-auto border-gr
5205idline border-gridline-color bg-scheme-background text-scheme-text"
5206          id="popup-slot"
5207          role="dialog"
5208          @popup-is-open.window="setTimeout(() => { $el.setAttribute('aria-modal', 'true') }, 120)"
5209          @popup-is-closed.window="setTimeout(() => { $el.removeAttribute('aria-modal') }, 120)"
5210          :aria-label="getModalLabel('popup', $el)"
5211          tabindex="-1"
5212        >
5213          <!-- Modal content is teleported here -->
5214        </div>
5215      </div>
5216    </div>
5217  </template>
5218</data-island>
5219<data-island x-data on="load">
5220  <template x-teleport="body">
5221    <div
5222      x-show="$store.modals.modal.open"
5223      x-transition:enter="transition ease-out duration-300"
5224      x-transition:enter-start="opacity-0"
5225      x-transition:enter-end="opacity-100"
5226      x-transition:leave="transition ease-in duration-200"
5227      x-transition:leave-start="opacity-100"
5228      x-transition:leave-end="opacity-0"
5229      @keydown.escape.prevent.stop="$store.modals.close('modal')"
5230      @click="$store.modals.close('modal')"
5231      class="fixed inset-0 z-110 bg-black/40 backdrop-blur-md"
5232      style="backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);"
5233      data-color-scheme="scheme1"
5234      id="modals-modal"
5235    >
5236      <div
5237        x-show="$store.modals.modal.open"
5238        class="flex h-full w-full justify-center p-2 sm:p-4 md:p-6 lg:p-8"
5239        :class="$store.modals.modal.contents === 'quoteRequest' ? 'items-stretch sm:items-center sm:p-6 lg:p-10' : 'items-center'"
5240      >
5241        <div
5242          @click.stop
5243          x-show="$store.modals.modal.open"
5244          x-transition:enter="transition ease-out duration-300"
5245          x-transition:enter-start="opacity-0 scale-95 translate-y-4"
5246          x-transition:enter-end="opacity-100 scale-100 translate-y-0"
5247          x-transition:leave="transition ease-in duration-200"
5248          x-transition:leave-start="opacity-100 scale-100 translate-y-0"
5249          x-transition:leave-end="opacity-0 scale-95 translate-y-4"
5250          x-trap.inert="$store.modals.modal.open"
5251          class="relative flex w-full flex-col overflow-hidden text-scheme-text"
5252          :class="$store.modals.modal.contents === 'quoteRequest'
5253            ? 'max-w-2xl max-h-[100dvh] sm:max-h-[calc(100dvh-48px)] rounded-none sm:rounded-[24px]'
5254            : 'max-w-lg sm:max-w-xl md:max-w-2xl lg:max-w-3xl max-h-[calc(100vh-24px)] sm:max-h-[calc(100vh-48px)] md:max-h-[calc(100vh-64px)] lg:max-h-[calc(100vh-96px)] rounded-[20px]'"
5255          style="background: #FBFBF6; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);"
5256          id="modal-slot"
5257          role="dialog"
5258          @modal-is-open.window="setTimeout(() => { $el.setAttribute('aria-modal', 'true') }, 120)"
5259          @modal-is-closed.window="setTimeout(() => { $el.removeAttribute('aria-modal') }, 120)"
5260          :aria-label="getModalLabel('modal', $el)"
5261          tabindex="-1"
5262        >
5263          <!-- Modal content is teleported here -->
5264        </div>
5265      </div>
5266    </div>
5267  </template>
5268</data-island>
5269
5270
5271    
5272    
5273
5274    
5275    <style>
5276  /* Push chatbot left when quote drawer is open */
5277  body:has([data-favorites-drawer]:not([style*="display: none"])) #tidio-chat,
5278  body:has([data-favorites-drawer]:not([style*="display: none"])) .tidio-chat,
5279  body:has([data-favorites-drawer]:not([style*="display: none"])) iframe[title*="chat" i],
5280  body:has([data-favorites-drawer]:not([style*="display: none"])) iframe[title*="tidio" i],
5281  body:has([data-favorites-drawer]:not([style*="display: none"])) [class*="chat-widget"],
5282  body:has([data-favorites-drawer]:not([style*="display: none"])) [id*="chat-widget"] {
5283    transform: translateX(-464px) !important;
5284    transition: transform 0.3s ease !important;
5285  }
5286
5287  /* Push AI chatbot trigger left when drawer is open - desktop only */
5288  @media (min-width: 768px) {
5289    body:has([data-favorites-drawer]:not([style*="display: none"])) .ai-chatbot__trigger {
5290      right: calc(32rem + 24px) !important;
5291      transition: right 0.3s ease, transform 0.2s ease, box-shadow 0.2s ease, background 0.2s ease !important;
5292    }
5293  }
5294
5295  /* Override theme color scheme — force black text throughout drawer */
5296  [data-favorites-drawer] {
5297    --color-scheme-text: 0 0 0 !important;
5298  }
5299  [data-favorites-drawer] h2 {
5300    letter-spacing: 0px !important;
5301  }
5302  @media (max-width: 639px) {
5303    [data-favorites-drawer] h2 {
5304      text-align: left !important;
5305    }
5306  }
5307  [data-favorites-drawer] *,
5308  [data-favorites-drawer] h2,
5309  [data-favorites-drawer] p,
5310  [data-favorites-drawer] a,
5311  [data-favorites-drawer] span,
5312  [data-favorites-drawer] div,
5313  [data-favorites-drawer] li {
5314    color: black !important;
5315  }
5316
5317  /* Close button stays muted */
5318  [data-favorites-drawer] button[aria-label*="Close"],
5319  [data-favorites-drawer] button[aria-label*="Close"] svg {
5320    color: rgba(0,0,0,0.4) !important;
5321  }
5322
5323  /* Remove button stays muted, red on hover */
5324  [data-favorites-drawer] button[aria-label*="Remove"],
5325  [data-favorites-drawer] button[aria-label*="Remove"] svg {
5326    color: rgba(0,0,0,0.3) !important;
5327  }
5328  [data-favorites-drawer] button[aria-label*="Remove"]:hover,
5329  [data-favorites-drawer] button[aria-label*="Remove"]:hover svg {
5330    color: #ef4444 !important;
5331  }
5332
5333  /* Product dividers — solid black */
5334  [data-favorites-drawer] li {
5335    border-bottom: 1px solid black !important;
5336  }
5337  [data-favorites-drawer] li:last-child {
5338    border-bottom: none !important;
5339  }
5340
5341  /* Footer dividers — solid black */
5342  [data-favorites-drawer] .drawer-divider {
5343    border-top: 1px solid black !important;
5344  }
5345
5346  /* Start quote button — visible border */
5347  [data-favorites-drawer] .drawer-cta-btn {
5348    border: 2px solid #4B4D72 !important;
5349    color: #4B4D72 !important;
5350  }
5351  [data-favorites-drawer] .drawer-cta-btn:hover {
5352    background-color: #4B4D72 !important;
5353    color: #fff !important;
5354  }
5355</style>
5356
5357<data-island
5358  x-data="FavoritesDrawer"
5359  on="idle"
5360  x-cloak
5361>
5362  <div>
5363    <template x-teleport="#right-drawer-slot">
5364      <div
5365        class="flex h-full flex-col overflow-hidden" style="background: #FBFBF6;"
5366        :data-modal-label="`Your current project - ${$store.favorites.countWithText()}`"
5367        x-show="$store.modals.rightDrawer.contents === 'favorites'"
5368        data-favorites-drawer
5369      ><div class="relative shrink-0" style="padding: 80px 40px 24px;">
5370          <button
5371            @click.prevent="$store.modals.close('favorites')"
5372            class="absolute rounded-full p-2 transition-colors"
5373            style="top: 19px; right: 19px; color: rgba(0,0,0,0.4);"
5374            type="button"
5375          >
5376            <span class="sr-only">Close project drawer</span>
5377            <svg width="24" height="24" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-width="2" d="m6 6 12 12m0-12-12 12"/></svg>
5378          </button>
5379          <h2 id="FavoritesTitle" tabindex="-1" class="font-bold" style="font-size: 41px; letter-spacing: 0px; line-height: 1; color: black; text-align: center;">
5380            Your current project
5381          </h2>
5382        </div><div class="flex-1 overflow-y-auto" style="padding: 20px 40px; min-height: 0;"><template x-if="$store.favorites.count === 0">
5383            <div class="flex flex-col items-center justify-center py-12 text-center">
5384              <p class="mb-2 text-base font-medium text-scheme-text">No products yet</p>
5385              <p class="mx-auto mb-8 max-w-xs text-sm text-scheme-text/60">Browse our products and add items to your project.</p>
5386              <a
5387                href="/collections/product-library"
5388                class="inline-flex items-center justify-center font-light transition"
5389                style="border: 2px solid #4B4D72; color: #4B4D72; border-radius: 50px; padding: 18px 48px; font-size: 24px;"
5390                onmouseover="this.style.backgroundColor='#4B4D72'; this.style.color='#fff';"
5391                onmouseout="this.style.backgroundColor='transparent'; this.style.color='#4B4D72';"
5392                @click="$store.modals.close('favorites')"
5393              >
5394                Browse Products
5395              </a>
5396            </div>
5397          </template><template x-if="$store.favorites.count > 0">
5398            <ul>
5399              <template x-for="item in $store.favorites.items" :key="item.key">
5400                <li class="flex items-center" style="padding: 20px 0; gap: 16px;">
5401                  <button
5402                    @click="$store.favorites.remove(item.key)"
5403                    class="shrink-0 rounded-full p-1 transition-colors hover:text-red-500"
5404                    style="color: rgba(0,0,0,0.3);"
5405                    :aria-label="'Remove ' + item.title"
5406                  >
5407                    <svg width="19" height="19" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-width="2" d="m6 6 12 12m0-12-12 12"/></svg>
5408                  </button>
5409                  <a :href="item.url" class="block shrink-0 overflow-hidden bg-gray-100" style="width: 90px; height: 90px;">
5410                    <img :src="item.image" :alt="item.title" class="h-full w-full object-cover" loading="lazy" width="90" height="90">
5411                  </a>
5412                  <div class="min-w-0 flex-1">
5413                    <p style="font-size: 16px; font-weight: 300; line-height: 18px; color: black;" x-text="item.vendor || ''"></p>
5414                    <a :href="item.url" class="line-clamp-1" style="font-size: 16px; font-weight: 600; line-height: 18px; color: black;" x-text="item.title"></a>
5415                    <p class="text-xs text-gray-600" x-text="item.colour || (item.hasColours ? 'Colour TBC' : '')"></p>
5416                  </div>
5417                </li>
5418              </template>
5419            </ul>
5420          </template>
5421        </div><div class="shrink-0" style="padding: 0 40px 48px;">
5422          <template x-if="$store.favorites.count > 0">
5423            <div>
5424              <div class="drawer-divider" style="padding-top: 28px;">
5425                <p style="font-size: 23px; font-weight: 300; line-height: 30px;">Get a quote for these products.</p>
5426              </div>
5427              <div class="drawer-divider" style="margin-top: 24px; padding-top: 24px;">
5428                <p style="font-size: 15px; line-height: 20px;">Once submitted, one of our team will provide a more accurate quote based on the information provided. We aim to have a quote back to you within 5 working days.</p>
5429              </div>
5430              <button
5431                @click="$store.modals.close('favorites'); setTimeout(() => $store.modals.open('quoteRequest'), 300)"
5432                class="drawer-cta-btn inline-flex w-full items-center justify-center text-center transition"
5433                style="margin-top: 24px; min-height: 79px; border-radius: 50px; font-size: 27px; font-weight: 300;"
5434              >
5435                Start quote request
5436              </button>
5437            </div>
5438          </template>
5439        </div>
5440      </div>
5441    </template>
5442  </div>
5443</data-island>
5444
5445
5446    
5447    <style>
5448  :root {
5449    --color-quote-accent: #2B3990;
5450  }
5451
5452  /* Modal inputs */
5453  .qr-input,
5454  .qr-select {
5455    width: 100%;
5456    min-height: 2.15rem;
5457    border: 0.666px solid black;
5458    border-radius: 9999px;
5459    padding: 0.5rem 1rem;
5460    background: transparent;
5461    color: #111827;
5462    font-size: 0.875rem;
5463    transition: border-color 0.2s ease, box-shadow 0.2s ease;
5464  }
5465
5466  .qr-textarea {
5467    width: 100%;
5468    border: 0.75px solid black;
5469    border-radius: 10px;
5470    padding: 0.75rem 1rem;
5471    background: transparent;
5472    color: #111827;
5473    font-size: 0.875rem;
5474    resize: vertical;
5475    transition: border-color 0.2s ease, box-shadow 0.2s ease;
5476  }
5477
5478  .qr-input:focus,
5479  .qr-select:focus,
5480  .qr-textarea:focus {
5481    outline: none;
5482    border-color: var(--color-quote-accent, #2B3990);
5483    box-shadow: 0 0 0 3px rgba(43, 57, 144, 0.1);
5484  }
5485
5486  /* Ensure date & select inputs stay pill-shaped */
5487  input[type="date"].qr-input,
5488  select.qr-select {
5489    border-radius: 9999px !important;
5490    padding-left: 1rem;
5491    padding-right: 2.5rem;
5492  }
5493
5494  input[type="date"].qr-input::-webkit-calendar-picker-indicator {
5495    opacity: 0.4;
5496    cursor: pointer;
5497  }
5498
5499  /* Budget slider */
5500  .qr-slider {
5501    -webkit-appearance: none;
5502    appearance: none;
5503    width: 100%;
5504    height: 28px;
5505    background: transparent;
5506    outline: none;
5507    cursor: pointer;
5508    position: relative;
5509    z-index: 2;
5510    touch-action: none;
5511    margin: 0;
5512    padding: 0;
5513  }
5514
5515  .qr-slider::-webkit-slider-runnable-track {
5516    height: 6px;
5517    border-radius: 9999px;
5518    background: var(--slider-track, #e5e7eb);
5519    cursor: pointer;
5520  }
5521
5522  .qr-slider::-webkit-slider-thumb {
5523    -webkit-appearance: none;
5524    appearance: none;
5525    width: 24px;
5526    height: 24px;
5527    border-radius: 50%;
5528    background: #658a6a;
5529    cursor: grab;
5530    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
5531    margin-top: -9px;
5532    border: 2px solid #fff;
5533  }
5534
5535  .qr-slider::-webkit-slider-thumb:active {
5536    cursor: grabbing;
5537    transform: scale(1.1);
5538    box-shadow: 0 3px 8px rgba(0, 0, 0, 0.2);
5539  }
5540
5541  .qr-slider::-moz-range-track {
5542    height: 6px;
5543    border-radius: 9999px;
5544    background: var(--slider-track, #e5e7eb);
5545    cursor: pointer;
5546  }
5547
5548  .qr-slider::-moz-range-thumb {
5549    width: 24px;
5550    height: 24px;
5551    border: 2px solid #fff;
5552    border-radius: 50%;
5553    background: #658a6a;
5554    cursor: grab;
5555    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
5556  }
5557
5558  .qr-slider::-moz-range-thumb:active {
5559    cursor: grabbing;
5560  }
5561
5562  .qr-slider::-moz-range-progress {
5563    height: 6px;
5564    border-radius: 9999px;
5565    background: #658a6a;
5566  }
5567
5568  /* Pill buttons for per-product fields */
5569  .qr-pill {
5570    display: inline-flex;
5571    height: 23px;
5572    align-items: center;
5573    justify-content: center;
5574    gap: 0.25rem;
5575    border: 0.666px solid black;
5576    border-radius: 9999px;
5577    padding: 0 0.75rem;
5578    background: #eee;
5579    color: #111827;
5580    font-size: 10.65px;
5581    font-weight: 400;
5582    cursor: pointer;
5583    transition: border-color 0.15s, background 0.15s;
5584    white-space: nowrap;
5585    position: relative;
5586  }
5587
5588  .qr-pill:hover {
5589    border-color: black;
5590    background: #e2e2e2;
5591  }
5592
5593  .qr-pill--active {
5594    border-color: black;
5595    color: #111827;
5596    background: #e2e2e2;
5597  }
5598
5599  .qr-pill--required {
5600    border-color: #dc2626;
5601  }
5602
5603  /* Pills grid: fixed equal columns across all rows */
5604  .qr-pills-row {
5605    display: grid;
5606    grid-template-columns: repeat(3, 1fr);
5607  }
5608
5609  /* Popover for pill fields */
5610  .qr-popover {
5611    position: absolute;
5612    top: calc(100% + 6px);
5613    left: 0;
5614    z-index: 50;
5615    min-width: 14rem;
5616    border: 0.666px solid black;
5617    border-radius: 8px;
5618    background: #fff;
5619    padding: 0.75rem;
5620    box-shadow: 0 3px 7px 0 rgba(0, 0, 0, 0.4);
5621  }
5622
5623  /* Product item rows */
5624  .qr-product-row {
5625    border-bottom: 1px solid black !important;
5626    padding: 0.75rem 0;
5627  }
5628
5629  .qr-product-row:last-child {
5630    border-bottom: none !important;
5631  }
5632
5633  /* Submit button */
5634  .qr-submit {
5635    display: flex;
5636    height: 70px;
5637    width: 100%;
5638    max-width: 351px;
5639    margin-left: auto;
5640    margin-right: auto;
5641    align-items: center;
5642    justify-content: center;
5643    border-radius: 50px;
5644    border: 2px solid #4B4D72;
5645    padding: 0.85rem 1.5rem;
5646    background: #4B4D72;
5647    color: #fff;
5648    font-size: 1.5rem;
5649    font-weight: 400;
5650    transition: opacity 0.2s ease, transform 0.2s ease;
5651  }
5652
5653  .qr-submit:hover {
5654    background: #3d3f5e;
5655    border-color: #3d3f5e;
5656    transform: translateY(-1px);
5657  }
5658
5659  .qr-submit:disabled {
5660    opacity: 0.4;
5661    cursor: not-allowed;
5662    transform: none;
5663  }
5664
5665  /* Outlined button */
5666  .qr-btn-outline {
5667    display: inline-flex;
5668    min-height: 2.75rem;
5669    align-items: center;
5670    justify-content: center;
5671    border: 1.5px solid #4B4D72;
5672    border-radius: 9999px;
5673    padding: 0.65rem 1.5rem;
5674    background: transparent;
5675    color: #4B4D72;
5676    font-size: 0.875rem;
5677    font-weight: 600;
5678    transition: background-color 0.2s ease, color 0.2s ease;
5679  }
5680
5681  .qr-btn-outline:hover {
5682    background: #4B4D72;
5683    color: #fff;
5684  }
5685
5686  @media (max-width: 639px) {
5687    .qr-popover {
5688      position: fixed;
5689      top: auto;
5690      bottom: 0;
5691      left: 0;
5692      right: 0;
5693      min-width: 100%;
5694      border-radius: 8px 8px 0 0;
5695      padding: 1rem;
5696      box-shadow: 0 -3px 7px 0 rgba(0, 0, 0, 0.4);
5697    }
5698  }
5699
5700  /* Fix: Tailwind arbitrary rounded class not compiled */
5701  @media (min-width: 640px) {
5702    .sm\:rounded-\[24px\] {
5703      border-radius: 27px;
5704    }
5705  }
5706
5707  /* Fix: Tailwind sm:grid-cols-2 not compiled in this theme */
5708  @media (min-width: 640px) {
5709    [data-quote-request-modal] .sm\:grid-cols-2 {
5710      grid-template-columns: repeat(2, minmax(0, 1fr));
5711    }
5712  }
5713
5714  /* Make overlay scroll instead of modal body */
5715  #modals-modal:has([data-quote-request-modal]) {
5716    overflow-y: auto;
5717  }
5718
5719  /* Flex container: min-height instead of fixed height, always center */
5720  #modals-modal:has([data-quote-request-modal]) > div {
5721    height: auto;
5722    min-height: 100%;
5723    align-items: center;
5724  }
5725
5726  /* Card: remove max-height constraint, allow natural sizing, always rounded */
5727  #modals-modal:has([data-quote-request-modal]) #modal-slot {
5728    max-height: none !important;
5729    overflow: visible !important;
5730    border-radius: 27px;
5731    border: 1.75px solid black;
5732    box-shadow: 0px 4px 13px 2px rgba(0, 0, 0, 0.1);
5733  }
5734
5735  /* Fix: Tailwind sm:flex-nowrap not compiled */
5736  @media (min-width: 640px) {
5737    .qr-product-row {
5738      flex-wrap: nowrap;
5739    }
5740  }
5741
5742  /* Content div: match card rounding */
5743  [data-quote-request-modal] {
5744    border-radius: 27px;
5745    overflow: visible !important;
5746  }
5747
5748  /* All modal text defaults to black per Figma */
5749  [data-quote-request-modal] label,
5750  [data-quote-request-modal] h3,
5751  [data-quote-request-modal] p,
5752  [data-quote-request-modal] span {
5753    color: black;
5754  }
5755
5756  /* Preserve intentional non-black colors */
5757  [data-quote-request-modal] .text-gray-400 {
5758    color: #9ca3af !important;
5759  }
5760  [data-quote-request-modal] .text-emerald-600 {
5761    color: #059669 !important;
5762  }
5763  [data-quote-request-modal] .text-red-500 {
5764    color: #ef4444 !important;
5765  }
5766  /* Keep submit button text white */
5767  [data-quote-request-modal] .qr-submit span {
5768    color: #fff !important;
5769  }
5770
5771  /* Modal title letter spacing */
5772  [data-quote-request-modal] h2 {
5773    letter-spacing: 0px !important;
5774  }
5775
5776  /* All labels should be black per Figma */
5777  [data-quote-request-modal] label {
5778    color: black !important;
5779  }
5780
5781  /* Placeholder text should be grey, not blue */
5782  [data-quote-request-modal] textarea::placeholder,
5783  [data-quote-request-modal] input::placeholder {
5784    color: #9ca3af !important;
5785  }
5786</style>
5787
5788<data-island
5789  x-data="QuoteRequestForm"
5790  on="idle"
5791  x-cloakdata-webhook-url="https://print-room-chatbot-api.vercel.app/api/quote-request"
5792  data-turnstile-site-key="0x4AAAAAAETPnb_3iHel2J69"
5793>
5794  <template x-teleport="#modal-slot">
5795    <div
5796      x-show="$store.modals.modal.contents === 'quoteRequest'"
5797      class="flex w-full flex-col h-full"
5798      style="background: #FBFBF6;"
5799      data-quote-request-modal
5800    ><div class="shrink-0 px-5 py-4 sm:px-8 sm:py-5">
5801        <div class="flex items-center justify-between">
5802          <h2 x-show="!successMessage" class="font-bold" style="font-size: 2.75rem; letter-spacing: 0px; color: black;">Project quote request</h2>
5803          <div x-show="successMessage" class="flex-1"></div>
5804          <button
5805            @click.prevent="$store.modals.close('quoteRequest')"
5806            type="button"
5807            class="rounded-full p-2 text-gray-400 transition hover:text-gray-600"
5808          >
5809            <span class="sr-only">Close</span>
5810            <svg width="20" height="20" fill="none" viewBox="0 0 24 24">
5810<path stroke="currentColor" stroke-width="2" d="m6 6 12 12m0-12-12 12"/></svg>
5811          </button>
5812        </div>
5813      </div><div class="overflow-y-auto flex-1 px-5 py-5 sm:px-8 sm:py-6">
5814        <div class="mx-auto max-w-2xl">
5815          <template x-if="!successMessage">
5816            <form @submit.prevent="submitQuote" class="space-y-8"><section style="padding-bottom: 2rem;">
5817                <h3 class="text-sm font-normal" style="color: black;" x-text="'Selected products (' + ($store.chatQuote.active ? $store.chatQuote.count : $store.favorites.count) + ')'">Selected products</h3><template x-if="$store.chatQuote.active && $store.chatQuote.count > 0">
5818                  <div class="mt-3">
5819                    <template x-for="item in $store.chatQuote.items" :key="item.id">
5820                      <div class="qr-product-row flex items-start gap-3">
5821                        <div class="shrink-0 overflow-hidden rounded-lg bg-gray-100" style="width: 53px; height: 53px;">
5822                          <template x-if="item.image">
5823                            <img :src="item.image" :alt="item.title" class="h-full w-full object-cover" width="53" height="53">
5824                          </template>
5825                        </div>
5826                        <div class="min-w-0 flex-1">
5827                          <p class="text-sm font-semibold text-gray-900" x-text="item.title"></p>
5828                          <div class="mt-2 flex flex-wrap gap-2">
5829                            <span x-show="item.quantity" class="qr-pill" x-text="'Qty ' + item.quantity"></span>
5830                            <span x-show="item.colors && item.colors.length > 0" class="qr-pill" x-text="item.colors.join(', ')"></span>
5831                            <span x-show="item.sizes && item.sizes.length > 0" class="qr-pill" x-text="item.sizes.join(', ')"></span>
5832                            <span x-show="item.decorationMethod" class="qr-pill" x-text="item.decorationMethod"></span>
5833                          </div>
5834                        </div>
5835                      </div>
5836                    </template>
5837                  </div>
5838                </template><template x-if="!$store.chatQuote.active && $store.favorites.count > 0">
5839                  <div class="mt-3" x-data="{ openPill: null }"
5840                    @click.document="if (openPill && !$event.target.closest('.qr-pill') && !$event.target.closest('.qr-popover')) openPill = null">
5841                    <template x-for="item in $store.favorites.items" :key="item.key">
5842                      <div class="qr-product-row flex items-center gap-3 flex-wrap sm:flex-nowrap" x-init="if(item.handle === 'mystery-product') { $nextTick(() => openPill = item.key + '-notes') }">
5843                        <template x-if="item.handle === 'mystery-product'">
5844                          <div class="shrink-0 flex items-center justify-center" style="width: 53px; height: 53px;">
5845                            <span style="width: 33px; height: 33px; color: black;"><span class="h-full w-full fill-current">
5846  <svg
5847    aria-hidden="true"
5848    focusable="false"
5849    role="presentation"
5850    class="icon icon-product-question-mark"
5851    viewBox="0 0 24 24"
5852  >
5853    <path d="M12 1c6.075 0 11 4.925 11 11s-4.925 11-11 11S1 18.075 1 12 5.925 1 12 1Zm0 1.375a9.625 9.625 0 1 0 0 19.25 9.625 9.625 0 0 0 0-19.25Zm0 13.75.112.006a1.031 1.031 0 1 1-.224 0l.112-.006Zm3.35-7.646a3.437 3.437 0 0 1-2.204 4.012.688.688 0 0 0-.452.553l-.007.096v.922a.687.687 0 0 1-1.368.094l-.007-.094v-.921c0-.823.488-1.562 1.233-1.89l.143-.056a2.062 2.062 0 1 0-2.745-2.094l-.006.15a.688.688 0 1 1-1.374-.001 3.438 3.438 0 0 1 6.787-.771Z"></path>
5854  </svg>
5855</span>
5856</span>
5857                          </div>
5858                        </template>
5859                        <template x-if="item.handle !== 'mystery-product'">
5860                          <div class="shrink-0 overflow-hidden rounded-lg bg-gray-100" style="width: 53px; height: 53px;">
5861                            <img :src="item.image" :alt="item.title" class="h-full w-full object-cover" width="53" height="53">
5862                          </div>
5863                        </template>
5864                        <div class="min-w-0" style="width: 5rem; flex: 0 0 5rem;">
5865                          <p style="font-size: 10px; font-weight: 300; line-height: 11px; color: black;" x-text="item.vendor || ''"></p>
5866                          <p class="truncate" style="font-size: 10px; font-weight: 600; line-height: 11px; color: black;" x-text="item.title"></p>
5867                        </div><div class="qr-pills-row flex-1" style="margin-left: 1rem; gap: 0.75rem; align-items: center;">
5868                            <div class="relative" x-show="item.hasColours">
5869                              <button type="button" class="qr-pill" :class="{ 'qr-pill--active': openPill === item.key + '-colour' }"
5870                                @click="openPill = openPill === item.key + '-colour' ? null : item.key + '-colour'; if (openPill) $store.favorites.loadColourChoices(item.key)">
5871                                <span x-text="item.colour || 'Colour TBC'"></span>
5872                                <svg class="h-3 w-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/></svg>
5873                              </button>
5874                              <div x-show="openPill === item.key + '-colour'" x-transition class="qr-popover" style="min-width: 10rem; max-height: 15rem; overflow-y: auto;">
5875                                <button
5876                                  type="button"
5877                                  data-quote-colour-tbc
5878                                  class="block w-full text-left text-sm py-1"
5879                                  :disabled="!$store.favorites.canSelectTbc(item)"
5880                                  :class="!$store.favorites.canSelectTbc(item) ? 'opacity-40 cursor-not-allowed' : ''"
5881                                  @click="if ($store.favorites.rekey(item.key, { variantId: null, colour: null })) openPill = null"
5882                                >TBC (decide later)</button>
5883                                <p class="text-xs text-gray-600" x-show="!($store.favorites.colourChoicesByHandle[item.handle] || []).length">We'll confirm colour with you</p>
5884                                <template x-for="choice in ($store.favorites.colourChoicesByHandle[item.handle] || [])" :key="choice.variantId">
5885                                  <button type="button" class="block w-full text-left text-sm py-1" x-text="choice.label"
5886                                    :disabled="$store.favorites.colourChoiceTaken(item, choice)"
5887                                    :class="$store.favorites.colourChoiceTaken(item, choice) ? 'opacity-40 cursor-not-allowed' : ''"
5888                                    @click="if ($store.favorites.rekey(item.key, choice)) openPill = null"></button>
5889                                </template>
5890                              </div>
5891                            </div><div class="relative">
5892                              <button type="button" class="qr-pill" :class="{ 'qr-pill--active': openPill === item.key + '-qty' }" @click="openPill = openPill === item.key + '-qty' ? null : item.key + '-qty'">
5893                                <span x-text="'Quantity' + (item.quantity ? ' ' + (item.quantity >= 1000 ? '1000+' : item.quantity) : '')"></span>
5894                                <svg class="h-3 w-3 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/></svg>
5895                              </button>
5896                              <div x-show="openPill === item.key + '-qty'" x-transition class="qr-popover" style="min-width: 8rem; padding: 0.5rem 0.75rem;">
5897                                <div class="flex items-baseline gap-2">
5898                                  <span class="text-sm font-normal text-gray-900" x-text="item.quantity || item.moq || 24"></span>
5899                                  <span class="text-xs font-light text-gray-500">units</span>
5900                                </div>
5901                                <input x-show="item.sizeSplit === null"
5902                                  type="range"
5903                                  min="1"
5904                                  max="1000"
5905                                  step="1"
5906                                  class="qr-slider"
5907                                  style="height: 18px; margin-top: 2px;"
5908                                  :value="item.quantity || item.moq || 24"
5909                                  @input="$store.favorites.updateItemMeta(item.key, 'quantity', parseInt($event.target.value, 10))"
5910                                  :style="'--slider-track: linear-gradient(to right, #658a6a ' + ((item.quantity - 1) / 999 * 100) + '%, #e5e7eb ' + ((item.quantity - 1) / 999 * 100) + '%)'"
5911                                >
5912                                <label x-show="item.sizeOptions && item.sizeOptions.length" class="mt-2 flex items-center gap-2 text-xs">
5913                                  <input type="checkbox" :checked="item.sizeSplit !== null" @change="$store.favorites.setSizeSplit(item.key, $event.target.checked ? {} : null)">
5914                                  Split by size (optional)
5915                                </label>
5916                                <div x-show="item.sizeSplit !== null && item.sizeOptions && item.sizeOptions.length" class="mt-2 space-y-1">
5917                                  <template x-for="size in item.sizeOptions" :key="size">
5918                                    <label class="flex items-center gap-2 text-xs">
5919                                      <span x-text="size" class="w-10"></span>
5920                                      <input type="number" min="0" max="100000" step="1" class="w-20 border rounded px-1"
5921                                        :value="(item.sizeSplit || {})[size] || 0"
5922                                        @input="$store.favorites.setSizeSplit(item.key, { ...(item.sizeSplit || {}), [size]: parseInt($event.target.value, 10) || 0 })">
5923                                    </label>
5924                                  </template>
5925                                </div>
5926                              </div>
5927                            </div><div class="relative">
5928                              <button type="button" class="qr-pill" :class="{ 'qr-pill--active': openPill === item.key + '-artwork' || (item.artworks && item.artworks.length > 0) || item.artworkLink }" @click="openPill = openPill === item.key + '-artwork' ? null : item.key + '-artwork'">
5929                                <template x-if="item.artworks && item.artworks.length > 0">
5930                                  <span class="flex items-center gap-1">
5931                                    <svg class="h-3 w-3 shrink-0" style="color: #658a6a;" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/></svg>
5932                                    <span x-text="item.artworks.length === 1 ? '1 file' : item.artworks.length + ' files'"></span>
5933                                  </span>
5934                                </template>
5935                                <template x-if="item.artworkLink && !(item.artworks && item.artworks.length > 0)">
5936                                  <span class="flex items-center gap-1">
5937                                    <svg class="h-3 w-3 shrink-0" style="color: #658a6a;" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/></svg>
5938                                    <span>Artwork linked</span>
5939                                  </span>
5940                                </template>
5941                                <template x-if="!(item.artworks && item.artworks.length > 0) && !item.artworkLink">
5942                                  <span x-text="'Upload artwork \u2191'"></span>
5943                                </template>
5944                              </button>
5945                              <div x-show="openPill === item.key + '-artwork'" x-transition class="qr-popover" style="min-width: 14rem;">
5946                                <p class="mb-2 text-xs text-gray-500">Max <strong>5 files</strong>, <strong>10MB</strong> each</p><template x-if="item.artworks && item.artworks.length > 0">
5947                                  <div class="mb-2 space-y-3">
5948                                    <template x-for="(aw, awIdx) in item.artworks" :key="aw.fileName + awIdx">
5949                                      <div class="text-xs">
5950                                        <div class="flex items-center gap-1.5">
5951                                          <template x-if="aw.status === 'uploading'">
5952                                            <svg class="h-3 w-3 shrink-0 animate-spin text-gray-400" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"/></svg>
5953                                          </template>
5954                                          <template x-if="aw.status === 'done'">
5955                                            <svg class="h-3 w-3 shrink-0 text-emerald-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
5956                                          </template>
5957                                          <template x-if="aw.status === 'error'">
5958                                            <svg class="h-3 w-3 shrink-0 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
5958<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg>
5959                                          </template>
5960                                          <span class="flex-1 truncate" :class="aw.status === 'error' ? 'text-red-600' : 'text-gray-700'" x-text="aw.fileName"></span>
5961                                          <span class="shrink-0 text-gray-400" style="font-size: 10px;" x-text="aw.fileSize ? (aw.fileSize / 1024 < 1024 ? Math.round(aw.fileSize / 1024) + 'KB' : (aw.fileSize / (1024*1024)).toFixed(1) + 'MB') : ''"></span>
5962                                          <template x-if="aw.status === 'error'">
5963                                            <button type="button" class="shrink-0 text-blue-600 underline" @click="retryArtworkUpload(item.key, awIdx)">Retry</button>
5964                                          </template>
5965                                          <button type="button" class="shrink-0 text-red-400 hover:text-red-600" @click="removeArtwork(item.key, awIdx)" title="Remove file">
5966                                            <svg class="h-3 w-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg>
5967                                          </button>
5968                                        </div><template x-if="aw.status === 'done'">
5969                                          <div class="relative" style="margin-top: 3px; margin-left: 18px;" x-data="{ placementOpen: false }">
5970                                            <button
5971                                              type="button"
5972                                              @click="placementOpen = !placementOpen"
5973                                              class="flex w-full items-center justify-between"
5974                                              style="height: 20px; padding: 0 8px; font-size: 10px; border: 0.666px solid black; border-radius: 9999px; background: #eee; cursor: pointer;"
5975                                            >
5976                                              <span x-text="aw.placement || 'Placement…'" :style="aw.placement ? 'color: black' : 'color: #9ca3af'"></span>
5977                                              <svg :style="placementOpen ? 'transform: rotate(180deg)' : ''" width="6" height="4" viewBox="0 0 6 4" fill="none" style="margin-left: 4px; flex-shrink: 0; transition: transform 0.15s;">
5978                                                <path d="M0.5 0.5L3 3L5.5 0.5" stroke="black" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
5979                                              </svg>
5980                                            </button>
5981                                            <div
5982                                              x-show="placementOpen"
5983                                              x-transition
5984                                              @click.outside="placementOpen = false"
5985                                              style="position: absolute; top: calc(100% + 3px); left: 0; z-index: 60; background: white; border: 0.666px solid black; border-radius: 10px; padding: 0.35rem 0; min-width: 110px; box-shadow: 0 3px 7px 0 rgba(0,0,0,0.15);"
5986                                            >
5987                                              <template x-for="pl in ['Front','Left Chest','Right Chest','Back','Sleeve','Other']" :key="pl">
5988                                                <button
5989                                                  type="button"
5990                                                  class="block w-full text-left"
5991                                                  style="padding: 0.2rem 0.65rem; font-size: 10px; line-height: 13px; color: #4b5563; cursor: pointer; background: none; border: none;"
5992                                                  @click="updateArtworkPlacement(item.key, awIdx, pl); placementOpen = false"
5993                                                  @mouseover="$el.style.background = '#f3f4f6'"
5994                                                  @mouseout="$el.style.background = 'none'"
5995                                                  x-text="pl"
5996                                                ></button>
5997                                              </template>
5998                                            </div>
5999                                          </div>
6000                                        </template>
6001                                      </div>
6002                                    </template>
6003                                  </div>
6004                                </template><template x-if="!item.artworks || item.artworks.length < 5">
6005                                  <label class="flex cursor-pointer items-center justify-center gap-2 rounded-xl border border-dashed border-gray-300 px-4 py-2.5 text-sm text-gray-600 transition hover:border-gray-400">
6006                                    <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
6006<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v2a2 2 0 002 2h12a2 2 0 002-2v-2M7 10l5-5m0 0l5 5m-5-5v12"/></svg>
6007                                    <span x-text="item.artworks && item.artworks.length > 0 ? 'Add more files' : 'Select files'"></span>
6008                                    <input
6009                                      type="file"
6010                                      class="hidden"
6011                                      multiple
6012                                      accept=".png,.jpg,.jpeg,.svg,.pdf,.ai,.eps"
6013                                      @change="handlePerProductFileUpload($event, item.key)"
6014                                    >
6015                                  </label>
6016                                </template><div style="margin-top: 0.75rem; padding-top: 0.75rem; border-top: 1px solid #e5e7eb;">
6017                                  <p class="text-xs text-gray-500">For <strong>larger files</strong>: via shared link</p>
6018                                  <input
6019                                    type="url"
6020                                    class="qr-input text-sm"
6021                                    style="margin-top: 0.5rem; font-size: 0.75rem;"
6022                                    placeholder="Link address"
6023                                    :value="item.artworkLink || ''"
6024                                    @input="$store.favorites.updateItemMeta(item.key, 'artworkLink', $event.target.value)"
6025                                  >
6026                                  <p class="mt-1 text-gray-400" style="font-size: 9px;">Eg. Google drive, Dropbox</p>
6027                                </div>
6028                              </div>
6029                            </div><div class="relative">
6030                              <button type="button" class="qr-pill" :class="{ 'qr-pill--active': openPill === item.key + '-notes' || (item.notes && item.notes.length > 0), 'qr-pill--required': item.handle === 'mystery-product' && (!item.notes || !item.notes.trim()) }" @click="openPill = openPill === item.key + '-notes' ? null : item.key + '-notes'">
6031                                <span class="qr-pill-notes-text" x-text="item.notes && item.notes.length > 0 ? 'Notes added' : 'Notes\u2026'"></span>
6032                                <template x-if="item.handle === 'mystery-product'"><span style="color: #dc2626; margin-left: 2px;">*</span></template>
6033                              </button>
6034                              <div x-show="openPill === item.key + '-notes'" x-transition class="qr-popover" style="left: auto; right: 0;">
6035                                <label class="mb-1.5 block text-xs font-medium text-gray-500">Notes</label>
6036                                <textarea
6037                                  rows="3"
6038                                  class="qr-textarea text-sm"
6039                                  :placeholder="item.handle === 'mystery-product' ? 'Include the brand, product name or SKU you require' : 'Tell us how and where you would like your artwork printed.'"
6040                                  :value="item.notes || ''"
6041                                  @input="$store.favorites.updateItemMeta(item.key, 'notes', $event.target.value)"
6042                                ></textarea>
6043                              </div>
6044                            </div>
6045                        </div>
6046                      </div>
6047                    </template>
6048                    <template x-for="shortfall in $store.favorites.moqShortfalls()" :key="shortfall.id">
6049                      <p class="mt-2 text-xs text-red-600" role="alert" x-text="shortfall.title + ' total ' + shortfall.total + ' — minimum ' + shortfall.moq"></p>
6050                    </template>
6051                  </div>
6052                </template><template x-if="!$store.chatQuote.active && $store.favorites.count === 0">
6053                  <p class="mt-3 text-sm text-gray-400">No products added yet. Browse products and add items to your quote.</p>
6054                </template>
6055              </section><section style="padding-bottom: 2rem;">
6056                <div style="border: 0.75px solid black; border-radius: 10px; padding: 0.65rem 1.25rem;">
6057                  <p style="font-size: 11px; color: black; margin-bottom: 2px;">Additional notes:</p>
6058                  <textarea
6059                    id="project-description"
6060                    x-model="formData.description"
6061                    rows="2"
6062                    placeholder="Is there anything else we might need to know about your project?"
6063                    style="width: 100%; border: none; padding: 0; background: transparent; font-size: 11.5px; color: #111827; resize: vertical; outline: none;"
6064                  ></textarea>
6065                </div>
6066              </section><section style="padding-bottom: 2rem;">
6067                <label class="text-sm" style="color: black;">Your budget</label>
6068                <div class="flex items-center justify-between" style="margin-top: 0.25rem;">
6069                  <span class="text-xs text-gray-400">$500</span>
6070                  <span style="font-size: 1.95rem; font-weight: 400; line-height: 1; color: #658a6a;" x-text="'$' + Number(formData.budget).toLocaleString()"></span>
6071                  <span class="text-xs text-gray-400">$10,000+</span>
6072                </div>
6073                <div @mousedown.stop @touchstart.stop>
6074                  <input
6075                    type="range"
6076                    x-model.number="formData.budget"
6077                    @input="formData.budget = parseInt($event.target.value, 10)"
6078                    @click.stop
6079                    min="500"
6080                    max="10000"
6081                    step="500"
6082                    class="qr-slider"
6083                    :style="'--slider-track: linear-gradient(to right, #658a6a ' + ((formData.budget - 500) / 9500 * 100) + '%, #e5e7eb ' + ((formData.budget - 500) / 9500 * 100) + '%)'"
6084                  >
6085                </div>
6086              </section><section class="grid grid-cols-1 gap-4 sm:grid-cols-2">
6087                <div>
6088                  <label for="in-hand-date" class="mb-1.5 block text-sm">The date I need my merch*</label>
6089                  <input
6090                    type="date"
6091                    id="in-hand-date"
6092                    x-model="formData.inHandDate"
6093                    required
6094                    class="qr-input text-sm"
6095                    :min="(() => { let d = new Date(), a = 0; while (a < 7) { d.setDate(d.getDate() + 1); if (d.getDay() !== 0 && d.getDay() !== 6) a++; } return d.toISOString().split('T')[0]; })()"
6096                  >
6097                </div>
6098                <div x-data="{ locationOpen: false }">
6099                  <label class="mb-1.5 block text-sm" style="color: black;">I need it sent to*</label>
6100                  <div class="relative"><select x-model="formData.location" required class="sr-only" tabindex="-1" aria-hidden="true">
6101                      <option value="">Select location</option>
6102                      <optgroup label="New Zealand">
6103                        <option value="Northland">Northland</option>
6104                        <option value="Auckland">Auckland</option>
6105                        <option value="Waikato">Waikato</option>
6106                        <option value="Bay of Plenty">Bay of Plenty</option>
6107                        <option value="Gisborne">Gisborne</option>
6108                        <option value="Hawke's Bay">Hawke's Bay</option>
6109                        <option value="Taranaki">Taranaki</option>
6110                        <option value="Manawatū-Whanganui">Manawat&#363;-Whanganui</option>
6111                        <option value="Wellington">Wellington</option>
6112                        <option value="Tasman">Tasman</option>
6113                        <option value="Nelson">Nelson</option>
6114                        <option value="Marlborough">Marlborough</option>
6115                        <option value="West Coast">West Coast</option>
6116                        <option value="Canterbury">Canterbury</option>
6117                        <option value="Otago">Otago</option>
6118                        <option value="Southland">Southland</option>
6119                      </optgroup>
6120                      <optgroup label="Australia">
6121                        <option value="New South Wales">New South Wales</option>
6122                        <option value="Victoria">Victoria</option>
6123                        <option value="Queensland">Queensland</option>
6124                        <option value="Western Australia">Western Australia</option>
6125                        <option value="South Australia">South Australia</option>
6126                        <option value="Tasmania">Tasmania</option>
6127                        <option value="Australian Capital Territory">Australian Capital Territory</option>
6128                        <option value="Northern Territory">Northern Territory</option>
6129                      </optgroup>
6130                      <option value="International">International</option>
6131                    </select><button
6132                      type="button"
6133                      @click="locationOpen = !locationOpen"
6134                      class="qr-select flex w-full items-center justify-between text-sm"
6135                      style="cursor: pointer;"
6136                    >
6137                      <span x-text="formData.location || 'Select location'" :style="formData.location ? 'color: black' : 'color: #9ca3af'"></span>
6138                      <svg class="h-4 w-4 shrink-0 transition-transform" :style="locationOpen ? 'transform: rotate(180deg)' : ''" fill="none" stroke="currentColor" viewBox="0 0 24 24" style="color: black;">
6139                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
6140                      </svg>
6141                    </button><div
6142                      x-show="locationOpen"
6143                      x-transition
6144                      @click.outside="locationOpen = false"
6145                      style="position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 50; background: white; border: 0.666px solid black; border-radius: 15.5px; max-height: 232px; overflow-y: auto; padding: 0.75rem 0;"
6146                    >
6147                      <template x-for="loc in ['Northland','Auckland','Waikato','Bay of Plenty','Gisborne','Hawke\'s Bay','Taranaki','Manawat\u016b-Whanganui','Wellington','Tasman','Nelson','Marlborough','West Coast','Canterbury','Otago','Southland','New South Wales','Victoria','Queensland','Western Australia','South Australia','Tasmania','Australian Capital Territory','Northern Territory','International']" :key="loc">
6148                        <button
6149                          type="button"
6150                          class="block w-full text-left"
6151                          style="padding: 0.25rem 1rem; font-size: 12.65px; line-height: 13.313px; color: #4b5563; cursor: pointer; background: none; border: none;"
6152                          @click="formData.location = loc; locationOpen = false"
6153                          @mouseover="$el.style.background = '#f3f4f6'"
6154                          @mouseout="$el.style.background = 'none'"
6155                          x-text="loc"
6156                        ></button>
6157                      </template>
6158                    </div>
6159                  </div>
6160                </div>
6161                <div>
6162                  <label for="contact-name" class="mb-1.5 block text-sm">Your name*</label>
6163                  <input
6164                    type="text"
6165                    id="contact-name"
6166                    x-model="formData.name"
6167                    required
6168                    placeholder="Your name here"
6169                    class="qr-input text-sm"
6170                  >
6171                </div>
6172                <div>
6173                  <label for="contact-email" class="mb-1.5 block text-sm">Email*</label>
6174                  <input
6175                    type="email"
6176                    id="contact-email"
6177                    x-model="formData.email"
6178                    required
6179                    placeholder="[email protected]"
6180                    class="qr-input text-sm"
6181                  >
6182                </div>
6183                <div>
6184                  <label for="contact-phone" class="mb-1.5 block text-sm">Phone*</label>
6185                  <input
6186                    type="tel"
6187                    id="contact-phone"
6188                    x-model="formData.phone"
6189                    required
6190                    placeholder="Your phone number"
6191                    class="qr-input text-sm"
6192                  >
6193                </div>
6194                <div>
6195                  <label for="contact-company" class="mb-1.5 block text-sm">Company</label>
6196                  <input
6197                    type="text"
6198                    id="contact-company"
6199                    x-model="formData.company"
6200                    placeholder="Your company's name"
6201                    class="qr-input text-sm"
6202                  >
6203                </div>
6204                <div x-data="{ heardAboutOpen: false }" class="sm:col-span-2"><label id="heard-about-label" class="mb-1.5 block text-sm" style="color: black;">How did you hear about us?*</label>
6205                  <div class="relative"><select x-model="formData.heardAbout" required class="sr-only" tabindex="-1" aria-hidden="true">
6206                      <option value="">Select an option</option><option value="Google search">Google search</option><option value="Social media">Social media</option><option value="Referral or word of mouth">Referral or word of mouth</option><option value="Repeat customer">Repeat customer</option><option value="Saw our work in the wild">Saw our work in the wild</option><option value="Email or newsletter">Email or newsletter</option><option value="Event or trade show">Event or trade show</option><option value="Other">Other</option><option value="Prefer not to say">Prefer not to say</option></select><button
6207                      type="button"
6208                      @click="heardAboutOpen = !heardAboutOpen"
6209                      :aria-expanded="heardAboutOpen"
6210                      aria-labelledby="heard-about-label"
6211                      class="qr-select flex w-full items-center justify-between text-sm"
6212                      style="cursor: pointer;"
6213                    >
6214                      <span x-text="formData.heardAbout || 'Select an option'" :style="formData.heardAbout ? 'color: black' : 'color: #9ca3af'"></span>
6215                      <svg class="h-4 w-4 shrink-0 transition-transform" :style="heardAboutOpen ? 'transform: rotate(180deg)' : ''" fill="none" stroke="currentColor" viewBox="0 0 24 24" style="color: black;">
6216                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
6217                      </svg>
6218                    </button><div
6219                      x-show="heardAboutOpen"
6220                      x-transition
6221                      @click.outside="heardAboutOpen = false"
6222                      style="position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 50; background: white; border: 0.666px solid black; border-radius: 15.5px; max-height: 232px; overflow-y: auto; padding: 0.75rem 0;"
6223                    >
6224                      <template x-for='opt in ["Google search","Social media","Referral or word of mouth","Repeat customer","Saw our work in the wild","Email or newsletter","Event or trade show","Other","Prefer not to say"]' :key="opt">
6225                        <button
6226                          type="button"
6227                          class="block w-full text-left"
6228                          style="padding: 0.25rem 1rem; font-size: 12.65px; line-height: 13.313px; color: #4b5563; cursor: pointer; background: none; border: none;"
6229                          @click="selectHeardAbout(opt); heardAboutOpen = false"
6230                          @mouseover="$el.style.background = '#f3f4f6'"
6231                          @mouseout="$el.style.background = 'none'"
6232                          x-text="opt"
6233                        ></button>
6234                      </template>
6235                    </div>
6236                  </div><p x-show="formData.heardAbout === 'Social media'" x-transition class="mt-1.5 text-xs" style="color: #6b7280;">
6237                    Instagram, Facebook, TikTok or LinkedIn
6238                  </p><div
6239                    x-show="formData.heardAbout === 'Referral or word of mouth' || formData.heardAbout === 'Other'"
6240                    x-transition
6241                    class="mt-3"
6242                  >
6243                    <label for="contact-heard-detail" class="mb-1.5 block text-sm" x-text="formData.heardAbout === 'Other' ? 'Tell us more*' : 'Who referred you? (optional)'"></label>
6244                    <input
6245                      type="text"
6246                      id="contact-heard-detail"
6247                      x-model="formData.heardAboutDetail"
6248                      :required="formData.heardAbout === 'Other'"
6249                      :placeholder="formData.heardAbout === 'Other' ? 'How you found us' : 'Their name or company'"
6250                      class="qr-input text-sm"
6251                    >
6252                  </div>
6253                </div>
6254              </section><template x-if="errorMessage">
6255                <div class="rounded-2xl px-4 py-3 text-center" style="border: 1px solid #e5e7eb; background: #FFFBEB;">
6256                  <p class="text-sm" style="color: #92400e;">
6257                    <span style="font-size: 1.25rem; vertical-align: middle; margin-right: 0.25rem;">&#128578;</span>
6258                    <span x-text="errorMessage"></span>
6259                  </p>
6260                </div>
6261              </template><button
6262                type="submit"
6263                class="qr-submit"
6264                style="margin-top: 2.5rem;"
6265                :disabled="submitting || ($store.favorites.count === 0 && !$store.chatQuote.active) || (!$store.chatQuote.active && $store.favorites.moqShortfalls().length > 0)"
6266              >
6267                <span x-show="!submitting">Submit quote request</span>
6268                <span x-show="submitting" class="flex items-center justify-center gap-2">
6269                  <svg class="h-4 w-4 animate-spin" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
6270                    <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
6271                    <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
6272                  </svg>
6273                  Sending...
6274                </span>
6275              </button>
6276            </form>
6277          </template><template x-if="successMessage">
6278            <div class="flex flex-col items-center justify-center text-center" style="padding: 3rem 1.5rem 4rem;"><img src="//printroom.co/cdn/shop/t/59/assets/success-thumbs-up.svg?v=51729750037822013731787098435" alt="Success" width="141" height="179" style="width: 141px; height: 179px;">
6279
6280              <h3 style="margin-top: 1.5rem; font-size: clamp(48px, 12vw, 80px); font-weight: 300; line-height: 1; color: black;">Success</h3>
6281
6282              <div style="margin-top: 3rem; max-width: 414px; font-size: clamp(18px, 4vw, 25px); line-height: 1.16; color: black; text-align: center;">
6283                <p style="margin: 0;">Nice! Your quote request has successfully been submitted.
6284                Our team will try and have a quote back to you within 1 working day.</p>
6285                <p style="margin: 1.5rem 0 0;">In the meantime, a confirmation email has been sent to you.</p>
6286              </div>
6287
6288              <a
6289                href="/collections/product-library"
6290                @click="$store.modals.close('quoteRequest'); successMessage = ''"
6291                class="flex items-center justify-center"
6292                style="margin-top: 2.5rem; width: min(300px, 80vw); max-width: 100%; height: 64px; border: 2.7px solid #4B4D72; border-radius: 40px; font-size: clamp(18px, 5vw, 25px); font-weight: 400; color: #4B4D72; letter-spacing: -1.24px; text-decoration: none; transition: background-color 0.2s ease, color 0.2s ease;"
6293                onmouseover="this.style.backgroundColor='#4B4D72';this.style.color='#fff'"
6294                onmouseout="this.style.backgroundColor='transparent';this.style.color='#4B4D72'"
6295              >
6296                Browse more products
6297              </a>
6298            </div>
6299          </template>
6300        </div>
6301      </div>
6302    </div>
6303  </template>
6304</data-island>
6305
6306
6307    
6308    
6309    
6310
6311    
6312    <style>
6313  .cwp-overlay {
6314    position: fixed;
6315    top: var(--header-group-height, 119px);
6316    left: 0;
6317    right: 0;
6318    bottom: 0;
6319    z-index: 999;
6320    display: flex;
6321    align-items: center;
6322    justify-content: center;
6323    backdrop-filter: blur(6px);
6324    -webkit-backdrop-filter: blur(6px);
6325    background: rgba(247, 247, 247, 0.6);
6326    opacity: 0;
6327    transition: opacity 0.3s ease;
6328  }
6329
6330  .cwp-card {
6331    position: relative;
6332    width: 100%;
6333    max-width: 598px;
6334    margin: 1rem;
6335    background: #FBFBF6;
6336    border: 1.565px solid black;
6337    border-radius: 23px;
6338    box-shadow: 0 3.5px 11.5px 1.75px rgba(0, 0, 0, 0.1);
6339    padding: 2.5rem 3rem 2.5rem;
6340    overflow: visible;
6341  }
6342
6343  .cwp-close {
6344    position: absolute;
6345    top: 1.25rem;
6346    right: 1.25rem;
6347    background: none;
6348    border: none;
6349    cursor: pointer;
6350    padding: 0.5rem;
6351    color: black;
6352  }
6353
6354  .cwp-title {
6355    font-size: 70px;
6356    font-weight: 300;
6357    line-height: 1;
6358    color: black;
6359    margin: 0 0 1.5rem;
6360  }
6361
6362  .cwp-body {
6363    font-size: 19px;
6364    line-height: 22px;
6365    color: black;
6366    margin: 0 0 1rem;
6367  }
6368
6369  .cwp-body + .cwp-body {
6370    margin-top: 1rem;
6371  }
6372
6373  .cwp-btn {
6374    display: inline-flex;
6375    align-items: center;
6376    justify-content: center;
6377    margin-top: 1.25rem;
6378    height: 37px;
6379    padding: 0 1.5rem;
6380    background: white;
6381    border: 0.722px solid black;
6382    border-radius: 29px;
6383    font-size: 21.67px;
6384    font-weight: 400;
6385    color: black;
6386    cursor: pointer;
6387    transition: background 0.2s ease;
6388  }
6389
6390  .cwp-btn:hover {
6391    background: #f0f0f0;
6392  }
6393
6394  .cwp-pointer-left {
6395    position: fixed;
6396    left: 240px;
6397    top: 50%;
6398    transform: translateY(-50%) rotate(-15deg);
6399    width: 240px;
6400    opacity: 0;
6401    transition: opacity 0.6s ease;
6402    pointer-events: none;
6403    z-index: 1000;
6404  }
6405  .cwp-pointer-left.visible {
6406    opacity: 1;
6407    animation: cwp-bob-left 1.8s ease-in-out infinite;
6408  }
6409
6410  .cwp-pointer-up {
6411    position: fixed;
6412    top: calc(var(--header-group-height, 119px) - 60px);
6413    right: 60px;
6414    width: 180px;
6415    opacity: 0;
6416    transition: opacity 0.6s ease;
6417    pointer-events: none;
6418    z-index: 1000;
6419  }
6420  .cwp-pointer-up.visible {
6421    opacity: 1;
6422    animation: cwp-bob-up 1.8s ease-in-out infinite;
6423  }
6424
6425  @keyframes cwp-bob-left {
6426    0%, 100% { transform: translateY(-50%) rotate(-15deg) translateX(0); }
6427    50% { transform: translateY(-50%) rotate(-15deg) translateX(-10px); }
6428  }
6429
6430  @keyframes cwp-bob-up {
6431    0%, 100% { transform: translateY(0); }
6432    50% { transform: translateY(-10px); }
6433  }
6434
6435  @media (max-width: 639px) {
6436    .cwp-card {
6437      padding: 2rem 1.5rem;
6438    }
6439
6440    .cwp-title {
6441      font-size: 48px;
6442    }
6443
6444    .cwp-body {
6445      font-size: 16px;
6446      line-height: 20px;
6447    }
6448
6449    .cwp-btn {
6450      font-size: 18px;
6451    }
6452
6453    .cwp-pointer-left,
6454    .cwp-pointer-up {
6455      display: none;
6456    }
6457  }
6458</style>
6459
6460    
6461    <style>
6462  /* ── "Can't find something?" scroll-triggered tab ── */
6463  .cft-container {
6464    position: fixed;
6465    right: 0;
6466    bottom: 100px;
6467    z-index: 998;
6468    display: none;
6469    font-family: 'DM Sans', sans-serif;
6470  }
6471
6472  /* ── Tab state (collapsed) ── */
6473  .cft-tab {
6474    position: relative;
6475    width: 77px;
6476    height: 96px;
6477    cursor: pointer;
6478    opacity: 0;
6479    transform: translateX(20px);
6480    transition: opacity 0.4s ease, transform 0.4s ease;
6481  }
6482
6483  .cft-tab-bg {
6484    position: absolute;
6485    inset: 0;
6486    display: flex;
6487    align-items: center;
6488    justify-content: center;
6489  }
6490
6491  .cft-tab-bg-inner {
6492    width: 96px;
6493    height: 77px;
6494    flex-shrink: 0;
6495    transform: rotate(90deg);
6496    background: var(--cant-find-bg, #EFFE9C);
6497    border-bottom: 1.03px solid black;
6498    border-left: 1.03px solid black;
6499    border-right: 1.03px solid black;
6500    border-top: none;
6501    border-radius: 0 0 16px 16px;
6502    box-shadow: -2.94px 3.13px 5.88px 0px rgba(0, 0, 0, 0.2);
6503  }
6504
6505  .cft-tab-icon {
6506    position: absolute;
6507    top: 5%;
6508    left: 10%;
6509    width: 65%;
6510    height: 50%;
6511    background-size: contain;
6512    background-repeat: no-repeat;
6513    background-position: center;
6514  }
6515
6516  .cft-tab-text {
6517    position: absolute;
6518    bottom: 13%;
6519    left: 0;
6520    right: 0;
6521    font-weight: 600;
6522    font-size: 10px;
6523    line-height: 11.3px;
6524    color: black;
6525    text-align: center;
6526  }
6527
6528  .cft-tab:hover {
6529    transform: translateX(0) scale(1.04);
6530  }
6531
6532  /* ── Card state (expanded) — ~3× original size ── */
6533  .cft-card {
6534    position: relative;
6535    width: 300px;
6536    height: 200px;
6537    opacity: 0;
6538    transform: translateX(20px);
6539    transition: opacity 0.4s ease, transform 0.4s ease;
6540    cursor: default;
6541  }
6542
6543  .cft-card-bg {
6544    position: absolute;
6545    inset: 0;
6546  }
6547
6548  .cft-card-bg-inner {
6549    width: 100%;
6550    height: 100%;
6551    background: var(--cant-find-bg, #EFFE9C);
6552    border: 0.75px solid black;
6553    border-right: none;
6554    border-radius: 20px 0 0 20px;
6555    box-shadow: -1.17px 2.34px 2.34px 0px rgba(0, 0, 0, 0.14);
6556  }
6557
6558  .cft-card-content {
6559    position: absolute;
6560    inset: 0;
6561    z-index: 1;
6562    padding: 18px 22px;
6563  }
6564
6565  .cft-card-close {
6566    position: absolute;
6567    top: 8px;
6568    right: 8px;
6569    z-index: 2;
6570    background: none;
6571    border: none;
6572    cursor: pointer;
6573    padding: 4px;
6574    color: black;
6575    opacity: 0.5;
6576    transition: opacity 0.2s;
6577    line-height: 1;
6578  }
6579
6580  .cft-card-close:hover {
6581    opacity: 1;
6582  }
6583
6584  .cft-card-title {
6585    font-weight: 500;
6586    font-size: 18px;
6587    line-height: 20px;
6588    color: black;
6589    margin: 0 0 10px;
6590  }
6591
6592  .cft-card-body {
6593    font-weight: 400;
6594    font-size: 13px;
6595    line-height: 16px;
6596    color: black;
6597    margin: 0;
6598    max-width: 180px;
6599  }
6600
6601  .cft-card-link {
6602    font-weight: 400;
6603    font-size: 22px;
6604    line-height: 24px;
6605    color: black;
6606    text-decoration: underline;
6607    cursor: pointer;
6608    background: none;
6609    border: none;
6610    padding: 0;
6611    font-family: inherit;
6612    position: absolute;
6613    bottom: 18px;
6614    left: 22px;
6615    z-index: 1;
6616  }
6617
6618  .cft-card-link:hover {
6619    opacity: 0.7;
6620  }
6621
6622  .cft-card-doodle {
6623    position: absolute;
6624    bottom: -2px;
6625    right: 2px;
6626    width: 110px;
6627    height: 65px;
6628    transform: rotate(-24.8deg);
6629    pointer-events: none;
6630    z-index: 1;
6631    background-size: contain;
6632    background-repeat: no-repeat;
6633    background-position: center;
6634  }
6635
6636  /* ── Visible states (applied by JS) ── */
6637  .cft-tab.visible,
6638  .cft-card.visible {
6639    opacity: 1;
6640    transform: translateX(0);
6641  }
6642
6643  /* ── Hide when favorites drawer is open ── */
6644  body:has([data-favorites-drawer]:not([style*="display: none"])) .cft-container {
6645    display: none !important;
6646  }
6647
6648  /* ── Mobile adjustments ── */
6649  @media (max-width: 639px) {
6650    .cft-container {
6651      bottom: 80px;
6652    }
6653
6654    .cft-tab {
6655      width: 66px;
6656      height: 82px;
6657    }
6658
6659    .cft-tab-bg-inner {
6660      width: 82px;
6661      height: 66px;
6662    }
6663
6664    .cft-tab-text {
6665      font-size: 9px;
6666      line-height: 10px;
6667    }
6668
6669    .cft-card {
6670      width: 270px;
6671      height: 180px;
6672    }
6673  }
6674</style>
6675
6676    
6677    <div id="shopify-section-ai-chatbot" class="shopify-section contents"><link href="//printroom.co/cdn/shop/t/59/assets/ai-chatbot.css?v=112900874753543053291788472410" rel="stylesheet" type="text/css" media="all" />
6678<data-island
6679    x-data="
6680      AIChatbot({
6681        apiEndpoint: &quot;https:\/\/print-room-chatbot-api.vercel.app\/&quot;,
6682        questionsApiUrl: &quot;https:\/\/print-room-chatbot-api.vercel.app\/&quot;,
6683        welcomeMessage: &quot;Hi! I&#39;m here to help you with your printing needs. How can I assist you today?&quot;,
6684        unavailableMessage: &quot;Chat is temporarily unavailable. Please request a quote or contact us directly.&quot;,
6685        suggestedPrompts: []
6686      })
6687    "
6688    src="ai-chatbot"
6689    on="idle"
6690    id="ai-chatbot-ai-chatbot"
6691    class="ai-chatbot"
6692    data-color-scheme="scheme1"
6693  ><button
6694      @click="toggle()"
6695      class="ai-chatbot__trigger"
6696      :class="{ 'ai-chatbot__trigger--hidden': isOpen }"
6697      aria-label="Chat with us"
6698      type="button"
6699    >
6700      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
6701        <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
6702      </svg>
6703      <span>Chat with us</span>
6704    </button><template x-teleport="body">
6705      <div
6706        x-show="isOpen"
6707        x-transition:enter="ai-chatbot-enter"
6708        x-transition:enter-start="ai-chatbot-enter"
6709        x-transition:enter-end="ai-chatbot-enter-active"
6710        x-transition:leave="ai-chatbot-leave"
6711        x-transition:leave-start="ai-chatbot-leave"
6712        x-transition:leave-end="ai-chatbot-leave-active"
6713        class="ai-chatbot__window"
6714        :class="{ 'ai-chatbot__window--minimized': isMinimized }"
6715        data-color-scheme="scheme1"
6716        role="dialog"
6717        aria-label="Chat with us"
6718        @keydown.escape="close()"
6719      ><div class="ai-chatbot__header">
6720          <div class="ai-chatbot__header-title">
6721            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
6722              <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
6723            </svg>
6724            <span>Chat with us</span>
6725          </div>
6726          <div class="ai-chatbot__header-actions">
6727            <button
6728              x-show="messages.length > 0 && !isMinimized"
6729              @click="clearHistory()"
6730              class="ai-chatbot__header-btn"
6731              type="button"
6732              :disabled="isLoading"
6733              aria-label="Clear history"
6734            >
6735              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
6736                <polyline points="3 6 5 6 21 6"></polyline>
6737                <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path>
6738              </svg>
6739            </button>
6740            <button
6741              @click="minimize()"
6742              class="ai-chatbot__header-btn"
6743              type="button"
6744              :aria-label="isMinimized ? 'Expand' : 'Minimize'"
6745            >
6746              <template x-if="isMinimized">
6747                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
6748                  <polyline points="15 3 21 3 21 9"></polyline>
6749                  <polyline points="9 21 3 21 3 15"></polyline>
6750                  <line x1="21" y1="3" x2="14" y2="10"></line>
6751                  <line x1="3" y1="21" x2="10" y2="14"></line>
6752                </svg>
6753              </template>
6754              <template x-if="!isMinimized">
6755                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
6756                  <polyline points="4 14 10 14 10 20"></polyline>
6757                  <polyline points="20 10 14 10 14 4"></polyline>
6758                  <line x1="14" y1="10" x2="21" y2="3"></line>
6759                  <line x1="3" y1="21" x2="10" y2="14"></line>
6760                </svg>
6761              </template>
6762            </button>
6763            <button
6764              @click="close()"
6765              class="ai-chatbot__header-btn"
6766              type="button"
6767              aria-label="Close"
6768            >
6769              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
6770                <line x1="18" y1="6" x2="6" y2="18"></line>
6771                <line x1="6" y1="6" x2="18" y2="18"></line>
6772              </svg>
6773            </button>
6774          </div>
6775        </div><div class="ai-chatbot__body" x-show="!isMinimized"><div class="ai-chatbot__messages" x-ref="messagesContainer"><template x-if="messages.length === 0">
6776              <div class="ai-chatbot__welcome">
6777                <svg class="ai-chatbot__welcome-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
6778                  <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
6779                </svg>
6780                <p class="ai-chatbot__welcome-text" x-text="welcomeMessage"></p>
6781                <p class="ai-chatbot__welcome-subtext">Ask me anything about our products and services.</p>
6782              </div>
6783            </template><template x-for="(message, index) in messages" :key="message.id">
6784              <div
6785                class="ai-chatbot__message-row"
6786                :class="'ai-chatbot__message-row--' + message.role"
6787              ><template x-if="message.role === 'system'">
6788                  <div class="ai-chatbot__message-content ai-chatbot__message-content--system" x-text="message.content"></div>
6789                </template><template x-if="message.role !== 'system'">
6790                  <div class="ai-chatbot__message-stack"><template x-if="message.role === 'staff'">
6791                      <div class="ai-chatbot__staff-meta">
6792                        <span class="ai-chatbot__staff-avatar" x-text="message.initials"></span>
6793                        <span class="ai-chatbot__staff-name" x-text="message.senderName"></span>
6794                        <span
6795                          class="ai-chatbot__staff-time"
6796                          x-show="message.timestamp"
6797                          x-text="message.timestamp ? new Date(message.timestamp).toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' }) : ''"
6798                        ></span>
6799                      </div>
6800                    </template>
6801
6802                    <div
6803                      class="ai-chatbot__message-bubble"
6804                      :class="'ai-chatbot__message-bubble--' + message.role"
6805                    ><div class="ai-chatbot__message-content"><span x-text="message.content"></span><span x-show="message.isStreaming && message.content" class="ai-chatbot__cursor"></span></div><template x-if="message.role === 'assistant' && message.options && message.options.choices.length > 0">
6806                        <div class="ai-chatbot__options" :class="{ 'ai-chatbot__options--submitted': message.optionsSubmitted }">
6807                          <p class="ai-chatbot__options-prompt" x-show="message.options.prompt" x-text="message.options.prompt"></p>
6808                          <div class="ai-chatbot__options-list">
6809                            <template x-for="(choice, ci) in message.options.choices" :key="choice.value">
6810                              <button
6811                                @click="selectOption(index, choice.value)"
6812                                class="ai-chatbot__option-chip"
6813                                :class="{
6814                                  'ai-chatbot__option-chip--selected': message.selectedOptions.includes(choice.value),
6815                                  'ai-chatbot__option-chip--disabled': message.optionsSubmitted
6816                                }"
6817                                :disabled="message.optionsSubmitted"
6818                                type="button"
6819                                x-text="choice.label"
6820                              ></button>
6821                            </template>
6822                          </div>
6823                          <button
6824                            x-show="message.options.multiSelect && !message.optionsSubmitted && message.selectedOptions.length > 0"
6825                            @click="submitOptions(index)"
6826                            class="ai-chatbot__options-submit"
6827                            type="button"
6828                          >
6829                            Continue
6830                          </button>
6831                        </div>
6832                      </template>
6833                    </div>
6834                  </div>
6835                </template>
6836              </div>
6837            </template><template x-if="isLoading && messages.length > 0 && !messages[messages.length - 1].content">
6838              <div class="ai-chatbot__message-row ai-chatbot__message-row--assistant">
6839                <div class="ai-chatbot__message-stack">
6840                  <div class="ai-chatbot__message-bubble ai-chatbot__message-bubble--assistant ai-chatbot__message-bubble--typing">
6841                    <div class="ai-chatbot__typing" aria-label="Assistant is typing">
6842                      <span></span>
6843                      <span></span>
6844                      <span></span>
6845                    </div>
6846                  </div>
6847                </div>
6848              </div>
6849            </template>
6850          </div><div x-show="error" class="ai-chatbot__error">
6851            <svg class="ai-chatbot__error-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
6852              <circle cx="12" cy="12" r="10"></circle>
6853              <line x1="12" y1="8" x2="12" y2="12"></line>
6854              <line x1="12" y1="16" x2="12.01" y2="16"></line>
6855            </svg>
6856            <div class="ai-chatbot__error-content">
6857              <p class="ai-chatbot__error-text" x-text="error"></p>
6858              <div class="ai-chatbot__error-actions">
6859                <button @click="openQuoteRequest()" class="ai-chatbot__error-action" type="button">
6860                  Request a quote
6861                </button>
6862                <a href="/pages/contact-us" class="ai-chatbot__error-action">
6863                  Contact us
6864                </a>
6865              </div>
6866              <button @click="clearError()" class="ai-chatbot__error-dismiss" type="button">
6867                Dismiss
6868              </button>
6869            </div>
6870          </div><div x-show="messages.length === 0 && (getActivePrompts().length > 0 || questionsLoading)" class="ai-chatbot__prompts">
6871            <p class="ai-chatbot__prompts-label">Try asking:</p><template x-if="questionsLoading && getActivePrompts().length === 0">
6872              <div class="ai-chatbot__prompts-loading">
6873                <span class="ai-chatbot__prompt-skeleton"></span>
6874                <span class="ai-chatbot__prompt-skeleton"></span>
6875                <span class="ai-chatbot__prompt-skeleton"></span>
6876              </div>
6877            </template><template x-for="(prompt, index) in getActivePrompts()" :key="index">
6878              <button
6879                @click="useSuggestedPrompt(prompt)"
6880                class="ai-chatbot__prompt-btn"
6881                type="button"
6882                x-text="prompt"
6883              ></button>
6884            </template>
6885          </div><div x-show="ctaButton && ctaButton.show" x-cloak class="ai-chatbot__cta">
6886            <button
6887              @click="handleCTAClick()"
6888              class="ai-chatbot__cta-btn"
6889              type="button"
6890              x-text="ctaButton?.text || 'Request a Quote'"
6891            ></button>
6892            <button
6893              @click="dismissCTA()"
6894              class="ai-chatbot__cta-dismiss"
6895              type="button"
6896              aria-label="Dismiss"
6897            >
6898              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
6899                <line x1="18" y1="6" x2="6" y2="18"></line>
6900                <line x1="6" y1="6" x2="18" y2="18"></line>
6901              </svg>
6902            </button>
6903          </div><div x-show="conversationStatus === 'resolved'" x-cloak class="ai-chatbot__resolved-banner">
6904            Chat ended — send a message to start again.
6905          </div><div x-show="showContactAsk" x-cloak class="ai-chatbot__contact-ask">
6906            <p class="ai-chatbot__contact-ask-prompt" x-show="contactAskMode === 'email_chip'">Leave your email in case you step away.</p>
6907            <p class="ai-chatbot__contact-ask-prompt" x-show="contactAskMode === 'progressive'">Mind sharing your name and email so we can follow up?</p>
6908            <form @submit.prevent="submitContact()" class="ai-chatbot__contact-ask-form">
6909              <input
6910                x-show="contactAskMode !== 'email_chip' && !contactName"
6911                x-model="contactNameInput"
6912                type="text"
6913                class="ai-chatbot__contact-ask-input"
6914                placeholder="Your name"
6915                :disabled="contactSubmitting"
6916              >
6917              <input
6918                x-show="!contactEmail"
6919                x-model="contactEmailInput"
6920                type="email"
6921                class="ai-chatbot__contact-ask-input"
6922                placeholder="Your email"
6923                :disabled="contactSubmitting"
6924              >
6925              <button
6926                type="submit"
6927                class="ai-chatbot__contact-ask-submit"
6928                :disabled="contactSubmitting"
6929              >
6930                Send
6931              </button>
6932              <button
6933                type="button"
6934                @click="dismissContactAsk()"
6935                class="ai-chatbot__contact-ask-dismiss"
6936                aria-label="Dismiss"
6937              >
6938                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
6939                  <line x1="18" y1="6" x2="6" y2="18"></line>
6940                  <line x1="6" y1="6" x2="18" y2="18"></line>
6941                </svg>
6942              </button>
6943            </form>
6944          </div><div class="ai-chatbot__input-area">
6945            <form @submit.prevent="sendMessage()" class="ai-chatbot__input-form">
6946              <textarea
6947                x-ref="chatInput"
6948                x-model="inputText"
6949                @keydown="handleKeyDown($event)"
6950                class="ai-chatbot__input"
6951                placeholder="Type your message..."
6952                rows="1"
6953                :disabled="isLoading"
6954              ></textarea>
6955              <button
6956                type="submit"
6957                class="ai-chatbot__send-btn"
6958                :disabled="isLoading || !inputText.trim()"
6959                aria-label="Send"
6960              >
6961                <template x-if="isLoading">
6962                  <svg class="ai-chatbot__spinner" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
6963                    <line x1="12" y1="2" x2="12" y2="6"></line>
6964                    <line x1="12" y1="18" x2="12" y2="22"></line>
6965                    <line x1="4.93" y1="4.93" x2="7.76" y2="7.76"></line>
6966                    <line x1="16.24" y1="16.24" x2="19.07" y2="19.07"></line>
6967                    <line x1="2" y1="12" x2="6" y2="12"></line>
6968                    <line x1="18" y1="12" x2="22" y2="12"></line>
6969                    <line x1="4.93" y1="19.07" x2="7.76" y2="16.24"></line>
6970                    <line x1="16.24" y1="7.76" x2="19.07" y2="4.93"></line>
6971                  </svg>
6972                </template>
6973                <template x-if="!isLoading">
6974                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
6975                    <line x1="22" y1="2" x2="11" y2="13"></line>
6976                    <polygon points="22 2 15 22 11 13 2 9 22 2"></polygon>
6977                  </svg>
6978                </template>
6979              </button>
6980            </form><p
6981              class="ai-chatbot__disclaimer"
6982              x-show="conversationStatus === null || conversationStatus === 'bot'"
6983            >
6984              Responses are generated by AI and may be inaccurate.
6985            </p>
6986          </div>
6987        </div>
6988      </div>
6989    </template>
6990  </data-island>
6991</div>
6992
6993    
6994    <section id="shopify-section-branding-service-cards" class="shopify-section branding-service-cards-section"><style data-shopify>
6995  .branding-floating-overlay {
6996    position: fixed;
6997    inset: 0;
6998    z-index: 9999;
6999    background: rgba(0, 0, 0, 0.5);
7000    opacity: 0;
7001    transition: opacity 300ms ease;
7002    pointer-events: none;
7003  }
7004
7005  .branding-floating-overlay.active {
7006    opacity: 1;
7007    pointer-events: auto;
7008  }
7009
7010  /* Floating card - matches carousel expanded card styling */
7011  .branding-floating-card {
7012    position: fixed;
7013    z-index: 10000;
7014    background: rgb(var(--color-scheme-background, 255 255 255));
7015    border-radius: 16px;
7016    box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.4);
7017    display: none;
7018    flex-direction: column;
7019    max-height: 85vh;
7020    overflow: hidden;
7021    /* No default top/left/bottom - JS controls position */
7022  }
7023
7024  /* Close button - matches carousel style */
7025  .branding-floating-card .branding-pill-close {
7026    position: absolute;
7027    top: 12px;
7028    right: 12px;
7029    z-index: 10;
7030    width: 32px;
7031    height: 32px;
7032    border-radius: 50%;
7033    background: rgba(255, 255, 255, 0.9);
7034    border: none;
7035    cursor: pointer;
7036    display: flex;
7037    align-items: center;
7038    justify-content: center;
7039    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
7040    transition: background 200ms ease;
7041  }
7042
7043  .branding-floating-card .branding-pill-close:hover {
7044    background: rgba(255, 255, 255, 1);
7045  }
7046
7047  .branding-floating-card .branding-pill-close svg {
7048    width: 16px;
7049    height: 16px;
7050    stroke: #333;
7051  }
7052
7053  /* Image link - matches carousel style */
7054  .branding-floating-card .branding-pill-image-link {
7055    display: block;
7056    flex-shrink: 0;
7057    background: rgba(var(--color-scheme-text, 0 0 0), 0.05);
7058    min-height: 200px;
7059  }
7060
7061  .branding-floating-card .branding-pill-image-link.has-image {
7062    min-height: 0;
7063  }
7064
7065  .branding-floating-card .branding-pill-image {
7066    border-radius: 16px 16px 0 0;
7067    width: 100%;
7068    height: auto;
7069    max-height: 280px;
7070    object-fit: cover;
7071    display: block;
7072  }
7073
7074  .branding-floating-card .branding-pill-image:not([src]),
7075  .branding-floating-card .branding-pill-image[src=""] {
7076    display: none;
7077  }
7078
7079  /* Label button overlay - matches carousel style */
7080  .branding-floating-card .branding-pill-label {
7081    display: none; /* Hidden in expanded state like carousel */
7082  }
7083
7084  /* Expanded content - matches carousel style */
7085  .branding-floating-card .branding-pill-content {
7086    padding: 20px;
7087    flex-shrink: 0;
7088  }
7089
7090  .branding-floating-card .branding-expanded-title {
7091    margin: 0 0 12px 0;
7092    font-size: 1.25rem;
7093    font-weight: 600;
7094    color: black;
7095
7096  }
7097
7098  .branding-floating-card .branding-expanded-loading {
7099    display: flex;
7100    align-items: center;
7101    justify-content: center;
7102    padding: 20px;
7103  }
7104
7105  .branding-floating-card .branding-expanded-spinner {
7106    width: 24px;
7107    height: 24px;
7108    border: 2px solid rgba(var(--color-scheme-text, 0 0 0), 0.1);
7109    border-top-color: rgb(var(--color-scheme-text, 0 0 0));
7110    border-radius: 50%;
7111    animation: branding-pill-spin 0.8s linear infinite;
7112  }
7113
7114  @keyframes branding-pill-spin {
7115    to { transform: rotate(360deg); }
7116  }
7117
7118  .branding-floating-card .branding-expanded-description {
7119    margin-bottom: 16px;
7120    line-height: 1.6;
7121    color: black;
7122  }
7123
7124  .branding-floating-card .branding-expanded-description p {
7125    margin: 0;
7126  }
7127
7128  .branding-floating-card .branding-expanded-description p + p {
7129    margin-top: 0.75em;
7130  }
7131
7132  @media (max-width: 749px) {
7133    .branding-floating-card {
7134      width: calc(100vw - 48px) !important;
7135      left: 24px !important;
7136      max-width: none !important;
7137    }
7138  }
7139</style>
7140
7141<!-- Overlay backdrop -->
7142<div
7143  id="branding-floating-overlay"
7144  class="branding-floating-overlay"
7145  onclick="window.closeBrandingServiceCard()"
7146></div>
7147
7148<!-- Floating card - HTML structure matches carousel expanded cards -->
7149<div
7150  id="branding-floating-card"
7151  class="branding-floating-card color-scheme5"
7152>
7153  <!-- Close button (top right over image) -->
7154  <button type="button" class="branding-pill-close" onclick="window.closeBrandingServiceCard()">
7155    <span class="sr-only">Close</span>
7156    <svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
7157      <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
7158    </svg>
7159  </button>
7160
7161  <!-- Image with link -->
7162  <a id="branding-card-image-link" href="#" class="branding-pill-image-link">
7163    <img
7164      id="branding-card-image"
7165      class="branding-pill-image"
7166      src=""
7167      alt=""
7168      loading="lazy"
7169      width="300"
7170      height="300"
7171    >
7172  </a>
7173
7174  <!-- Label button (hidden in expanded state, like carousel) -->
7175  <a id="branding-card-label" href="#" class="branding-pill-label"></a>
7176
7177  <!-- Expanded content -->
7178  <div class="branding-pill-content">
7179    <h3 id="branding-card-title" class="branding-expanded-title"></h3>
7180    <div id="branding-card-loading" class="branding-expanded-loading" style="display: none;">
7181      <div class="branding-expanded-spinner"></div>
7182    </div>
7183    <div id="branding-card-description" class="branding-expanded-description"></div>
7184  </div>
7185</div>
7186
7187<script>
7188(function() {
7189  // Build service data from Shopify blocks
7190  // Key is the lowercase metafield value (e.g., "screen print", "custom neck tags")
7191  const brandingServiceData = {
7192    
7193      'high density transfer': {
7194        title: "High density transfer",
7195        description: "\u003cp\u003eA high density transfer is a heat-applied decoration that creates a raised, textured print using layered ink, producing a bold, dimensional effect with sharp edges and strong durability on garments.\u003c\/p\u003e",
7196        image: '//printroom.co/cdn/shop/files/heat_transfer_2_1b6dd18d-7ae5-452a-a0ca-fef697ba6400.jpg?v=1761181341&width=800',
7197        imageAlt: "High density transfer",
7198        ctaText: "Learn more",
7199        ctaUrl: '#'
7200      },
7201    
7202      'printed seam tape': {
7203        title: "printed seam tape",
7204        description: "\u003cp\u003eAdd a custom touch to the inside of your cap with printed seam tape. This often-overlooked detail offers a unique way to showcase your brand, giving your caps a polished finish that stands out from the inside out. Fully customisable, it’s a small touch that makes a big impression.\u003c\/p\u003e",
7205        image: '//printroom.co/cdn/shop/files/speights_cap_inner_3.jpg?v=1743540305&width=800',
7206        imageAlt: "custom caps NZ",
7207        ctaText: "Learn more",
7208        ctaUrl: '#'
7209      },
7210    
7211      'knitted all-over': {
7212        title: "Knitted all-over",
7213        description: "\u003cp\u003eKnitted all-over designs weave patterns directly into the fabric of your custom socks, creating a seamless, durable look that won’t fade over time. Ideal for intricate, full-length designs with lasting quality.\u003c\/p\u003e",
7214        image: '//printroom.co/cdn/shop/files/knitted_all_over_detail.jpg?v=1772668725&width=800',
7215        imageAlt: "Knitted all-over",
7216        ctaText: "Learn more",
7217        ctaUrl: '#'
7218      },
7219    
7220      'dye-sublimation': {
7221        title: "Dye-sublimation",
7222        description: "\u003cp\u003eDye-sublimation allows vibrant, full-colour designs to be seamlessly printed on your custom socks. The process ensures high-quality, durable prints that won’t fade, perfect for intricate patterns or all-over designs.\u003c\/p\u003e",
7223        image: '//printroom.co/cdn/shop/files/dye_sub_detail.jpg?v=1772673144&width=800',
7224        imageAlt: "Dye-sublimation",
7225        ctaText: "Learn more",
7226        ctaUrl: '#'
7227      },
7228    
7229      'additional cushioning': {
7230        title: "Additional cushioning",
7231        description: "\u003cp\u003eAdd extra cushioning to your custom socks for improved comfort and support. The soft padding underfoot reduces impact, perfect for all-day wear or active use.\u003c\/p\u003e",
7232        image: '//printroom.co/cdn/shop/files/cushion_detail.jpg?v=1772673175&width=800',
7233        imageAlt: "Additional cushioning",
7234        ctaText: "Learn more",
7235        ctaUrl: '#'
7236      },
7237    
7238      'added grip': {
7239        title: "Added grip",
7240        description: "\u003cp\u003eEnhance your custom socks with added grip to prevent slipping! The textured grip on the sole ensures better traction, or adds an extra dimension to your custom product.\u003c\/p\u003e",
7241        image: '//printroom.co/cdn/shop/files/added_grip_detail.jpg?v=1772675209&width=800',
7242        imageAlt: "Added grip",
7243        ctaText: "Learn more",
7244        ctaUrl: '#'
7245      },
7246    
7247      'custom neck tags': {
7248        title: "Custom neck tags",
7249        description: "\u003cp\u003eMake your brand stand out with custom neck tags! Whether you choose woven labels or screen printing, our high-quality neck tags offer a professional finish and are ideal for showcasing your unique brand identity.\u003c\/p\u003e",
7250        image: '//printroom.co/cdn/shop/files/cardrona_4_2_936c38b5-e634-4f0f-b224-0c9ed7b76ed9.jpg?v=1648584454&width=800',
7251        imageAlt: "garment relabelling and custom neck tags christchurch",
7252        ctaText: "Learn more",
7253        ctaUrl: '#'
7254      },
7255    
7256      'screen print': {
7257        title: "Screen Printing",
7258        description: "\u003cp\u003eOur most popular print method for good reason—it delivers \u003cstrong\u003etop-tier qual
7258ity\u003c\/strong\u003e, long-lasting results, and exceptional value for larger orders.\u003c\/p\u003e",
7259        image: '//printroom.co/cdn/shop/files/PrintRoomMay2024Image-16.jpg?v=1733350366&width=800',
7260        imageAlt: "Screen Printing",
7261        ctaText: "Learn more",
7262        ctaUrl: '#'
7263      },
7264    
7265      'embroidery': {
7266        title: "Embroidery",
7267        description: "\u003cp\u003eUnmatched in durability, embroidery is a simple choice for those wanting texture, dimension and a high-end finish.\u003c\/p\u003e",
7268        image: '//printroom.co/cdn/shop/files/The_print_room_custom_embroidery_new_zealand.jpg?v=1613753361&width=800',
7269        imageAlt: "Embroidery",
7270        ctaText: "Learn more",
7271        ctaUrl: '#'
7272      },
7273    
7274      'heat transfer': {
7275        title: "Heat Transfers",
7276        description: "\u003cp\u003ePerfect for producing vibrant, detail-rich prints that require low minimums.\u003c\/p\u003e",
7277        image: '//printroom.co/cdn/shop/files/heat_press_print_room.jpg?v=1776795804&width=800',
7278        imageAlt: "Heat Transfers",
7279        ctaText: "Learn more",
7280        ctaUrl: '/pages/heat-transfers'
7281      },
7282    
7283      'custom patches': {
7284        title: "Custom Patches",
7285        description: "\u003cp\u003eDurable and versatile, add dimension to your merch with embroidered, woven or iron-on custom patches.\u003c\/p\u003e",
7286        image: '//printroom.co/cdn/shop/files/PrintRoomApril2024Image-42_28acbdcf-7baf-4834-9201-752d656019ad.jpg?v=1754535298&width=800',
7287        imageAlt: "custom patches NZ",
7288        ctaText: "Learn more",
7289        ctaUrl: '#'
7290      },
7291    
7292      'custom packaging': {
7293        title: "Custom packaging",
7294        description: "\u003cp\u003eThe ultimate finishing touch; custom packaging. It’s the first thing your customer sees, make the best impression possible and package your products inline with your brand.\u003c\/p\u003e",
7295        image: '//printroom.co/cdn/shop/files/socks_label.jpg?v=1743476398&width=800',
7296        imageAlt: "custom socks",
7297        ctaText: "Learn more",
7298        ctaUrl: '#'
7299      },
7300    
7301      'custom woven label': {
7302        title: "Custom woven label",
7303        description: "\u003cp\u003eGive all of the details you need while putting the finishing touches on your product.\u003c\/p\u003e",
7304        image: '//printroom.co/cdn/shop/files/garage_project_cap_4.1.jpg?v=1770086525&width=800',
7305        imageAlt: "Custom woven label",
7306        ctaText: "Learn more",
7307        ctaUrl: '#'
7308      },
7309    
7310      'pip tags': {
7311        title: "Pip tags",
7312        description: "\u003cp\u003eElevate your garments with custom pip tags. Perfect for adding subtle branding, a small detail with a big impact for your apparel collection.\u003c\/p\u003e",
7313        image: '//printroom.co/cdn/shop/files/cardrona_3_19a3035b-75a5-4fd0-9604-01d159cdc102.jpg?v=1648585469&width=800',
7314        imageAlt: "garment relabelling and custom neck tags nz",
7315        ctaText: "Learn more",
7316        ctaUrl: '#'
7317      },
7318    
7319      'additional print placements': {
7320        title: "Additional print placements",
7321        description: "\u003cp\u003eAdd extra visibility to your brand by adding additional prints\/decorations. Back of the cap, sleeve of your sweatshirt; you name it, we can most likely do it. Make the most of your products' full 360 degrees.\u003c\/p\u003e",
7322        image: '//printroom.co/cdn/shop/files/garage_project_cap_3.1.jpg?v=1770083144&width=800',
7323        imageAlt: "Additional print placements",
7324        ctaText: "Learn more",
7325        ctaUrl: '#'
7326      },
7327    
7328      'various attachments available': {
7329        title: "Various attachments available",
7330        description: "\u003cp\u003eMake the most of customisation and choose the attachment style that works for your project. Robust, intricate, elegant…your choice.\u003c\/p\u003e",
7331        image: '//printroom.co/cdn/shop/files/pack-a-punch.jpg?v=1760925265&width=800',
7332        imageAlt: "Various attachments available",
7333        ctaText: "Learn more",
7334        ctaUrl: '#'
7335      },
7336    
7337      'add additional colours': {
7338        title: "Add additional colours",
7339        description: "\u003cp\u003eCreate more depth and complexity when your brand needs it. Specific limitations apply to each product. Consult your account manager for specific limitations.\u003c\/p\u003e",
7340        image: '//printroom.co/cdn/shop/files/ombre.jpg?v=1770253000&width=800',
7341        imageAlt: "Add additional colours",
7342        ctaText: "Learn more",
7343        ctaUrl: '#'
7344      },
7345    
7346      'various closures available': {
7347        title: "Various closures available",
7348        description: "\u003cp\u003eAchieve the result you want with control over what closure you go with.\u003c\/p\u003e",
7349        image: '//printroom.co/cdn/shop/files/closure_options_2.1_76d53ef9-c502-45b4-b915-66543d3c7f40.jpg?v=1769654951&width=800',
7350        imageAlt: "Various closures available",
7351        ctaText: "Learn more",
7352        ctaUrl: '#'
7353      },
7354    
7355      'glow in the dark': {
7356        title: "Glow in the dark",
7357        description: "\u003cp\u003eBe seen…in the dark! Add a novel element to your product and have some fun with it.\u003c\/p\u003e",
7358        image: '//printroom.co/cdn/shop/files/glow_in_the_dark.jpg?v=1770253668&width=800',
7359        imageAlt: "Glow in the dark",
7360        ctaText: "Learn more",
7361        ctaUrl: '#'
7362      },
7363    
7364      'applique': {
7365        title: "Applique",
7366        description: "\u003cp\u003eAppliqué embroidery isa technique where small pieces of fabric are laser cut and layered and stitched onto a garment, adding texture to the design.\u003c\/p\u003e",
7367        image: '//printroom.co/cdn/shop/files/Screenshot-2026-04-22-at-6.18.38_AM.jpg?v=1776795959&width=800',
7368        imageAlt: "Applique",
7369        ctaText: "Learn more",
7370        ctaUrl: '#'
7371      },
7372    
7373      'spreadsheet': {
7374        title: "Spreadsheet",
7375        description: "\u003cp\u003eWe send you a formatted spreadsheet that can be shared around your year group for each student to input the
7375ir garment style, size and custom name. \u003c\/p\u003e",
7376        image: null,
7377        imageAlt: "Spreadsheet",
7378        ctaText: "Learn more",
7379        ctaUrl: '#'
7380      },
7381    
7382      'online portal': {
7383        title: "Online portal",
7384        description: "\u003cp\u003eWe setup an password portected online portal for your year group to log into and purchased or order their garments. \u003c\/p\u003e",
7385        image: '//printroom.co/cdn/shop/files/product_1db770e9-3325-4bd4-8636-6f4b6d5e566a_slot_5.jpg?v=1776753322&width=800',
7386        imageAlt: "Earth Positive Premium Jersey T-shirt EP185 T-shirt branded merchandise nz",
7387        ctaText: "Click",
7388        ctaUrl: '#'
7389      }
7390    
7391  };
7392
7393  // Also build hyphenated keys for matching
7394  const brandingServiceDataNormalized = {};
7395  Object.keys(brandingServiceData).forEach(key => {
7396    // Store with original key
7397    brandingServiceDataNormalized[key] = brandingServiceData[key];
7398    // Also store with hyphenated version
7399    const hyphenated = key.replace(/\s+/g, '-');
7400    brandingServiceDataNormalized[hyphenated] = brandingServiceData[key];
7401    // Also store with spaced version (in case key was hyphenated)
7402    const spaced = key.replace(/-/g, ' ');
7403    brandingServiceDataNormalized[spaced] = brandingServiceData[key];
7404  });
7405
7406  // Configuration from section settings
7407  const config = {
7408    maxWidth: 400,
7409    animationDuration: 300,
7410    showOverlay: false
7411  };
7412
7413  // State
7414  let isCardOpen = false;
7415  let originRect = null;
7416
7417  // DOM elements
7418  const overlay = document.getElementById('branding-floating-overlay');
7419  const card = document.getElementById('branding-floating-card');
7420  const cardImageLink = document.getElementById('branding-card-image-link');
7421  const cardImage = document.getElementById('branding-card-image');
7422  const cardLabel = document.getElementById('branding-card-label');
7423  const cardTitle = document.getElementById('branding-card-title');
7424  const cardLoading = document.getElementById('branding-card-loading');
7425  const cardDescription = document.getElementById('branding-card-description');
7426
7427  // Find service data by matching the label text
7428  function findServiceData(label) {
7429    if (!label) return null;
7430    const searchKey = label.toLowerCase().trim();
7431    const searchKeyHyphenated = searchKey.replace(/\s+/g, '-');
7432    
7433    // Direct match
7434    if (brandingServiceDataNormalized[searchKey]) {
7435      return brandingServiceDataNormalized[searchKey];
7436    }
7437    
7438    // Try hyphenated version
7439    if (brandingServiceDataNormalized[searchKeyHyphenated]) {
7440      return brandingServiceDataNormalized[searchKeyHyphenated];
7441    }
7442    
7443    // Partial match - check if any key is contained in the label or vice versa
7444    for (const key of Object.keys(brandingServiceDataNormalized)) {
7445      if (searchKey.includes(key) || key.includes(searchKey)) {
7446        return brandingServiceDataNormalized[key];
7447      }
7448    }
7449    
7450    return null;
7451  }
7452
7453  // Populate card content
7454  function populateCard(data, serviceUrl) {
7455    const url = data.ctaUrl || serviceUrl || '#';
7456
7457    // Set image
7458    if (data.image) {
7459      cardImage.src = data.image;
7460      cardImage.alt = data.imageAlt || data.title || '';
7461      cardImageLink.classList.add('has-image');
7462    } else {
7463      cardImage.src = '';
7464      cardImage.alt = '';
7465      cardImageLink.classList.remove('has-image');
7466    }
7467
7468    // Set links
7469    cardImageLink.href = url;
7470    cardLabel.href = url;
7471    cardLabel.textContent = data.title || '';
7472
7473    // Set content
7474    cardTitle.textContent = data.title || '';
7475
7476    // Handle description - if we have static content use it, otherwise fetch
7477    if (data.description && data.description.trim() !== '' && data.description !== '<p>Add a description of this branding service.</p>') {
7478      cardDescription.innerHTML = data.description;
7479      cardLoading.style.display = 'none';
7480    } else {
7481      // Fetch description from service page
7482      cardDescription.innerHTML = '';
7483      cardLoading.style.display = 'flex';
7484
7485      if (url && url !== '#') {
7486        fetch(url)
7487          .then(response => response.text())
7488          .then(html => {
7489            const parser = new DOMParser();
7490            const doc = parser.parseFromString(html, 'text/html');
7491            const main = doc.querySelector('main') || doc.querySelector('.page-content') || doc.querySelector('.shopify-section') || doc.body;
7492            let description = '<p>Discover our premium branding service.</p>';
7493            if (main) {
7494              const firstP = main.querySelector('p');
7495              if (firstP) description = '<p>' + firstP.textContent.trim() + '</p>';
7496            }
7497            cardDescription.innerHTML = description;
7498            cardLoading.style.display = 'none';
7499          })
7500          .catch(() => {
7501            cardDescription.innerHTML = '<p>Discover our premium branding service.</p>';
7502            cardLoading.style.display = 'none';
7503          });
7504      } else {
7505        cardDescription.innerHTML = '<p>Discover our premium branding service.</p>';
7506        cardLoading.style.display = 'none';
7507      }
7508    }
7509  }
7510
7511  // Show card with animation from button position
7512  function showCardWithData(data, buttonElement, serviceUrl) {
7513    if (!data) {
7514      console.warn('No service data provided');
7515      return;
7516    }
7517
7518    // Get button position for animation origin
7519    const buttonRect = buttonElement
7520      ? buttonElement.getBoundingClientRect()
7521      : { left: window.innerWidth / 2 - 50, top: window.innerHeight / 2, width: 100, height: 40 };
7522
7523    originRect = { ...buttonRect };
7524
7525    // Populate content
7526    populateCard(data, serviceUrl);
7527
7528    // Calculate target dimensions
7529    const expandedWidth = Math.min(window.innerWidth - 40, config.maxWidth);
7530    const padding = 20;
7531    const headerHeight = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--header-height') || '0', 10);
7532
7533   // Center expanded card horizontally on the button's center
7534const buttonCenterX = buttonRect.left + (buttonRect.width / 2);
7535let targetLeft = buttonCenterX - (expandedWidth / 2);
7536
7537// Clamp to viewport bounds horizontally
7538targetLeft = Math.max(padding, Math.min(targetLeft, window.innerWidth - expandedWidth - padding));
7539
7540// Position vertically: expand from button's top, but ensure it stays in viewport
7541// Start from the button's vertical position
7542let targetTop = buttonRect.top;
7543
7544// Get actual card content height or use a more realistic estimate
7545const cardContent = card.querySelector('.card__content') || card;
7546const estimatedCardHeight = cardContent.scrollHeight || 600; // Increased from 400 to 600
7547
7548// Calculate available space below and above the button
7549const spaceBelow = window.innerHeight - buttonRect.bottom - padding;
7550const spaceAbove = buttonRect.top - headerHeight - padding;
7551
7552// If card would go below viewport, shift it up
7553if (targetTop + estimatedCardHeight > window.innerHeight - padding) {
7554  targetTop = Math.max(headerHeight + padding, window.innerHeight - estimatedCardHeight - padding);
7555}
7556
7557// If card would go above header, shift it down
7558if (targetTop < headerHeight + padding) {
7559  targetTop = headerHeight + padding;
7560}
7561
7562// Final safety check: ensure card fits in viewport
7563const maxAllowedHeight = window.innerHeight - headerHeight - (padding * 2);
7564if (estimatedCardHeight > maxAllowedHeight) {
7565  targetTop = headerHeight + padding;
7566  card.style.maxHeight = maxAllowedHeight + 'px';
7567  card.style.overflowY = 'auto';
7568}
7569
7570
7571    // Show overlay
7572    if (config.showOverlay) {
7573      overlay.classList.add('active');
7574    }
7575
7576    // Set initial state at EXACT button position
7577    card.style.position = 'fixed';
7578    card.style.top = buttonRect.top + 'px';
7579    card.style.left = buttonRect.left + 'px';
7580    card.style.width = buttonRect.width + 'px';
7581    card.style.height = buttonRect.height + 'px';
7582    card.style.zIndex = '10000';
7583    card.style.margin = '0';
7584    card.style.display = 'flex';
7585    card.style.opacity = '1';
7586    card.style.pointerEvents = 'auto';
7587    card.style.overflow = 'hidden';
7588    card.style.transition = 'none';
7589    card.style.flexDirection = 'column';
7590    card.style.borderRadius = '16px';
7591
7592    // Force reflow to ensure initial position is applied
7593    card.getBoundingClientRect();
7594
7595    // Now animate to expanded position
7596    requestAnimationFrame(() => {
7597      requestAnimationFrame(() => {
7598        card.style.transition = `
7599          top ${config.animationDuration}ms cubic-bezier(0.32, 0.72, 0, 1),
7600          left ${config.animationDuration}ms cubic-bezier(0.32, 0.72, 0, 1),
7601          width ${config.animationDuration}ms cubic-bezier(0.32, 0.72, 0, 1),
7602          height ${config.animationDuration}ms cubic-bezier(0.32, 0.72, 0, 1)
7603        `;
7604        card.style.top = targetTop + 'px';
7605        card.style.left = targetLeft + 'px';
7606        card.style.width = expandedWidth + 'px';
7607        card.style.height = 'auto';
7608      });
7609    });
7610
7611    isCardOpen = true;
7612  }
7613
7614  // Close card with animation back to origin
7615  window.closeBrandingServiceCard = function() {
7616    if (!isCardOpen) return;
7617
7618    // Animate back to origin position (exactly like carousel collapseCard)
7619    if (originRect) {
7620      card.style.transition = `
7621        top ${config.animationDuration}ms cubic-bezier(0.32, 0.72, 0, 1),
7622        left ${config.animationDuration}ms cubic-bezier(0.32, 0.72, 0, 1),
7623        width ${config.animationDuration}ms cubic-bezier(0.32, 0.72, 0, 1),
7624        height ${config.animationDuration}ms cubic-bezier(0.32, 0.72, 0, 1)
7625      `;
7626      card.style.top = originRect.top + 'px';
7627      card.style.left = originRect.left + 'px';
7628      card.style.width = originRect.width + 'px';
7629      card.style.height = originRect.height + 'px';
7630      card.style.overflow = 'hidden';
7631    }
7632
7633    // Hide overlay
7634    overlay.classList.remove('active');
7635
7636    // Clean up after animation
7637    setTimeout(() => {
7638      card.style.display = 'none';
7639      card.style.transition = '';
7640      card.style.top = '';
7641      card.style.left = '';
7642      card.style.width = '';
7643      card.style.height = '';
7644      card.style.opacity = '';
7645      card.style.pointerEvents = '';
7646      card.style.overflow = '';
7647      isCardOpen = false;
7648      originRect = null;
7649    }, config.animationDuration);
7650  };
7651
7652  // Event listener for pill button clicks
7653  // Alpine's $dispatch bubbles from the element through the DOM
7654  document.addEventListener('branding-modal:open', (event) => {
7655    // Prevent duplicate handling
7656    if (event._handled) return;
7657    event._handled = true;
7658
7659    const { label, url, element } = event.detail || {};
7660
7661    // Get the pill text from the button element if available
7662    const pillText = element ? (element.querySelector('.branding-service-pill__text')?.textContent || label) : label;
7663
7664    // Find service data by matching the pill text
7665    const serviceData = findServiceData(pillText);
7666    if (!serviceData) {
7667      console.warn('No service data configured for:', pillText);
7668      return;
7669    }
7670
7671    // If a card is already open, close it first
7672    if (isCardOpen) {
7673      window.closeBrandingServiceCard();
7674      setTimeout(() => {
7675        showCardWithData(serviceData, element, url);
7676      }, config.animationDuration + 50);
7677    } else {
7678      showCardWithData(serviceData, element, url);
7679    }
7680  });
7681
7682  // Escape key handler
7683  document.addEventListener('keydown', (e) => {
7684    if (e.key === 'Escape' && isCardOpen) {
7685      window.closeBrandingServiceCard();
7686    }
7687  });
7688})();
7689</script>
7689
7690
7691
7692</section>
7693
7694    
7694<script src="//printroom.co/cdn/shop/t/59/assets/global.bundle.js?v=149077486339995821341790734057" type="module"></script>
7694
7695
7696    
7696<script>
7697      window.Shopify = window.Shopify || {};
7698      window.Shopify.locale = "en";
7699      window.Shopify.currency = {
7700        active: "USD",
7701        rate: ""
7702      };
7703    </script>
7703
7704  
7704<script src="https://cdn.shopify.com/storefront/standard-actions.js" type="module" data-source-attribution="shopify.standard_actions"></script>
7704
7705</body>
7706</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.