PageSourceSearch

https://ergonis.com/en/store/

html ergonis.com collected 2026-09-24 10:19:30 UTC 61,893 bytes, 589 lines download raw bytes

1<!DOCTYPE html><html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width"><link rel="icon" type="image/svg+xml" href="/favicon.ico"><link rel="apple-touch-icon" href="/favicon.ico"><meta name="generator" content="Astro v5.16.5"><meta name="facebook-domain-verification" content="dyd88lsr6pudyvf80jjlfxic3ys06w"><title>Buy Typinator, KeyCue, or PopChar | ergonis store</title><link rel="canonical" href="https://ergonis.com/en/store/"><meta name="description" content="Buy Typinator, KeyCue, and PopChar in the ergonis store. Improve your productivity today."><meta name="robots" content="index, follow"><meta property="og:title" content="Buy Typinator, KeyCue, or PopChar | ergonis store"><meta property="og:type" content="website"><meta property="og:image" content="https://www.ergonis.com/seo/ergonis.png"><meta property="og:url" content="https://ergonis.com/en/store/"><meta property="og:description" content="Buy Typinator, KeyCue, and PopChar in the ergonis store. Improve your productivity today."><meta property="og:site_name" content="Ergonis Software"><meta property="og:image:url" content="https://www.ergonis.com/seo/ergonis.png"><meta property="og:image:secure_url" content="https://www.ergonis.com/seo/ergonis.png"><meta property="og:image:alt" content="ergonis productivity software homepage"><meta name="twitter:card" content="summary"><meta name="twitter:site" content="@ergonis"><meta name="twitter:title" content="Buy Typinator, KeyCue, or PopChar | ergonis store"><meta name="twitter:description" content="Buy Typinator, KeyCue, and PopChar in the ergonis store. Improve your productivity today."><meta property="article:modified_time" content="2026-09-17">
1<script type="application/ld+json">{"@context":"https://schema.org","@type":"Organization","name":"Ergonis Software","url":"https://ergonis.com","logo":{"@type":"ImageObject","url":"https://ergonis.com/favicon.ico"},"sameAs":["https://ergonis.com"]}</script>
1<link rel="alternate" href="https://ergonis.com/en/store/" hreflang="en"><link rel="alternate" href="https://ergonis.com/fr/store/" hreflang="fr"><link rel="alternate" href="https://ergonis.com/de/store/" hreflang="de"><link rel="alternate" href="https://ergonis.com/es/store/" hreflang="es"><link rel="alternate" hreflang="x-default" href="https://ergonis.com/en/store/">
1<script type="text/javascript">
2      (function (a, b, c, d, e, f, g) {e['ire_o'] = c;e[c] = e[c] || function () {(e[c].a = e[c].a || []).push(arguments)};f = d.createElement(b);g = d.getElementsByTagName(b)[0];f.async = 1;f.src = a;g.parentNode.insertBefore(f, g);})('https://utt.impactcdn.com/A4893852-8ed8-4ab2-9d4c-1fd81bbee4a01.js', 'script', 'ire', document, window);
3    </script>
3<vercel-analytics data-props="{}" data-params="{&#34;locale&#34;:&#34;en&#34;}" data-pathname="/en/store/"></vercel-analytics> 
3<script type="module">var v=()=>{window.va||(window.va=function(...i){window.vaq||(window.vaq=[]),window.vaq.push(i)})},w="@vercel/analytics",b="2.0.1";function f(){return typeof window<"u"}function p(){try{const e="production"}catch{}return"production"}function h(e="auto"){if(e==="auto"){window.vam=p();return}window.vam=e}function y(){return(f()?window.vam:p())||"production"}function d(){return y()==="development"}function m(e,i){if(!e||!i)return e;let n=e;try{const t=Object.entries(i);for(const[r,s]of t)if(!Array.isArray(s)){const o=u(s);o.test(n)&&(n=n.replace(o,`/[${r}]`))}for(const[r,s]of t)if(Array.isArray(s)){const o=u(s.join("/"));o.test(n)&&(n=n.replace(o,`/[...${r}]`))}return n}catch{return e}}function u(e){return new RegExp(`/${g(e)}(?=[/?#]|$)`)}function g(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function E(e){return e.scriptSrc?a(e.scriptSrc):d()?"https://va.vercel-scripts.com/v1/script.debug.js":e.basePath?a(`${e.basePath}/insights/script.js`):"/_vercel/insights/script.js"}function S(e,i){var n;let t=e;if(i)try{t={...(n=JSON.parse(i))==null?void 0:n.analytics,...e}}catch{}h(t.mode);const r={sdkn:w+(t.framework?`/${t.framework}`:""),sdkv:b};return t.disableAutoTrack&&(r.disableAutoTrack="1"),t.viewEndpoint&&(r.viewEndpoint=a(t.viewEndpoint)),t.eventEndpoint&&(r.eventEndpoint=a(t.eventEndpoint)),t.sessionEndpoint&&(r.sessionEndpoint=a(t.sessionEndpoint)),d()&&t.debug===!1&&(r.debug="false"),t.dsn&&(r.dsn=t.dsn),t.endpoint?r.endpoint=t.endpoint:t.basePath&&(r.endpoint=a(`${t.basePath}/insights`)),{beforeSend:t.beforeSend,src:E(t),dataset:r}}function a(e){return e.startsWith("http://")||e.startsWith("https://")||e.startsWith("/")?e:`/${e}`}function k(e={debug:!0},i){var n;if(!f())return;const{beforeSend:t,src:r,dataset:s}=S(e,i);if(v(),t&&((n=window.va)==null||n.call(window,"beforeSend",t)),document.head.querySelector(`script[src*="${r}"]`))return;const o=document.createElement("script");o.src=r;for(const[c,l]of Object.entries(s))o.dataset[c]=l;o.defer=!0,o.onerror=()=>{const c=d()?"Please check if any ad blockers are enabled and try again.":"Be sure to enable Web Analytics for your project and deploy again. See https://vercel.com/docs/analytics/quickstart for more information.";console.log(`[Vercel Web Analytics] Failed to load script from ${r}. ${c}`)},document.head.appendChild(o)}function $({route:e,path:i}){var n;(n=window.va)==null||n.call(window,"pageview",{route:e,path:i})}function A(){try{return}catch{}}function j(){try{return'{"analytics":{"scriptSrc":"e2b56e65c9b9aa75/script.js","viewEndpoint":"e2b56e65c9b9aa75/view","eventEndpoint":"e2b56e65c9b9aa75/event","sessionEndpoint":"e2b56e65c9b9aa75/session"},"speedInsights":{"scriptSrc":"393fd9b340282a06/script.js","endpoint":"393fd9b340282a06/vitals"}}'}catch{}}customElements.define("vercel-analytics",class extends HTMLElement{constructor(){super();try{const i=JSON.parse(this.dataset.props??"{}"),n=JSON.parse(this.dataset.params??"{}");k({...i,disableAutoTrack:!0,framework:"astro",basePath:A(),beforeSend:window.webAnalyticsBeforeSend},j());const t=this.dataset.pathname;$({route:m(t??"",n),path:t})}catch(i){throw new Error(`Failed to parse WebAnalytics properties: ${i}`)}}});</script>
3<link rel="stylesheet" href="/_astro/about.rSDBOgOL.css">
3<script type="module" src="/_astro/page.DogxaioH.js"></script>
vendor: 1 bytes, line 3
3
4<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s);j.async=true;j.src='https://a.ergonis.com/3konxcpqlbzv.js?'+i;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','9a=aWQ9R1RNLUtCMk1YTFc%3D&page=2')</script>
4<style>[data-astro-transition-scope="astro-o7bz76pi-1"] { view-transition-name: astro-o7bz76pi-1; }@layer astro { ::view-transition-old(astro-o7bz76pi-1) { animation: none; opacity: 0; mix-blend-mode: normal; }::view-transition-new(astro-o7bz76pi-1) { animation: none; mix-blend-mode: normal; }::view-transition-group(astro-o7bz76pi-1) { animation: none } }[data-astro-transition-fallback="old"] [data-astro-transition-scope="astro-o7bz76pi-1"],
5			[data-astro-transition-fallback="old"][data-astro-transition-scope="astro-o7bz76pi-1"] { animation: none; mix-blend-mode: normal; }[data-astro-transition-fallback="new"] [data-astro-transition-scope="astro-o7bz76pi-1"],
6			[data-astro-transition-fallback="new"][data-astro-transition-scope="astro-o7bz76pi-1"] { animation: none; mix-blend-mode: normal; }</style></head> <body class="min-h-screen h-screen"> <div class="flex min-h-full flex-col">  <!-- <Banner
7          href={getRelativeLocaleUrl(Astro.currentLocale || 'en', '/typinator/pricing')}
8          label={t('overview.banner.label')}
9          text={t('overview.banner.text')}
10          variant="info"
11          slot="banner"
12  ></Banner> --> 
12<script type="text/javascript">
13    ire('identify', {customerId: '',
14      customerEmail: '', customProfileId: ''});
15  </script>
15 <header class="astronav-sticky-header sticky top-0 border-b z-20 transition-all py-5 border-transparent" data-astro-cid-nvpbalwk>  <div class="container">  <div class="flex flex-col lg:flex-row justify-between items-center relative z-10" data-astro-transition-scope="astro-o7bz76pi-1">  <div class="flex w-full lg:w-auto items-center justify-between"> <div class="flex items-center"> <div class="-ml-2 mr-2 flex items-center lg:hidden"> <div class="inline-flex items-center justify-center p-1 sm:p-2 rounded-md text-gray-800 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-blue-500"> <button id="astronav-menu" aria-label="Toggle Menu">  <svg fill="currentColor" width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <title>Toggle Menu</title> <path class="astronav-close-icon astronav-toggle hidden" fill-rule="evenodd" clip-rule="evenodd" d="M18.278 16.864a1 1 0 01-1.414 1.414l-4.829-4.828-4.828 4.828a1 1 0 01-1.414-1.414l4.828-4.829-4.828-4.828a1 1 0 011.414-1.414l4.829 4.828 4.828-4.828a1 1 0 111.414 1.414l-4.828 4.829 4.828 4.828z"></path> <path class="astronav-open-icon astronav-toggle" fill-rule="evenodd" d="M4 5h16a1 1 0 010 2H4a1 1 0 110-2zm0 6h16a1 1 0 010 2H4a1 1 0 010-2zm0 6h16a1 1 0 010 2H4a1 1 0 010-2z"></path> </svg>  </button> </div> </div> <a href="/en/" class="text-lg flex items-center transition focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded-full px-2 -ml-2"> <span class="text-blue font-display font-bold text-xl sm:text-2xl">ergonis</span> </a>  </div> <div class="block lg:hidden grid grid-cols-[auto_auto] items-center"> <style>astro-island,astro-slot,astro-static-slot{display:contents}</style>
15<script>(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).load=e;window.dispatchEvent(new Event("astro:load"));})();</script>
15<script>(()=>{var A=Object.defineProperty;var g=(i,o,a)=>o in i?A(i,o,{enumerable:!0,configurable:!0,writable:!0,value:a}):i[o]=a;var d=(i,o,a)=>g(i,typeof o!="symbol"?o+"":o,a);{let i={0:t=>m(t),1:t=>a(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(a(t)),5:t=>new Set(a(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t),11:t=>1/0*t},o=t=>{let[l,e]=t;return l in i?i[l](e):void 0},a=t=>t.map(o),m=t=>typeof t!="object"||t===null?t:Object.fromEntries(Object.entries(t).map(([l,e])=>[l,o(e)]));class y extends HTMLElement{constructor(){super(...arguments);d(this,"Component");d(this,"hydrator");d(this,"hydrate",async()=>{var b;if(!this.hydrator||!this.isConnected)return;let e=(b=this.parentElement)==null?void 0:b.closest("astro-island[ssr]");if(e){e.addEventListener("astro:hydrate",this.hydrate,{once:!0});return}let c=this.querySelectorAll("astro-slot"),n={},h=this.querySelectorAll("template[data-astro-template]");for(let r of h){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n[r.getAttribute("data-astro-template")||"default"]=r.innerHTML,r.remove())}for(let r of c){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n[r.getAttribute("name")||"default"]=r.innerHTML)}let p;try{p=this.hasAttribute("props")?m(JSON.parse(this.getAttribute("props"))):{}}catch(r){let s=this.getAttribute("component-url")||"<unknown>",v=this.getAttribute("component-export");throw v&&(s+=` (export ${v})`),console.error(`[hydrate] Error parsing props for component ${s}`,this.getAttribute("props"),r),r}let u;await this.hydrator(this)(this.Component,p,n,{client:this.getAttribute("client")}),this.removeAttribute("ssr"),this.dispatchEvent(new CustomEvent("astro:hydrate"))});d(this,"unmount",()=>{this.isConnected||this.dispatchEvent(new CustomEvent("astro:unmount"))})}disconnectedCallback(){document.removeEventListener("astro:after-swap",this.unmount),document.addEventListener("astro:after-swap",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute("await-children")||document.readyState==="interactive"||document.readyState==="complete")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener("DOMContentLoaded",e),c.disconnect(),this.childrenConnectedCallback()},c=new MutationObserver(()=>{var n;((n=this.lastChild)==null?void 0:n.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue==="astro:end"&&(this.lastChild.remove(),e())});c.observe(this,{childList:!0}),document.addEventListener("DOMContentLoaded",e)}}async childrenConnectedCallback(){let e=this.getAttribute("before-hydration-url");e&&await import(e),this.start()}async start(){let e=JSON.parse(this.getAttribute("opts")),c=this.getAttribute("client");if(Astro[c]===void 0){window.addEventListener(`astro:${c}`,()=>this.start(),{once:!0});return}try{await Astro[c](async()=>{let n=this.getAttribute("renderer-url"),[h,{default:p}]=await Promise.all([import(this.getAttribute("component-url")),n?import(n):()=>()=>{}]),u=this.getAttribute("component-export")||"default";if(!u.includes("."))this.Component=h[u];else{this.Component=h;for(let f of u.split("."))this.Component=this.Component[f]}return this.hydrator=p,this.hydrate},e,this)}catch(n){console.error(`[astro-island] Error hydrating ${this.getAttribute("component-url")}`,n)}}attributeChangedCallback(){this.hydrate()}}d(y,"observedAttributes",["props"]),customElements.get("astro-island")||customElements.define("astro-island",y)}})();</script>
15<astro-island uid="1fCsDs" prefix="s0" component-url="/_astro/language-selector.ux4d6awT.js" component-export="default" renderer-url="/_astro/client.CSC4vdki.js" props="{&quot;currentLocale&quot;:[0,&quot;en&quot;],&quot;currentPath&quot;:[0,&quot;/en/store/&quot;]}" ssr client="load" opts="{&quot;name&quot;:&quot;LanguageSelector&quot;,&quot;value&quot;:true}" await-children><!--[--><div class="sm:ml-3 xl:ml-8 relative" data-headlessui-state><button id="headlessui-listbox-button-s0-0" type="button" aria-haspopup="listbox" aria-expanded="false" data-headlessui-state class="relative flex space-x-2 p-2 rounded-md text-sm text-gray-600 hover:text-blue-600 cursor-pointer" data-testid="navbar-button-language"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" data-slot="icon" class="h-5 w-5 shrink-0"><path d="M16.555 5.412a8.028 8.028 0 0 0-3.503-2.81 14.899 14.899 0 0 1 1.663 4.472 8.547 8.547 0 0 0 1.84-1.662ZM13.326 7.825a13.43 13.43 0 0 0-2.413-5.773 8.087 8.087 0 0 0-1.826 0 13.43 13.43 0 0 0-2.413 5.773A8.473 8.473 0 0 0 10 8.5c1.18 0 2.304-.24 3.326-.675ZM6.514 9.376A9.98 9.98 0 0 0 10 10c1.226 0 2.4-.22 3.486-.624a13.54 13.54 0 0 1-.351 3.759A13.54 13.54 0 0 1 10 13.5c-1.079 0-2.128-.127-3.134-.366a13.538 13.538 0 0 1-.352-3.758ZM5.285 7.074a14.9 14.9 0 0 1 1.663-4.471 8.028 8.028 0 0 0-3.503 2.81c.529.638 1.149 1.199 1.84 1.66ZM17.334 6.798a7.973 7.973 0 0 1 .614 4.115 13.47 13.47 0 0 1-3.178 1.72 15.093 15.093 0 0 0 .174-3.939 10.043 10.043 0 0 0 2.39-1.896ZM2.666 6.798a10.042 10.042 0 0 0 2.39 1.896 15.196 15.196 0 0 0 .174 3.94 13.472 13.472 0 0 1-3.178-1.72 7.973 7.973 0 0 1 .615-4.115ZM10 15c.898 0 1.778-.079 2.633-.23a13.473 13.473 0 0 1-1.72 3.178 8.099 8.099 0 0 1-1.826 0 13.47 13.47 0 0 1-1.72-3.178c.855.151 1.735.23 2.633.23ZM14.357 14.357a14.912 14.912 0 0 1-1.305 3.04 8.027 8.027 0 0 0 4.345-4.345c-.953.542-1.971.981-3.04 1.305ZM6.948 17.397a8.027 8.027 0 0 1-4.345-4.345c.953.542 1.971.981 3.04 1.305a14.912 14.912 0 0 0 1.305 3.04Z"></path></svg><span class="uppercase">EN</span></button><!----></div><!--]--><!--astro:end--></astro-island> <astro-island uid="ZEid06" prefix="s1" component-url="/_astro/cart-button.KPuct_VM.js" component-export="default" renderer-url="/_astro/client.CSC4vdki.js" props="{}" ssr client="load" opts="{&quot;name&quot;:&quot;CartButton&quot;,&quot;value&quot;:true}" await-children><div data-fs-cart-root class="w-12 ml-1 sm:ml-2 flex justify-center items-center"><button data-fs-cart-button class="cursor-pointer border-none rounded-md bg-white p-2 hidden" type="button" aria-label="Items in cart, view bag"><div class="relative"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" data-slot="icon" class="h-5 w-5 flex-shrink-0 text-blue group-hover:text-blue-600"><path d="M1 1.75A.75.75 0 0 1 1.75 1h1.628a1.75 1.75 0 0 1 1.734 1.51L5.18 3a65.25 65.25 0 0 1 13.36 1.412.75.75 0 0 1 .58.875 48.645 48.645 0 0 1-1.618 6.2.75.75 0 0 1-.712.513H6a2.503 2.503 0 0 0-2.292 1.5H17.25a.75.75 0 0 1 0 1.5H2.76a.75.75 0 0 1-.748-.807 4.002 4.002 0 0 1 2.716-3.486L3.626 2.716a.25.25 0 0 0-.248-.216H1.75A.75.75 0 0 1 1 1.75ZM6 17.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM15.5 19a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg><div class="absolute bg-red rounded-full w-3 h-3 -top-3 -right-3"> </div></div><span class="sr-only">items in cart, view bag</span></button></div><!--astro:end--></astro-island> </div> </div> <nav class="astronav-items astronav-toggle hidden w-full lg:w-auto mt-2 lg:flex lg:mt-0">   <ul class="max-lg:hidden flex flex-col lg:flex-row lg:gap-3 items-center"> <li> <a href="/en/typinator/" class="flex lg:px-3 py-2 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 transition focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded-full"> Typinator </a> </li><li> <a href="/en/popchar/" class="flex lg:px-3 py-2 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 transition focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded-full"> PopChar </a> </li><li> <a href="/en/keycue/" class="flex lg:px-3 py-2 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 transition focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded-full"> KeyCue </a> </li><li> <a href="https://blog.ergonis.com/hc" class="flex lg:px-3 py-2 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 transition focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded-full"> Blog </a> </li><li> <a href="/en/store/" class="flex lg:px-3 py-2 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 transition focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded-full"> Store </a> </li> <li> <astro-island uid="18ihxa" prefix="s2" component-url="/_astro/language-selector.ux4d6awT.js" component-export="default" renderer-url="/_astro/client.CSC4vdki.js" props="{&quot;currentLocale&quot;:[0,&quot;en&quot;],&quot;currentPath&quot;:[0,&quot;/en/store/&quot;]}" ssr client="load" opts="{&quot;name&quot;:&quot;LanguageSelector&quot;,&quot;value&quot;:true}" await-children><!--[--><div class="sm:ml-3 xl:ml-8 relative" data-headlessui-state><button id="headlessui-listbox-button-s2-0" type="button" aria-haspopup="listbox" aria-expanded="false" data-headlessui-state class="relative flex space-x-2 p-2 rounded-md text-sm text-gray-600 hover:text-blue-600 cursor-pointer" data-testid="navbar-button-language"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" data-slot="icon" class="h-5 w-5 shrink-0"><path d="M16.555 5.412a8.028 8.028 0 0 0-3.503-2.81 14.899 14.899 0 0 1 1.663 4.472 8.547 8.547 0 0 0 1.84-1.662ZM13.326 7.825a13.43 13.43 0 0 0-2.413-5.773 8.087 8.087 0 0 0-1.826 0 13.43 13.43 0 0 0-2.413 5.773A8.473 8.473 0 0 0 10 8.5c1.18 0 2.304-.24 3.326-.675ZM6.514 9.376A9.98 9.98 0 0 0 10 10c1.226 0 2.4-.22 3.486-.624a13.54 13.54 0 0 1-.351 3.759A13.54 13.54 0 0 1 10 13.5c-1.079 0-2.128-.127-3.134-.366a13.538 13.538 0 0 1-.352-3.758ZM5.285 7.074a14.9 14.9 0 0 1 1.663-4.471 8.028 8.028 0 0 0-3.503 2.81c.529.638 1.149 1.199 1.84 1.66ZM17.334 6.798a7.973 7.973 0 0 1 .614 4.115 13.47 13.47 0 0 1-3.178 1.72 15.093 15.093 0 0 0 .174-3.939 10.043 10.043 0 0 0 2.39-1.896ZM2.666 6.798a10.042 
1510.042 0 0 0 2.39 1.896 15.196 15.196 0 0 0 .174 3.94 13.472 13.472 0 0 1-3.178-1.72 7.973 7.973 0 0 1 .615-4.115ZM10 15c.898 0 1.778-.079 2.633-.23a13.473 13.473 0 0 1-1.72 3.178 8.099 8.099 0 0 1-1.826 0 13.47 13.47 0 0 1-1.72-3.178c.855.151 1.735.23 2.633.23ZM14.357 14.357a14.912 14.912 0 0 1-1.305 3.04 8.027 8.027 0 0 0 4.345-4.345c-.953.542-1.971.981-3.04 1.305ZM6.948 17.397a8.027 8.027 0 0 1-4.345-4.345c.953.542 1.971.981 3.04 1.305a14.912 14.912 0 0 0 1.305 3.04Z"></path></svg><span class="uppercase">EN</span></button><!----></div><!--]--><!--astro:end--></astro-island> </li> <li> <astro-island uid="ZEid06" prefix="s3" component-url="/_astro/cart-button.KPuct_VM.js" component-export="default" renderer-url="/_astro/client.CSC4vdki.js" props="{}" ssr client="load" opts="{&quot;name&quot;:&quot;CartButton&quot;,&quot;value&quot;:true}" await-children><div data-fs-cart-root class="w-12 ml-1 sm:ml-2 flex justify-center items-center"><button data-fs-cart-button class="cursor-pointer border-none rounded-md bg-white p-2 hidden" type="button" aria-label="Items in cart, view bag"><div class="relative"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" data-slot="icon" class="h-5 w-5 flex-shrink-0 text-blue group-hover:text-blue-600"><path d="M1 1.75A.75.75 0 0 1 1.75 1h1.628a1.75 1.75 0 0 1 1.734 1.51L5.18 3a65.25 65.25 0 0 1 13.36 1.412.75.75 0 0 1 .58.875 48.645 48.645 0 0 1-1.618 6.2.75.75 0 0 1-.712.513H6a2.503 2.503 0 0 0-2.292 1.5H17.25a.75.75 0 0 1 0 1.5H2.76a.75.75 0 0 1-.748-.807 4.002 4.002 0 0 1 2.716-3.486L3.626 2.716a.25.25 0 0 0-.248-.216H1.75A.75.75 0 0 1 1 1.75ZM6 17.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM15.5 19a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg><div class="absolute bg-red rounded-full w-3 h-3 -top-3 -right-3"> </div></div><span class="sr-only">items in cart, view bag</span></button></div><!--astro:end--></astro-island> </li> </ul>  <ul class="flex flex-col lg:hidden lg:flex-row lg:gap-3 items-left"> <li class="relative z-50 isolate"> <menu class="astronav-dropdown group" aria-expanded="false"> <button class="flex items-center gap-1 text-sm w-full lg:w-auto transition lg:px-3 py-2 text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded-full"> <span>Typinator</span> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="3" stroke="currentColor" class="w-3 h-3 mt-0.5 group-open:rotate-180"> <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 8.25l-7.5 7.5-7.5-7.5"></path> </svg> </button> <div class="astronav-dropdown dropdown-toggle hidden" aria-expanded="false">  <div class="lg:absolute w-full lg:w-48 z-50 border-l lg:border-0 border-gray-200 lg:left-0 origin-top-left"> <div class="px-3 lg:py-2 lg:bg-white lg:rounded-md lg:shadow lg:border flex flex-col"> <a href="/en/typinator/" class="py-1 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded"> Overview </a><a href="/en/typinator/features/" class="py-1 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded"> Features </a><a href="/en/typinator/extensions/" class="py-1 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded"> Extensions </a><a href="/en/typinator/pricing/" class="py-1 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded"> Pricing </a><a href="https://help.typinator.ergonis.com/" class="py-1 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded"> Help </a><a href="/en/store/" class="py-1 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded"> Store </a> </div> </div>  </div> </menu> </li><li class="relative z-50 isolate">
15 <menu class="astronav-dropdown group" aria-expanded="false"> <button class="flex items-center gap-1 text-sm w-full lg:w-auto transition lg:px-3 py-2 text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded-full"> <span>PopChar</span> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="3" stroke="currentColor" class="w-3 h-3 mt-0.5 group-open:rotate-180"> <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 8.25l-7.5 7.5-7.5-7.5"></path> </svg> </button> <div class="astronav-dropdown dropdown-toggle hidden" aria-expanded="false">  <div class="lg:absolute w-full lg:w-48 z-50 border-l lg:border-0 border-gray-200 lg:left-0 origin-top-left"> <div class="px-3 lg:py-2 lg:bg-white lg:rounded-md lg:shadow lg:border flex flex-col"> <a href="/en/popchar/" class="py-1 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded"> Overview </a><a href="/en/popchar/features/" class="py-1 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded"> Features </a><a href="/en/popchar/extensions/" class="py-1 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded"> Extensions </a><a href="/en/popchar/pricing/" class="py-1 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded"> Pricing </a><a href="https://help.popchar.ergonis.com/" class="py-1 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded"> Help </a><a href="/en/store/" class="py-1 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded"> Store </a> </div> </div>  </div> </menu> </li><li class="relative z-50 isolate"> <menu class="astronav-dropdown group" aria-expanded="false"> <button class="flex items-center gap-1 text-sm w-full lg:w-auto transition lg:px-3 py-2 text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded-full"> <span>KeyCue</span> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="3" stroke="currentColor" class="w-3 h-3 mt-0.5 group-open:rotate-180"> <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 8.25l-7.5 7.5-7.5-7.5"></path> </svg> </button> <div class="astronav-dropdown dropdown-toggle hidden" aria-expanded="false">  <div class="lg:absolute w-full lg:w-48 z-50 border-l lg:border-0 border-gray-200 lg:left-0 origin-top-left"> <div class="px-3 lg:py-2 lg:bg-white lg:rounded-md lg:shadow lg:border flex flex-col"> <a href="/en/keycue/" class="py-1 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded"> Overview </a><a href="/en/keycue/features/" class="py-1 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded"> Features </a><a href="/en/keycue/extensions/" class="py-1 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded"> Extensions </a><a href="/en/keycue/pricing/" class="py-1 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded"> Pricing </a><a href="https://help.keycue.ergonis.com/" class="py-1 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded"> Help </a><a href="/en/store/" class="py-1 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded"> Store </a> </div> </div>  </div> </menu> </li><li> <a href="https://blog.ergonis.com/hc" class="flex lg:px-3 py-2 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 transition focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded-full"> Blog </a> </li><li> <a href="/en/store/" class="flex lg:px-3 py-2 text-sm text-gray-600 hover:text-blue-600 focus-visible:ring-2 focus-visible:ring-offset-2 transition focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue rounded-full"> Store </a> </li> </ul>  </nav>  
15<script>(function(){const closeOnClick = false;
16
17["DOMContentLoaded", "astro:after-swap"].forEach((event) => {
18  document.addEventListener(event, addListeners);
19});
20
21// Function to clone and replace elements
22function cloneAndReplace(element) {
23  const clone = element.cloneNode(true);
24  element.parentNode.replaceChild(clone, element);
25}
26
27function addListeners() {
28  // Clean up existing listeners
29  const oldMenuButton = document.getElementById("astronav-menu");
30  if (oldMenuButton) {
31    cloneAndReplace(oldMenuButton);
32  }
33
34  const oldDropdownMenus = document.querySelectorAll(".astronav-dropdown");
35  oldDropdownMenus.forEach((menu) => {
36    cloneAndReplace(menu);
37  });
38
39  // Mobile nav toggle
40  const menuButton = document.getElementById("astronav-menu");
41  menuButton && menuButton.addEventListener("click", toggleMobileNav);
42
43  // Dropdown menus
44  const dropdownMenus = document.querySelectorAll(".astronav-dropdown");
45  dropdownMenus.forEach((menu) => {
46    const button = menu.querySelector("button");
47    button &&
48      button.addEventListener("click", (event) =>
49        toggleDropdownMenu(event, menu, dropdownMenus)
50      );
51
52    // Handle Submenu Dropdowns
53    const dropDownSubmenus = menu.querySelectorAll(
54      ".astronav-dropdown-submenu"
55    );
56
57    dropDownSubmenus.forEach((submenu) => {
58      const submenuButton = submenu.querySelector("button");
59      submenuButton &&
60        submenuButton.addEventListener("click", (event) => {
61          event.stopImmediatePropagation();
62          toggleSubmenuDropdown(event, submenu);
63        });
64    });
65  });
66
67  // Clicking away from dropdown will remove the dropdown class
68  document.addEventListener("click", closeAllDropdowns);
69
70  if (closeOnClick) {
71    handleCloseOnClick();
72  }
73}
74
75function toggleMobileNav() {
76  [...document.querySelectorAll(".astronav-toggle")].forEach((el) => {
77    el.classList.toggle("hidden");
78  });
79}
80
81function toggleDropdownMenu(event, menu, dropdownMenus) {
82  toggleMenu(menu);
83
84  // Close one dropdown when selecting another
85  Array.from(dropdownMenus)
86    .filter((el) => el !== menu && !menu.contains(el))
87    .forEach(closeMenu);
88
89  event.stopPropagation();
90}
91
92function toggleSubmenuDropdown(event, submenu) {
93  event.stopPropagation();
94  toggleMenu(submenu);
95
96  // Close sibling submenus at the same nesting level
97  const siblingSubmenus = submenu
98    .closest(".astronav-dropdown")
99    .querySelectorAll(".astronav-dropdown-submenu");
100  Array.from(siblingSubmenus)
101    .filter((el) => el !== submenu && !submenu.contains(el))
102    .forEach(closeMenu);
103}
104
105function closeAllDropdowns(event) {
106  const dropdownMenus = document.querySelectorAll(".dropdown-toggle");
107  const dropdownParent = document.querySelectorAll(
108    ".astronav-dropdown, .astronav-dropdown-submenu"
109  );
110  const isButtonInsideDropdown = [
111    ...document.querySelectorAll(
112      `.astronav-dropdown button, .astronav-dropdown label, .astronav-dropdown input,
113	  .astronav-dropdown-submenu button, .astronav-dropdown-submenu label, .astronav-dropdown-submenu input,
114	  #astronav-menu`
115    ),
116  ].some((button) => button.contains(event.target));
117  if (!isButtonInsideDropdown) {
118    dropdownMenus.forEach((d) => {
119      // console.log("I ran", d);
120      // if (!d.contains(event.target)) {
121      d.classList.remove("open");
122      d.removeAttribute("open");
123      d.classList.add("hidden");
124      // }
125    });
126    dropdownParent.forEach((d) => {
127      d.classList.remove("open");
128      d.removeAttribute("open");
129      d.setAttribute("aria-expanded", "false");
130    });
131  }
132}
133
134function toggleMenu(menu) {
135  menu.classList.toggle("open");
136  const expanded = menu.getAttribute("aria-expanded") === "true";
137  menu.setAttribute("aria-expanded", expanded ? "false" : "true");
138  menu.hasAttribute("open")
139    ? menu.removeAttribute("open")
140    : menu.setAttribute("open", "");
141
142  const dropdownToggle = menu.querySelector(".dropdown-toggle");
143  const dropdownExpanded = dropdownToggle.getAttribute("aria-expanded");
144  dropdownToggle.classList.toggle("hidden");
145  dropdownToggle.setAttribute(
146    "aria-expanded",
147    dropdownExpanded === "true" ? "false" : "true"
148  );
149}
150
151function closeMenu(menu) {
152  // console.log("closing", menu);
153  menu.classList.remove("open");
154  menu.removeAttribute("open");
155  menu.setAttribute("aria-expanded", "false");
156  const dropdownToggles = menu.querySelectorAll(".dropdown-toggle");
157  dropdownToggles.forEach((toggle) => {
158    toggle.classList.add("hidden");
159    toggle.setAttribute("aria-expanded", "false");
160  });
161}
162
163function handleCloseOnClick() {
164  const navMenuItems = document.querySelector(".astronav-items");
165  const navToggle = document.getElementById("astronav-menu");
166  const navLink = navMenuItems && navMenuItems.querySelectorAll("a");
167
168  const MenuIcons = navToggle.querySelectorAll(".astronav-toggle");
169
170  navLink &&
171    navLink.forEach((item) => {
172      item.addEventListener("click", () => {
173        navMenuItems?.classList.add("hidden");
174        MenuIcons.forEach((el) => {
175          el.classList.toggle("hidden");
176        });
177      });
178    });
179}
180})();</script>
180 </div>  </div>  </header> 
180<script data-astro-rerun>(function(){const scrollY = 20;
181const defaultClass = "py-5 border-transparent";
182const activeClass = "py-2 bg-white/80 border-gray-200 backdrop-blur-lg";
183
184  // @ts-nocheck
185  let lastKnownScrollPosition = 0;
186  let ticking = false;
187
188  const header = document.querySelector(".astronav-sticky-header");
189
190  // Define two different scroll positions
191  const addScrollY = Math.max(scrollY, 50); // Scroll position to add active class
192  const removeScrollY = Math.max(scrollY - 50, 10); // Scroll position to remove active class
193
194  function updateAnimation(scrollPos) {
195    if (scrollPos > addScrollY) {
196      header.classList.remove(...defaultClass.split(" "));
197      header.classList.add("is-active", ...activeClass.split(" "));
198      header.setAttribute("active", "");
199    } else if (scrollPos < removeScrollY) {
200      header.classList.remove("is-active", ...activeClass.split(" "));
201      header.classList.add(...defaultClass.split(" "));
202      header.removeAttribute("active");
203    }
204  }
205
206  window.addEventListener("scroll", function () {
207    lastKnownScrollPosition = window.scrollY;
208    if (!ticking) {
209      window.requestAnimationFrame(function () {
210        updateAnimation(lastKnownScrollPosition);
211        ticking = false;
212      });
213
214      ticking = true;
215    }
216  });
217})();</script>
217  <div class="flex-1"> <div class="container relative">  <h1 class="display-h1 text-center py-12">Boost your <span class="colored">productivity</span></h1> <div class="grid grid-cols-1 gap-6 md:grid-cols-3"> <!-- Typinator --> <div class="rounded-4xl relative bg-gray-50/50 transition-all ring-3 ring-gray-100  p-6 md:p-8 flex flex-col items-center justify-center">  <img src="/_astro/typinator_icon.Bjymz9Yl_ZovnhR.svg" alt="Typinator Logo" loading="lazy" decoding="async" fetchpriority="auto" width="1024" height="1024" class="mb-6 w-1/3 mx-auto"> <h1 class="text-lg font-semibold mb-1 text-center">Typinator</h1> <p class="text-sm text-gray-600 text-center mb-4">starting at 29.99 USD</p> <div class="flex center"> <a href="/en/typinator/pricing/" type="button" id="typinator-buy" class="rounded-full text-center transition focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue inline-flex items-center group gap-px px-7 py-2.5 cursor-pointer text-white bg-linear-to-bl from-blue-900 to-blue-600 hover:from-blue-700 hover:to-blue-600">Buy Typinator  </a> </div>  </div> <!-- PopChar --> <div class="rounded-4xl relative bg-gray-50/50 transition-all ring-3 ring-gray-100  p-6 md:p-8 flex flex-col items-center justify-center">  <img src="/_astro/popchar_icon.CCSIZPEp_ZovnhR.svg" alt="Popchar Logo" loading="lazy" decoding="async" fetchpriority="auto" width="1024" height="1024" class="mb-6 w-1/3 mx-auto"> <h1 class="text-lg font-semibold mb-1 text-center">PopChar</h1> <p class="text-sm text-gray-600 text-center mb-4">starting at 19,99 USD</p> <a href="/en/popchar/pricing/" type="button" id="popchar-buy" class="rounded-full text-center transition focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue inline-flex items-center group gap-px px-7 py-2.5 cursor-pointer text-white bg-linear-to-bl from-blue-900 to-blue-600 hover:from-blue-700 hover:to-blue-600">Buy PopChar  </a>  </div> <!-- KeyCue --> <div class="rounded-4xl relative bg-gray-50/50 transition-all ring-3 ring-gray-100  p-6 md:p-8 flex flex-col items-center justify-center">  <img src="/_astro/keycue_icon.D6hqKPbe_ZovnhR.svg" alt="KeyCue Logo" loading="lazy" decoding="async" fetchpriority="auto" width="1024" height="1024" class="mb-6 w-1/3 mx-auto"> <h1 class="text-lg font-semibold mb-1 text-center">KeyCue</h1> <p class="text-sm text-gray-600 text-center mb-4">starting at 19,99 USD</p> <a href="/en/keycue/pricing/" type="button" id="keycue-buy" class="rounded-full text-center transition focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue inline-flex items-center group gap-px px-7 py-2.5 cursor-pointer text-white bg-linear-to-bl from-blue-900 to-blue-600 hover:from-blue-700 hover:to-blue-600">Buy KeyCue  </a>  </div> </div>  </div> 
217<script>
218      (function () {
219        const btn = document.getElementById('buy-typinator');
220        if (btn) {
221          btn.addEventListener('click', () => window.fsAdd('typinator'));
222        }
223      })();
224    </script>
224  <div class="container my-24 grid lg:grid-cols-12 gap-4">  <div class="lg:col-span-8"> <a href="/en/productivity-suite/" class="block rounded-4xl focus:outline-none focus:ring-2 focus:ring-blue-600 focus:ring-offset-2" aria-label="Buy now"> <div class="rounded-4xl suite-gradient p-8 items-center text-center grid grid-cols-1 md:grid-cols-5 space-y-5"> <div class="col-span-3"> <img src="/_astro/suite.C4BHMd6c_HUuTW.svg" alt="Productivity Suite" loading="lazy" decoding="async" fetchpriority="auto" width="2555" height="1208" class="w-1/2 md:w-2/3 mx-auto md:mb-6"> <h3 class="display-h3">Productivity Suite</h3> <!-- ... existing code ... --> </div> <div class="relative col-span-2 bg-white/30 p-4 md:p-8 rounded-4xl"> <div class="text-xs md:text-sm font-bold absolute -top-3 left-1/2 -translate-x-1/2 bg-purple py-1 px-2 rounded-full inline whitespace-nowrap text-white uppercase"> save 33% </div> <h4 class="mt-1"> All three productivity tools in one package </h4> <div class="mb-6"> <span class="text-gray-700">starting at</span> <div class="flex justify-between align-middle text-4xl font-bold tracking-tight space-x-1 w-full mb-2"> <div class="mx-auto"> <span>$44.99</span> <span class="text-sm font-semibold leading-6"> /year </span> </div> </div> </div> <span class="pointer-events-none"> <span class="inline-flex items-center justify-center rounded-full px-5 py-3 font-semibold bg-blue-600 text-white"> Buy now </span> </span> </div> </div> </a> </div> <div class="bg-gray-50 p-8 mt-12 lg:mt-0 rounded-4xl lg:col-span-4 flex items-center justify-center"> <div class="text-center"> <h3> Do you already own an ergonis product? </h3> <p class="mb-6"> Need to upgrade your license? </p> <a href="/en/upgrade/" class="rounded-full text-center transition focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue inline-flex items-center group gap-px px-7 py-2.5 cursor-pointer bg-white text-blue border-3 border-inside border-blue hover:bg-blue-50 text-blue-800 leading-[1.2]">Upgrade now  </a> </div> </div>   </div> </div> <footer class="py-6 md:py-12 bg-gray-100 border-t border-gray-100"> <div class="container">  <div class="grid gap-8 sm:grid-cols-2">   <div class="text-center sm:text-left"> <h3 class="font-medium text-sm text-gray-800"> <a href="/en/about/" class="hover:text-blue-600">Company</a> </h3> <div class="flex flex-col mt-2"> <a href="/en/about/" class="py-2 text-sm text-gray-600 hover:text-blue-600"> About </a><a href="/en/press/" class="py-2 text-sm text-gray-600 hover:text-blue-600"> Press </a><a href="/en/partner/" class="py-2 text-sm text-gray-600 hover:text-blue-600"> Partner </a><a href="/en/affiliate/" class="py-2 text-sm text-gray-600 hover:text-blue-600"> Affiliate </a><a href="https://blog.ergonis.com/hc/" class="py-2 text-sm text-gray-600 hover:text-blue-600" target="_blank" rel="noopener noreferrer"> Blog </a> </div> </div> <div class="text-center sm:text-left"> <h3 class="font-medium text-sm text-gray-800"> <a href="/en/" class="hover:text-blue-600">Products</a> </h3> <div class="flex flex-col mt-3"> <a href="/en/typinator/" class="py-2 text-sm text-gray-600 hover:text-blue-600"> Typinator </a><a href="/en/popchar/" class="py-2 text-sm text-gray-600 hover:text-blue-600"> PopChar </a><a href="/en/keycue/" class="py-2 text-sm text-gray-600 hover:text-blue-600"> KeyCue </a> </div> </div> </div>  </div> <div class="mt-8 pt-6 border-t border-gray-200"> <div class="container">  <div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4"> <div class="flex flex-col sm:flex-row sm:items-center gap-4 text-center sm:text-left"> <a href="/" class="text-lg font-display text-gray-800">ergonis</a> <div class="flex space-x-4 my-6 md:my-4 place-items-center md:order-2 justify-center sm:justify-start"> <a href="https://www.linkedin.com/company/ergonis" target="_blank" class="text-gray-700 hover:text-gray-500 border-none"> <span class="sr-only">LinkedIn</span><svg fill="currentColor" viewBox="0 0 448 512" class="h-6 w-6" aria-hidden="true"><path fill-rule="evenodd" d="M100.3 448H7.4V148.9h92.9zM53.8 108.1C24.1 108.1 0 83.5 0 53.8a53.8 53.8 0 0 1 107.6 0c0 29.7-24.1 54.3-53.8 54.3zM447.9 448h-92.7V302.4c0-34.7-.7-79.2-48.3-79.2-48.3 0-55.7 37.7-55.7 76.7V448h-92.8V148.9h89.1v40.8h1.3c12.4-23.5 42.7-48.3 87.9-48.3 94 0 111.3 61.9 111.3 142.3V448z" clip-rule="evenodd"></path></svg> </a> <a href="https://www.facebook.com/ergonis.software/" target="_blank" class="text-gray-700 hover:text-gray-500 border-none"> <span class="sr-only">Facebook</span> <svg fill="currentColor" viewBox="0 0 24 24" class="h-6 w-6" aria-hidden="true"> <path fill-rule="evenodd" d="M22 12c0-5.523-4.477-10-10-10S2 6.477 2 12c0 4.991 3.657 9.128 8.438 9.878v-6.987
224h-2.54V12h2.54V9.797c0-2.506 1.492-3.89 3.777-3.89 1.094 0 2.238.195 2.238.195v2.46h-1.26c-1.243 0-1.63.771-1.63 1.562V12h2.773l-.443 2.89h-2.33v6.988C18.343 21.128 22 16.991 22 12z" clip-rule="evenodd"></path> </svg> </a><a href="https://www.youtube.com/channel/UC-hzDbZmj5uYDd9DgvIiNVQ" target="_blank" class="text-gray-700 hover:text-gray-500 border-none"> <span class="sr-only">Youtube</span><svg fill="currentColor" viewBox="0 0 36 36" class="h-6 w-6" aria-hidden="true"><path fill-rule="evenodd" d="M31.681 9.6s-.313-2.206-1.275-3.175C29.187 5.15 27.825 5.144 27.2 5.069c-4.475-.325-11.194-.325-11.194-.325h-.012s-6.719 0-11.194.325c-.625.075-1.987.081-3.206 1.356C.631 7.394.325 9.6.325 9.6s-.319 2.588-.319 5.181v2.425c0 2.587.319 5.181.319 5.181s.313 2.206 1.269 3.175c1.219 1.275 2.819 1.231 3.531 1.369 2.563.244 10.881.319 10.881.319s6.725-.012 11.2-.331c.625-.075 1.988-.081 3.206-1.356.962-.969 1.275-3.175 1.275-3.175s.319-2.587.319-5.181v-2.425c-.006-2.588-.325-5.181-.325-5.181zM12.694 20.15v-8.994l8.644 4.513-8.644 4.481z" clip-rule="evenodd"></path></svg></a><a href="https://twitter.com/ergonis/" target="_blank" class="text-gray-700 hover:text-gray-500 border-none"> <span class="sr-only">Twitter</span><svg fill="currentColor" viewBox="0 0 24 24" class="h-6 w-6" aria-hidden="true"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"></path></svg></a> </div> </div> <div class="inline-block max-w-5/6"> <a href="/en/affiliate/" class="rounded-full text-center transition focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500 focus-visible:outline-none focus-visible:shadow-outline-blue inline-flex items-center group gap-px px-4 py-2 cursor-pointer bg-gray-200 text-gray-600 hover:bg-gray-100 border-2 border-transparent hover:border-gray-200"> <span>Join our affiliate program today &amp; get rewarded</span>  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-4 h-4 mt-px group-hover:translate-x-1 transition-transform"> <path fill-rule="evenodd" d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd"></path> </svg> </a> </div> </div> <div class="mt-4 sm:flex sm:justify-between"> <p class="text-center text-xs text-gray-600 mt-2"> <span> <a href="/en/imprint/" class="hover:text-blue-500"> Imprint </a> <span> ・ </span> </span><span> <a href="/en/terms/" class="hover:text-blue-500"> Terms &amp; Conditions </a> <span> ・ </span> </span><span> <a href="/en/privacy/" class="hover:text-blue-500"> Privacy notice </a>  </span> </p> <p class="text-center text-xs text-gray-400 mt-1"><span>Last updated: 2026-09-17</span></p> </div>  </div> </div> </footer> <!-- Define global callbacks before loading the FastSpring script -->
224<script>
225  (function () {
226    var w = window;
227
228    // helper to push events to GTM dataLayer
229    function gtmAddEvent(eventName, payload) {
230      w.dataLayer = w.dataLayer || [];
231      // Nest payload under `ecommerce` — the GA4 tag in GTM reads ecommerce.value /
232      // ecommerce.items. A flat push leaves those empty (0 revenue). See ERGOWEB-1513.
233      w.dataLayer.push({event: eventName, ecommerce: payload || {}});
234    }
235
236    function getQueryParamIRClickId() {
237      try {
238        var urlParams = new URLSearchParams(document.location.search);
239        var clickID = urlParams.get('irClickID');
240        return clickID ? clickID : '';
241      } catch (e) {
242        return '';
243      }
244    }
245
246    // Build GTM item list from the latest FastSpring data (mirrors old helper)
247    function fsGetItemListForGTM() {
248      try {
249        var data = w.fsData;
250        var gtmItems = [];
251        if (data && data.groups && data.groups[0] && data.groups[0].items) {
252          for (var i = 0; i < data.groups[0].items.length; i++) {
253            var item = data.groups[0].items[i];
254            if (item && item.selected) {
255              gtmItems.push({
256                item_name: item.display,
257                item_id: item.variation,
258                price: item.priceValue,
259                quantity: item.quantity
260              });
261            }
262          }
263        }
264        return gtmItems;
265      } catch (e) {
266        return [];
267      }
268    }
269
270    // Ensure fastspring namespace exists
271    w.fastspring = w.fastspring || {initialized: false};
272
273    // Campaign promo: capture ?promo=CODE and persist it (sessionStorage) so it survives
274    // navigation within the visit but expires when the tab/window closes.
275    // It is applied to the cart in fsAddToCart / fsAdd via builder.promo(code).
276    (function captureCampaignPromo() {
277      try {
278        var code = new URLSearchParams(document.location.search).get('promo');
279        if (code) sessionStorage.setItem('campaignPromo', code.trim());
280      } catch (e) {}
281    })();
282    function getCampaignPromo() {
283      try { return sessionStorage.getItem('campaignPromo') || ''; } catch (e) { return ''; }
284    }
285
286    // Register FastSpring callbacks
287    w.fsPopClosed = function (data) {
288      window.dispatchEvent(new CustomEvent('fsPopupClosed', {detail: data}));
289
290      // helper function for getting locale from URL
291      const getLocaleFromUrl = (url) => {
292        try {
293          const path = url || window.location.pathname;
294          const segments = path.split('/').filter(segment => segment.length > 0);
295
296          // Return the first segment if it exists, otherwise null
297          return segments.length > 0 ? segments[0] : 'en';
298        } catch (error) {
299          console.warn('Failed to extract locale from URL:', error);
300          return 'en';
301        }
302      };
303
304
305      // id is only present if a purchase was made
306      if (data && data.id) {
307        // Campaign promo is single-use per session: clear it once redeemed.
308        try { sessionStorage.removeItem('campaignPromo'); } catch (e) {}
309        let purchasedProducts = ''
310        try {
311          purchasedProducts = JSON.parse(localStorage.getItem('purchased_products'));
312        } catch (e) {
313          purchasedProducts = '';
314        }
315        if (purchasedProducts) {
316          const purchasedProductsArray = purchasedProducts.split(',');
317          if (purchasedProductsArray.length > 1 || !purchasedProducts) {
318            // todo generic complete page
319            window.location.href = `/${locale}/store/g/complete`;
320            //todo typinator does not have a complete page yet
321          } else if (purchasedProductsArray.length === 1) {
322            const product = purchasedProductsArray[0].includes('popchar')
323                ? 'popchar' : purchasedProductsArray[0].includes('typinator')
324                    ? 'typinator' : purchasedProductsArray[0].includes('keycue')
325                        ? 'keycue' : 'suite';
326            const locale = getLocaleFromUrl() || 'en';
327            localStorage.setItem('purchased_products', '')
328            window.location.href = `/${locale}/store/${product}/complete`;
329          }
330        }
331      }
332      localStorage.setItem('purchased_products', '')
333
334    };
335
336    w.fsDataCallback = function (data) {
337      try {
338        if (!w.fastspring || !w.fastspring.initialized) {
339          var fsBuilder = w.fastspring ? w.fastspring.builder : undefined;
340          // Announce that the builder is available for consumers
341          window.dispatchEvent(new CustomEvent('fsBuilderReady', {detail: {builder: fsBuilder}}));
342          if (w.fastspring) w.fastspring.initialized = true;
343        }
344        // Expose last fs data to window and emit event
345        w.fsData = data;
346        window.dispatchEvent(new CustomEvent('fsData', {detail: data}));
347      } catch (e) {
348        console.error('fsDataCallback error', e);
349      }
350    };
351
352    w.fsWebhookReceived = function (data) {
353      if (!data) {
354        return;
355      }
356
357      var gtmItem = {};
358      gtmItem.currency = data.currency;
359      gtmItem.value = data.total;
360      gtmItem.transaction_id = data.reference;
361      gtmItem.tax = data.tax;
362
363      if (data.items && data.items.length > 0) {
364        gtmItem.items = [];
365        for (var i = 0; i < data.items.length; i++) {
366          var item = data.items[i];
367          gtmItem.items.push({
368            item_name: item.product,
369            item_id: item.product,
370            price: item.subtotal,
371            quantity: item.quantity,
372            item_coupon: item.coupon
373          });
374        }
375
376        if (data.items && data.items.length > 0) {
377          localStorage.setItem('purchased_products', JSON.stringify(data.items.map(i => i.product).join(',')));
378        } else {
379          localStorage.setItem('purchased_products', '');
380        }
381      }
382
383      gtmAddEvent('purchase', gtmItem);
384      // Also emit a DOM event for app listeners
385      window.dispatchEvent(new CustomEvent('fsPurchase', {detail: gtmItem}));
386    };
387
388    w.fsErrorOccurred = function (errorCode, errorMessage) {
389      var detail = {code: errorCode, message: errorMessage};
390      console.error('FastSpring error', detail);
391      window.dispatchEvent(new CustomEvent('fsError', {detail: detail}));
392      // Avoid throwing globally in the browser; let consumers handle via event
393    };
394
395    w.fsDataDecorateCallback = function (url) {
396      try {
397        var irClickID = getQueryParamIRClickId();
398        if (irClickID) {
399          try {
400            localStorage.setItem('irClickID', irClickID);
401          } catch (e) {
402          }
403          var hasQuery = url.indexOf('?') > -1;
404          var delim = hasQuery ? '&' : '?';
405          return url + delim + 'irClickID=' + encodeURIComponent(irClickID);
406        }
407      } catch (e) {
408        console.warn('fsDataDecorateCallback failed', e);
409      }
410      return url;
411    };
412
413    // Utility access to the builder
414    function getBuilder() {
415      return (w.fastspring && w.fastspring.builder) ? w.fastspring.builder : null;
416    }
417
418    // Ported utility: open cart with GTM event
419    w.fsOpenCart = function () {
420      try {
421        gtmAddEvent('view_cart', {items: fsGetItemListForGTM()});
422      } catch (e) {
423      }
424      var b = getBuilder();
425      if (b && typeof b.viewCart === 'function') {
426        try {
427          b.viewCart();
428        } catch (e) {
429        }
430      } else if (b && typeof b.checkout === 'function') {
431        try {
432          b.checkout();
433        } catch (e) {
434        }
435      } else {
436        console.warn('FastSpring builder not ready for fsOpenCart');
437      }
438    };
439
440    // Ported utility: checkout
441    w.fsCheckout = function () {
442      var b = getBuilder();
443      if (b && typeof b.checkout === 'function') {
444        try {
445          b.checkout();
446        } catch (e) {
447        }
448      } else {
449        console.warn('FastSpring builder not ready for fsCheckout');
450      }
451    };
452
453    // Ported utility: add single product then checkout
454    w.fsAdd = function (product) {
455      var b = getBuilder();
456      if (!b || typeof b.add !== 'function') {
457        console.warn('FastSpring builder not ready for fsAdd');
458        return;
459      }
460      try {
461        b.add(product, function () {
462          try {
463            var promo = getCampaignPromo();
464            if (promo && typeof b.promo === 'function') b.promo(promo);
465          } catch (e) {
466          }
467          try {
468            gtmAddEvent('begin_checkout', {items: fsGetItemListForGTM()});
469          } catch (e) {
470          }
471          try {
472            b.checkout();
473          } catch (e) {
474          }
475        });
476      } catch (e) {
477        console.error('fsAdd failed', e);
478      }
479    };
480
481    // Ported utility: add multiple items (with upgrade quantity fix), optional open cart, optional tag
482    w.fsAddToCart = function (items, shouldOpenCart, sessionTags) {
483      var b = getBuilder();
484      if (!b || typeof b.push !== 'function') {
485        console.warn('FastSpring builder not ready for fsAddToCart');
486        return;
487      }
488      try {
489        b.push({reset: false, products: items}, function () {
490          try {
491            for (var i = 0; i < items.length; i++) {
492              var item = items[i];
493              // Set quantity to the defined number if > 1 as builder otherwise doesn't allow setting the quantity for upgrades and grace products
494              if (item && typeof item.quantity === 'number' && item.quantity > 1 && typeof item.path === 'string' && (item.path.endsWith('-upgrade') || item.path.includes('-grace'))) {
495                if (typeof b.update === 'function') {
496                  try {
497                    b.update(item.path, item.quantity);
498                  } catch (e) {
499                  }
500                }
501              }
502            }
503          } catch (e) {
504          }
505
506          try {
507            if (sessionTags && typeof b.tag === 'function') {
508              b.tag(sessionTags);
509            }
510          } catch (e) {
511          }
512
513          // Apply campaign promo captured from ?promo=CODE
514          try {
515            var promo = getCampaignPromo();
516            if (promo && typeof b.promo === 'function') b.promo(promo);
517          } catch (e) {
518          }
519
520          try {
521            gtmAddEvent('begin_checkout', {items: fsGetItemListForGTM()});
522          } catch (e) {
523          }
524
525          if (shouldOpenCart) {
526            if (typeof b.viewCart === 'function') {
527              try {
528                b.viewCart();
529              } catch (e) {
530              }
531            } else {
532              try {
533                b.checkout();
534              } catch (e) {
535              }
536            }
537          }
538        });
539      } catch (e) {
540        console.error('fsAddToCart failed', e);
541      }
542    };
543
544    // Ported utility: add bundle then checkout
545    w.fsAddBundle = function () {
546      var b = getBuilder();
547      if (!b || typeof b.add !== 'function') {
548        console.warn('FastSpring builder not ready for fsAddBundle');
549        return;
550      }
551      try {
552        b.add('typinator');
553        b.add('popchar-mac');
554        b.add('keycue');
555        if (typeof b.checkout === 'function') {
556          try {
557            b.checkout();
558          } catch (e) {
559          }
560        }
561      } catch (e) {
562        console.error('fsAddBundle failed', e);
563      }
564    };
565
566    // Ported utility: apply coupon and open cart
567    w.fsApplyCoupon = function (couponCode) {
568      var b = getBuilder();
569      if (!b || typeof b.promo !== 'function') {
570        console.warn('FastSpring builder not ready for fsApplyCoupon');
571        return;
572      }
573      try {
574        b.promo(couponCode);
575        if (typeof b.viewCart === 'function') {
576          try {
577            b.viewCart();
578          } catch (e) {
579          }
580        }
581      } catch (e) {
582        console.error('fsApplyCoupon failed', e);
583      }
584    };
585
586    // Expose the GTM item builder for external use if needed
587    w.fsGetItemListForGTM = fsGetItemListForGTM;
588  })();
589</script>
589 <!-- Load the FastSpring builder -->
589<script id="fsc-api" src="https://sbl.onfastspring.com/sbl/1.0.5/fastspring-builder.min.js" data-storefront="ergonis.onfastspring.com/popup-default" data-popup-closed="fsPopClosed" data-data-callback="fsDataCallback" data-error-callback="fsErrorOccurred" data-popup-webhook-received="fsWebhookReceived" data-decorate-callback="fsDataDecorateCallback" data-continuous="true" data-access-key="DYZVVZ8URXK8XZ4TXL2X7Q"></script>
589 <vercel-speed-insights data-props="{}" data-params="{&#34;locale&#34;:&#34;en&#34;}" data-pathname="/en/store/"></vercel-speed-insights> 
589<script type="module">var o="@vercel/speed-insights",u="1.3.1",f=()=>{window.si||(window.si=function(...r){(window.siq=window.siq||[]).push(r)})};function l(){return typeof window<"u"}function h(){try{const e="production"}catch{}return"production"}function d(){return h()==="development"}function v(e,r){if(!e||!r)return e;let n=e;try{const t=Object.entries(r);for(const[s,i]of t)if(!Array.isArray(i)){const a=c(i);a.test(n)&&(n=n.replace(a,`/[${s}]`))}for(const[s,i]of t)if(Array.isArray(i)){const a=c(i.join("/"));a.test(n)&&(n=n.replace(a,`/[...${s}]`))}return n}catch{return e}}function c(e){return new RegExp(`/${g(e)}(?=[/?#]|$)`)}function g(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function m(e){return e.scriptSrc?e.scriptSrc:d()?"https://va.vercel-scripts.com/v1/speed-insights/script.debug.js":e.dsn?"https://va.vercel-scripts.com/v1/speed-insights/script.js":e.basePath?`${e.basePath}/speed-insights/script.js`:"/_vercel/speed-insights/script.js"}function w(e={}){var r;if(!l()||e.route===null)return null;f();const n=m(e);if(document.head.querySelector(`script[src*="${n}"]`))return null;e.beforeSend&&((r=window.si)==null||r.call(window,"beforeSend",e.beforeSend));const t=document.createElement("script");return t.src=n,t.defer=!0,t.dataset.sdkn=o+(e.framework?`/${e.framework}`:""),t.dataset.sdkv=u,e.sampleRate&&(t.dataset.sampleRate=e.sampleRate.toString()),e.route&&(t.dataset.route=e.route),e.endpoint?t.dataset.endpoint=e.endpoint:e.basePath&&(t.dataset.endpoint=`${e.basePath}/speed-insights/vitals`),e.dsn&&(t.dataset.dsn=e.dsn),d()&&e.debug===!1&&(t.dataset.debug="false"),t.onerror=()=>{console.log(`[Vercel Speed Insights] Failed to load script from ${n}. Please check if any content blockers are enabled and try again.`)},document.head.appendChild(t),{setRoute:s=>{t.dataset.route=s??void 0}}}function p(){try{return}catch{}}customElements.define("vercel-speed-insights",class extends HTMLElement{constructor(){super();try{const r=JSON.parse(this.dataset.props??"{}"),n=JSON.parse(this.dataset.params??"{}"),t=v(this.dataset.pathname??"",n);w({route:t,...r,framework:"astro",basePath:p(),beforeSend:window.speedInsightsBeforeSend})}catch(r){throw new Error(`Failed to parse SpeedInsights properties: ${r}`)}}});</script>
589 </div> </body></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.