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="{"locale":"en"}" 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="{"currentLocale":[0,"en"],"currentPath":[0,"/en/store/"]}" ssr client="load" opts="{"name":"LanguageSelector","value":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="{"name":"CartButton","value":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="{"currentLocale":[0,"en"],"currentPath":[0,"/en/store/"]}" ssr client="load" opts="{"name":"LanguageSelector","value":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="{"name":"CartButton","value":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 & 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 & 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="{"locale":"en"}" 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.