Beta-invitation pill and modal for the old emojicopy.com site and the Chrome-extension popup. Ship one site modal — B or D; F is the extension's.
<button class="ec-upgrade-pill" type="button" data-ec-open>
<span class="ecu-spark" aria-hidden="true"></span>
<span class="ecu-label">JOIN THE BETA!</span>
<span class="ecu-arrow" aria-hidden="true">→</span>
</button>
:root {
--ecu-green: #30D90A; /* EmojiCopy logo green */
--ecu-green-deep: #1f9c06; /* darker — for text / hover / contrast on white */
--ecu-green-soft: #e4fbdb; /* light tint — for backgrounds */
--ecu-navy: #1a1a2e;
/* JoyPixels party-popper (🎉) artwork as a data URI.
Swap for your own asset path/version if preferred. */
--ecu-party: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODIiIGhlaWdodD0iODIiIHZpZXdCb3g9IjAgMCA4MiA4MiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTE2LjA3NzkgMzcuNDgwNUMxNi4wNzc5IDM3LjQ4MDUgMTYuMDc3OSAzNy40ODA1IDIuNTgwOTYgNzcuNzAyQzIuMzgwMzcgNzguMzAyNSAyLjkzMjY0IDc4Ljg4NzggMy41NDMzIDc4LjY2NjlDNDIuMjE1OSA2NC42NzQ4IDQyLjIxNTkgNjQuNjc0OCA0Mi4yMTU5IDY0LjY3NDhMMTYuMDc3OSAzNy40ODA1WiIgZmlsbD0idXJsKCNwYWludDBfbGluZWFyXzQyMV8xODA0KSIvPgo8cGF0aCBkPSJNMzQuODAxNyA0NS40MzY5QzQyLjE4NTYgNTIuOTU3OSA0NS45OTY5IDYxLjI2OTggNDMuMzE2OCA2NC4wMDA3QzQwLjYzNDIgNjYuNzMxNSAzMi40NjgyIDYyLjg1MTcgMjUuMDgxOCA1NS4zMzA3QzE3LjY5OCA0Ny44MTEgMTMuODg2NyAzOS40OTkxIDE2LjU2OTMgMzYuNzY4MkMxOS4yNTE5IDM0LjAzNjEgMjcuNDE1MyAzNy45MTg0IDM0LjgwMTcgNDUuNDM2OVoiIGZpbGw9IiNFODhBMzAiLz4KPHBhdGggb3BhY2l0eT0iMC4zIiBkPSJNMTMuMjQ2OSA2MS43ODE1TDEyLjU3MDIgNTcuODEyOEw5LjU5MTggNTYuODA5OEw5Ljg5MTQyIDU1LjkxODZMMTIuMzIxNCA1NC42NjQyTDEyLjM2NTggNTAuNjM5NkwxNS4yNDI3IDUzLjQ1M0wxOS4wNzY4IDUyLjI0OTVMMTcuMjk1NiA1NS44NTM4TDE5LjYyNjUgNTkuMTM0NEwxNS42NDY0IDU4LjU1MTdMMTMuMjQ2OSA2MS43ODE1WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggb3BhY2l0eT0iMC4zIiBkPSJNMTkuNjk2MiA2OS43NjEzTDE2LjExNDcgNzEuNTkwN0wxOS42NzM0IDcyLjgzMjRMMjQuNjk5NiA3MS4wMTE4TDI2LjQ3NyA2Ny40MTg5TDIyLjYyOSA2OC41ODE4TDE5Ljc4MjYgNjUuNzM5M0wxOS42OTYyIDY5Ljc2MTNaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBvcGFjaXR5PSIwLjMiIGQ9Ik0zLjAyMjk1IDc2LjM4NTZMNS40NzcwNCA3My42NzI1TDguOTc4NTQgNzQuNTUzNkw3LjE5NjA1IDcxLjQxMjZMOS4xMTgyIDY4LjM1NTVMNS40NDUzIDY5LjE2NTVMMy4wMjI5NSA3Ni4zODU2WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTM0LjY2ODMgNDUuNTcxOUM0MS45MTEyIDUyLjk0MzEgNDUuNzAyMiA2MS4wMzI4IDQzLjE0NjYgNjMuNjQxOEM0MC41ODQ1IDY2LjI0NyAzMi42MzgyIDYyLjM4NzUgMjUuMzk1MyA1NS4wMTVDMTguMTU0OSA0Ny42NDg5IDE0LjM2MTQgMzkuNTU5MiAxNi45MjIxIDM2Ljk1MTRDMTkuNDgwMyAzNC4zNDEyIDI3LjQyOTIgMzguMjAzMyAzNC42NjgzIDQ1LjU3MTlaIiBmaWxsPSJ1cmwoI3BhaW50MV9yYWRpYWxfNDIxXzE4MDQpIi8+CjxwYXRoIGQ9Ik01NC45Njg4IDEwLjQxMjJDNTcuNjQ2MyA4Ljk3MzgyIDY4LjAxNjIgMTguMTIyNCA2Mi42MzgzIDI1LjU1N0M2Mi4yNTg3IDI2LjA4NTIgNjUuMTkwMSAyNC4wMTQ1IDY1LjAwODYgMjQuNTU3OUM3Mi4wNjg3IDE2LjcxMTkgNTguNTI3NCA1LjA0OTU1IDU2Ljg5OTggNy40OTg1N0M1NS4xMzI1IDEwLjE2MDkgNTYuNzM0NyA3Ljc0OTk0IDU0Ljk2ODggMTAuNDEyMloiIGZpbGw9InVybCgjcGFpbnQyX2xpbmVhcl80MjFfMTgwNCkiLz4KPHBhdGggZD0iTTU2Ljg5NzYgNy40OTUxMkM1Ni4wOTY1IDEyLjA4NzIgNjkuNzQ3IDE0LjYwODYgNzQuOTAyOCA5LjY1MjEzQzcwLjQxMjMgMTkuMjAwNiA1NS43NDk5IDE2LjUzNDUgNTQuMTkyMSAxMS41NzA1QzUzLjgxODkgMTAuMzY1NiA1NS4xMzI5IDEwLjE1ODcgNTYuODk3NiA3LjQ5NTEyWiIgZmlsbD0idXJsKCNwYWludDNfbGluZWFyXzQyMV8xODA0KSIvPgo8cGF0aCBkPSJNNDcuNTM2NiAyMS43NzE3QzUwLjIwOTEgMjAuMzM3IDYxLjA0NjIgMjguODg2NCA1NS41MjEgMzguMDAzMkM1NS4xODA3IDM4LjU2NjkgNTcuNzYwNSAzNS4zNjYzIDU3LjU3NjQgMzUuOTE2QzY0LjYzNCAyOC4wNjg4IDUxLjA5NTIgMTYuNDA5IDQ5LjQ2NzYgMTguODU2N0M0Ny43MDA0IDIxLjUyMDMgNDkuMzA1MSAxOS4xMTA2IDQ3LjUzNjYgMjEuNzcxN1oiIGZpbGw9InVybCgjcGFpbnQ0X2xpbmVhcl80MjFfMTgwNCkiLz4KPHBhdGggZD0iTTQ5LjQ2NjggMTguODU4NEM0OC45NTE0IDIzLjM4MTkgNjEuMTM4MSAyNy4zMDg3IDY2LjMwOTEgMjIuNjQwNUM2MS40ODM0IDMzLjE5MDcgNDcuNzk4NiAyNy42NjY3IDQ2Ljc2NjQgMjIuOTMyNUM0Ni40OTYgMjEuNzA0OCA0Ny43MDA4IDIxLjUyMDcgNDkuNDY2OCAxOC44NTg0WiIgZmlsbD0idXJsKCNwYWludDVfbGluZWFyXzQyMV8xODA0KSIvPgo8cGF0aCBkPSJNNTguNTU0IDM0LjYwMzVDNTAuMTk1MSA1MS45NTQ4IDM0LjQ1ODcgNDIuODg4OCAyNi45MTM2IDUxLjYwNTdDMzYuMTA1MyAzNy43NTcxIDQ4LjcxNDggNDUuODIyOCA1OC41NTQgMzQuNjAzNVoiIGZpbGw9InVybCgjcGFpbnQ2X2xpbmVhcl80MjFfMTgwNCkiLz4KPHBhdGggZD0iTTY2LjU3NDEgNDEuNTQ3QzY4LjcyNiA0MS43NDY0IDcxLjI5NTcgNTEuMjU1NSA2NS4xODI3IDUzLjU1OThDNjQuNzQ4NSA1My43MjM2IDY3LjMwMjggNTMuNjQ0OSA2Ni45ODI5IDUzLjg5NjJDNzQuMjU2MyA1Mi4wMDk2IDcwLjc5MTcgMzkuNzYwNyA2OC44NjQ0IDQwLjU3NzFDNjYuNzcyMiA0MS40NjMzIDY4LjY2NjQgNDAuNjU4MyA2Ni41NzQxIDQxLjU0N1oiIGZpbGw9InVybCgjcGFpbnQ3X2xpbmVhcl80MjFfMTgwNCkiLz4KPHBhdGggZD0iTTY4Ljg2NDMgNDAuNTc2MkM2Ni41ODU0IDQyLjk4NTggNzMuNzA1MiA0OS44NDkyIDc4LjcxMzcgNDguOTI3NUM3Mi4yOTYgNTIuODM3OCA2NC42MzE1IDQ1LjQ5MiA2NS42NTg2IDQxLjkzMjFDNjUuOTA2MiA0MS4wNyA2Ni43Njk1IDQxLjQ2MjMgNjguODY0MyA0MC41NzYyWiIgZmlsbD0idXJsKCNwYWludDhfbGluZWFyXzQyMV8xODA0KSIvPgo8cGF0aCBkPSJNNTcuNjk1OCA0NS4zNzY0QzU5Ljg0NzggNDUuNTczMiA2Mi45MjUyIDU0LjkxMjIgNTYuMDY3IDU4LjE1NkM1NS42NDI5IDU4LjM1NjYgNTguNDI5NyA1Ny40NjkyIDU4LjEwNzIgNTcuNzI0NEM2NS4zODA2IDU1LjgzNjUgNjEuOTE1OSA0My41ODg5IDU5Ljk4NjIgNDQuNDA1MkM1Ny44OTUyIDQ1LjI5MjcgNTkuNzkxOSA0NC40ODkgNTcuNjk1OCA0NS4zNzY0WiIgZmlsbD0idXJsKCNwYWludDlfbGluZWFyXzQyMV8xODA0KSIvPgo8cGF0aCBkPSJNNTkuOTg3NSA0NC40MDQzQzU3LjkwNDEgNDYuODg3NiA2My42MDMzIDU0LjAxMTIgNjguNTA3NyA1My4yNjZDNjEuNDk4MyA1Ny42Mzk3IDU1LjUzNjQgNDguOTc4NiA1Ni43ODE4IDQ1Ljc2MTVDNTcuMTA0MyA0NC45Mjc0IDU3Ljg5MjcgNDUuMjkxNyA1OS45ODc1IDQ0LjQwNDNaIiBmaWxsPSJ1cmwoI3BhaW50MTBfbGluZWFyXzQyMV8xODA0KSIvPgo8cGF0aCBkPSJNNTkuMjA0NCA1Ny4zMjY5QzQ3LjQyMzkgNjQuMzUwMiA0MS42MzU5IDUyLjc4MzEgMzMuNzI5IDU0Ljk5NTlDNDQuNjI4MyA1MC4zODIzIDQ4Ljk1MzggNjAuMTI3NiA1OS4yMDQ0IDU3LjMyNjlaIiBmaWxsPSJ1cmwoI3BhaW50MTFfbGluZWFyXzQyMV8xODA0KSIvPgo8cGF0aCBkPSJNMzguODg4NiAxNC42MzMyQzM4Ljg3NTkgMTIuNTc1MyAzMC4wODI4IDkuMzcyMTEgMjcuNDA3OCAxNC45NzQ4QzI3LjIxNzQgMTUuMzcwOSAyNy40OTkyIDEyLjk2MTIgMjcuMjMzOSAxMy4yNDE4QzI5LjYwOTMgNi41MDkyMSA0MC45MTc0IDEwLjc4MjYgMzkuOTkxOSAxMi41NDFDMzguOTggMTQuNDUzIDM5Ljg5NTQgMTIuNzIxMyAzOC44ODg2IDE0LjYzMzJaIiBmaWxsPSJ1cmwoI3BhaW50MTJfbGluZWFyXzQyMV8xODA0KSIvPgo8cGF0aCBkPSJNMzkuOTkxNiAxMi41NDA4QzM3LjUyNzQgMTQuNTAyMyAzMS42MDk5IDcuMjA2MDMgMzIuODg0NSAyLjUzOTA2QzI4LjY2NyA4LjI5OTE0IDM0Ljk5NzEgMTYuMTUxNSAzOC40NDY2IDE1LjQ2ODRDMzkuMjg0NSAxNS4zMDIxIDM4Ljk3OTggMTQuNDUyOCAzOS45OTE2IDEyLjU0MDhaIiBmaWxsPSJ1cmwoI3BhaW50MTNfbGluZWFyXzQyMV8xODA0KSIvPgo8cGF0aCBkPSJNMzQuNTQ0MSAyMi43MjUzQzM0LjUzMTQgMjAuNjcyNCAyNS45NDI3IDE2Ljk5ODIgMjIuMzE2OCAyMy4yMzE4QzIyLjA5MDggMjMuNjE5MSAyMy4xNTczIDIxLjA0ODIgMjIuODkyIDIxLjMzNzZDMjUuMjY0OCAxNC42MDI1IDM2LjU3NjcgMTguODc1OSAzNS42NDc0IDIwLjYzM0MzNC42MzgxIDIyLjU0NjMgMzUuNTUwOSAyMC44MTQ2IDM0LjU0NDEgMjIuNzI1M1oiIGZpbGw9InVybCgjcGFpbnQxNF9saW5lYXJfNDIxXzE4MDQpIi8+CjxwYXRoIGQ9Ik0zNS42NDcgMjAuNjM0MUMzMy4xMzA3IDIyLjQwNjQgMjYuODUxMyAxNi40MzQ0IDI3Ljk0OTUgMTEuODQ4NkMyMy4yNDgzIDE4LjEzMTggMzAuOTU0NiAyNC40NzcxIDM0LjEwMTkgMjMuNTYxOEMzNC45MjA4IDIzLjMyMTggMzQuNjQwMiAyMi41NDYxIDM1LjY0NyAyMC42MzQxWiIgZmlsbD0idXJsKCNwYWludDE1X2xpbmVhcl80MjFfMTgwNCkiLz4KPHBhdGggZD0iTTIzLjM1NTEgMjAuMzMxMUMxNS43NTU0IDMwLjkxNTUgMjYuMjMyIDM3LjMzNDUgMjMuNDk2IDQ0LjYzOTdDMjguNzQ3IDM0LjY5MzggMTkuODc2NSAyOS44MDk3IDIzLjM1NTEgMjAuMzMxMVoiIGZpbGw9InVybCgjcGFpbnQxNl9saW5lYXJfNDIxXzE4MDQpIi8+CjxwYXRoIGQ9Ik0zNS40OTM1IDM1LjU5ODhMMzYuMTUzNyAzMi4zODhMMzMuNjM4NyAzMC4yODY4TDM2Ljg5NTEgMjkuOTIyNUwzOC4xMTY1IDI2Ljg4MThMMzkuNDY4NiAyOS44NjY2TDQyLjczNjUgMzAuMDg4OEw0MC4zMTkyIDMyLjI5NjZMNDEuMTE1MiAzNS40NzQzTDM4LjI2ODggMzMuODU2OUwzNS40OTM1IDM1LjU5ODhaIiBmaWxsPSIjRTYzNURFIi8+CjxwYXRoIGQ9Ik03My4yNzg2IDMyLjk4MjdMNzMuNjg0OCAzMS4wMDZMNzIuMTM3MiAyOS43MTM2TDc0LjE0MDYgMjkuNDg4OEw3NC44OTIyIDI3LjYxNjJMNzUuNzI1IDI5LjQ1MzNMNzcuNzM4NiAyOS41OTE3TDc2LjI0OTQgMzAuOTUxNEw3Ni43NDIgMzIuOTA3OEw3NC45ODg3IDMxLjkxMjVMNzMuMjc4NiAzMi45ODI3WiIgZmlsbD0iIzNDQzNFQyIvPgo8cGF0aCBkPSJNNDQuNTA3OCAxMS4wMTA2TDQ1Ljk4MzEgOS4xOTc2Nkw0NS4wODggNy4wMzkzOEw0Ny4yNjY2IDcuODg0OTJMNDkuMDQ1MyA2LjM2NTIzTDQ4LjkxMzMgOC42OTk5OUw1MC45MDc4IDkuOTE4NzhMNDguNjQ3OSAxMC41MTY4TDQ4LjEwNTggMTIuNzkxOEw0Ni44Mzg4IDEwLjgyNzhMNDQuNTA3OCAxMS4wMTA2WiIgZmlsbD0iI0E2RTYzOSIvPgo8cGF0aCBkPSJNNDkuMjMyOSA1Mi43MDc5TDUwLjcxMDcgNTAuODk2Mkw0OS44MTU2IDQ4LjczNzlMNTEuOTk1NSA0OS41ODIyTDUzLjc3MTcgNDguMDYyNUw1My42Mzk2IDUwLjM5NzNMNTUuNjM1NCA1MS42MTczTDUzLjM3NDMgNTIuMjE1M0w1Mi44MzA5IDU0LjQ4OTFMNTEuNTY2NCA1Mi41MjUxTDQ5LjIzMjkgNTIuNzA3OVoiIGZpbGw9IiNFODFDMjciLz4KPHBhdGggZD0iTTQ0LjMzMTIgNDUuMzMyTDQ2LjI0NTggNDguODEwN0w0My40NDYzIDUxLjYwNzZMNDIuMTA2OSA0Ny45ODE2TDQ0LjMzMTIgNDUuMzMyWiIgZmlsbD0iI0E2RTYzOSIvPgo8cGF0aCBkPSJNMjkuMzA0NCAzNy40MDQzTDMxLjIxODkgNDAuODgyOUwyOC40MjIgNDMuNjgyNEwyNy4wODAxIDQwLjA1NTJMMjkuMzA0NCAzNy40MDQzWiIgZmlsbD0iIzNDQzNFQyIvPgo8cGF0aCBkPSJNNjUuMjUwMSAzNi42ODkyTDYyLjkzMDYgMzkuMjEwNkw1OS44NzYgMzcuNjkwOUw2Mi40NzIzIDM1LjU5ODZMNjUuMjUwMSAzNi42ODkyWiIgZmlsbD0iI0U4MUMyNyIvPgo8cGF0aCBkPSJNMTkuODE5MyA4LjU1NDY5TDIyLjc0MzEgMTEuNTIxN0wyMC43MTY5IDE1LjE0MzhMMTguMzMwMSAxMS44NjQ1TDE5LjgxOTMgOC41NTQ2OVoiIGZpbGw9IiNFNjM1REUiLz4KPHBhdGggZD0iTTY1LjQ4NzQgNjEuMzk0NUw2Mi40NDkzIDYyLjk3NTFMNjAuMDk0MiA2MC41MDU4TDYzLjI0NzkgNTkuNDIyOUw2NS40ODc0IDYxLjM5NDVaIiBmaWxsPSIjQTZFNjM5Ii8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfNDIxXzE4MDQiIHgxPSIyMi40MzM5IiB5MT0iNzEuNTE1NSIgeDI9IjExLjk2MDIiIHkyPSI1My42NjI2IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiNEQjc2MDAiLz4KPHN0b3Agb2Zmc2V0PSIwLjIyODQiIHN0b3AtY29sb3I9IiNFMTg2MDgiLz4KPHN0b3Agb2Zmc2V0PSIwLjY3MjIiIHN0b3AtY29sb3I9IiNGMUFGMUYiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjRkZEMjMxIi8+CjwvbGluZWFyR3JhZGllbnQ+CjxyYWRpYWxHcmFkaWVudCBpZD0icGFpbnQxX3JhZGlhbF80MjFfMTgwNCIgY3g9IjAiIGN5PSIwIiByPSIxIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSgzMC4wMzIyIDUwLjI5NSkgc2NhbGUoMTQuMDM2IDE0LjAzNikiPgo8c3RvcCBzdG9wLWNvbG9yPSIjODUzQjFCIi8+CjxzdG9wIG9mZnNldD0iMC4xODMyIiBzdG9wLWNvbG9yPSIjN0QzOTFEIi8+CjxzdG9wIG9mZnNldD0iMC40Njc5IiBzdG9wLWNvbG9yPSIjNjczMzIxIi8+CjxzdG9wIG9mZnNldD0iMC44MTY4IiBzdG9wLWNvbG9yPSIjNDMyOTI4Ii8+CjxzdG9wIG9mZnNldD0iMC44NzI3IiBzdG9wLWNvbG9yPSIjM0QyNzI5Ii8+CjwvcmFkaWFsR3JhZGllbnQ+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQyX2xpbmVhcl80MjFfMTgwNCIgeDE9IjY3LjQ5MzkiIHkxPSIyMC45OTA5IiB4Mj0iNTMuOTI1OCIgeTI9IjExLjk4MTMiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzUzREFGMiIvPgo8c3RvcCBvZmZzZXQ9IjAuMjA5MyIgc3RvcC1jb2xvcj0iIzRFRDVGMSIvPgo8c3RvcCBvZmZzZXQ9IjAuNDU2MSIgc3RvcC1jb2xvcj0iIzQwQzdFRCIvPgo8c3RvcCBvZmZzZXQ9IjAuNzIxOCIgc3RvcC1jb2xvcj0iIzI4QUZFNyIvPgo8c3RvcCBvZmZzZXQ9IjAuOTk5MiIgc3RvcC1jb2xvcj0iIzA3OEVERSIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMwNzhFREUiLz4KPC9saW5lYXJHcmFkaWVudD4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDNfbGluZWFyXzQyMV8xODA0IiB4MT0iNzEuMTQyOSIgeTE9IjE1LjUzNTYiIHgyPSI1Ny4xOTI2IiB5Mj0iNi4yNzIxNiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjMDc4RURFIi8+CjxzdG9wIG9mZnNldD0iMC4wNzUyIiBzdG9wLWNvbG9yPSIjMTE5OUUyIi8+CjxzdG9wIG9mZnNldD0iMC4zMzE5IiBzdG9wLWNvbG9yPSIjMkZCQUVGIi8+CjxzdG9wIG9mZnNldD0iMC41Nzc5IiBzdG9wLWNvbG9yPSIjNDVEMkY4Ii8+CjxzdG9wIG9mZnNldD0iMC44MDYzIiBzdG9wLWNvbG9yPSIjNTJFMEZEIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzU3RTVGRiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50NF9saW5lYXJfNDIxXzE4MDQiIHgxPSI1OS44NjI2IiB5MT0iMzIuNjQ4NiIgeDI9IjQ2LjI5NjUiIHkyPSIyMy42NDAzIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiM1M0RBRjIiLz4KPHN0b3Agb2Zmc2V0PSIwLjIwOTMiIHN0b3AtY29sb3I9IiM0RUQ1RjEiLz4KPHN0b3Agb2Zmc2V0PSIwLjQ1NjEiIHN0b3AtY29sb3I9IiM0MEM3RUQiLz4KPHN0b3Agb2Zmc2V0PSIwLjcyMTgiIHN0b3AtY29sb3I9IiMyOEFGRTciLz4KPHN0b3Agb2Zmc2V0PSIwLjk5OTIiIHN0b3AtY29sb3I9IiMwNzhFREUiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMDc4RURFIi8+CjwvbGluZWFyR3JhZGllbnQ+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQ1X2xpbmVhcl80MjFfMTgwNCIgeDE9IjYzLjAyMTgiIHkxPSIyNy44Nzg0IiB4Mj0iNDkuMTI3MyIgeTI9IjE4LjY1MiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjMDc4RURFIi8+CjxzdG9wIG9mZnNldD0iMC4wNzUyIiBzdG9wLWNvbG9yPSIjMTE5OUUyIi8+CjxzdG9wIG9mZnNldD0iMC4zMzE5IiBzdG9wLWNvbG9yPSIjMkZCQUVGIi8+CjxzdG9wIG9mZnNldD0iMC41Nzc5IiBzdG9wLWNvbG9yPSIjNDVEMkY4Ii8+CjxzdG9wIG9mZnNldD0iMC44MDYzIiBzdG9wLWNvbG9yPSIjNTJFMEZEIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzU3RTVGRiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50Nl9saW5lYXJfNDIxXzE4MDQiIHgxPSI1MC4wMTQzIiB5MT0iNDcuOTM5MiIgeDI9IjM1LjY3MzYiIHkyPSIzOC40MTY2IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiM1N0U1RkYiLz4KPHN0b3Agb2Zmc2V0PSIwLjE5MzciIHN0b3AtY29sb3I9IiM1MkUwRkQiLz4KPHN0b3Agb2Zmc2V0PSIwLjQyMjEiIHN0b3AtY29sb3I9IiM0NUQyRjgiLz4KPHN0b3Agb2Zmc2V0PSIwLjY2ODEiIHN0b3AtY29sb3I9IiMyRkJBRUYiLz4KPHN0b3Agb2Zmc2V0PSIwLjkyNDgiIHN0b3AtY29sb3I9IiMxMTk5RTIiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMDc4RURFIi8+CjwvbGluZWFyR3JhZGllbnQ+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQ3X2xpbmVhcl80MjFfMTgwNCIgeDE9IjY5Ljg1ODUiIHkxPSI1Mi43NTI2IiB4Mj0iNjUuMzM2OSIgeTI9IjQyLjA3MDQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agb2Zmc2V0PSIwLjIzMDMiIHN0b3AtY29sb3I9IiNBQTVCRUYiLz4KPHN0b3Agb2Zmc2V0PSIwLjQ5MDYiIHN0b3AtY29sb3I9IiNBODU4RUUiLz4KPHN0b3Agb2Zmc2V0PSIwLjY1OTciIHN0b3AtY29sb3I9IiNBMjUwRTkiLz4KPHN0b3Agb2Zmc2V0PSIwLjgwMjkiIHN0b3AtY29sb3I9IiM5NjQxRTEiLz4KPHN0b3Agb2Zmc2V0PSIwLjkzMDgiIHN0b3AtY29sb3I9IiM4NzJDRDciLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjN0MxRENGIi8+CjwvbGluZWFyR3JhZGllbnQ+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQ4X2xpbmVhcl80MjFfMTgwNCIgeDE9Ijc0LjE2OTIiIHkxPSI1MC45NDM3IiB4Mj0iNjkuNTIwNSIgeTI9IjM5Ljk2MTIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzdDMURDRiIvPgo8c3RvcCBvZmZzZXQ9IjAuMDY5MiIgc3RvcC1jb2xvcj0iIzg3MkNENyIvPgo8c3RvcCBvZmZzZXQ9IjAuMTk3MSIgc3RvcC1jb2xvcj0iIzk2NDFFMSIvPgo8c3RvcCBvZmZzZXQ9IjAuMzQwMyIgc3RvcC1jb2xvcj0iI0EyNTBFOSIvPgo8c3RvcCBvZmZzZXQ9IjAuNTA5NCIgc3RvcC1jb2xvcj0iI0E4NThFRSIvPgo8c3RvcCBvZmZzZXQ9IjAuNzY5NyIgc3RvcC1jb2xvcj0iI0FBNUJFRiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50OV9saW5lYXJfNDIxXzE4MDQiIHgxPSI2MC43NDgxIiB5MT0iNTYuNjgxOCIgeDI9IjU2LjIyNjYiIHkyPSI0NS45OTk2IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIG9mZnNldD0iMC4yMzAzIiBzdG9wLWNvbG9yPSIjQUE1QkVGIi8+CjxzdG9wIG9mZnNldD0iMC40OTA2IiBzdG9wLWNvbG9yPSIjQTg1OEVFIi8+CjxzdG9wIG9mZnNldD0iMC42NTk3IiBzdG9wLWNvbG9yPSIjQTI1MEU5Ii8+CjxzdG9wIG9mZnNldD0iMC44MDI5IiBzdG9wLWNvbG9yPSIjOTY0MUUxIi8+CjxzdG9wIG9mZnNldD0iMC45MzA4IiBzdG9wLWNvbG9yPSIjODcyQ0Q3Ii8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzdDMURDRiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MTBfbGluZWFyXzQyMV8xODA0IiB4MT0iNjQuNDk3MiIgeTE9IjU1LjA4NTMiIHgyPSI1OS44NjYzIiB5Mj0iNDQuMTQ0OSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjN0MxRENGIi8+CjxzdG9wIG9mZnNldD0iMC4wNjkyIiBzdG9wLWNvbG9yPSIjODcyQ0Q3Ii8+CjxzdG9wIG9mZnNldD0iMC4xOTcxIiBzdG9wLWNvbG9yPSIjOTY0MUUxIi8+CjxzdG9wIG9mZnNldD0iMC4zNDAzIiBzdG9wLWNvbG9yPSIjQTI1MEU5Ii8+CjxzdG9wIG9mZnNldD0iMC41MDk0IiBzdG9wLWNvbG9yPSIjQTg1OEVFIi8+CjxzdG9wIG9mZnNldD0iMC43Njk3IiBzdG9wLWNvbG9yPSIjQUE1QkVGIi8+CjwvbGluZWFyR3JhZGllbnQ+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQxMV9saW5lYXJfNDIxXzE4MDQiIHgxPSI0OC44OTIiIHkxPSI2MS44OTM2IiB4Mj0iNDQuMTExOCIgeTI9IjUwLjYwMDUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agb2Zmc2V0PSIwLjIzMDMiIHN0b3AtY29sb3I9IiNBQTVCRUYiLz4KPHN0b3Agb2Zmc2V0PSIwLjQ5MDYiIHN0b3AtY29sb3I9IiNBODU4RUUiLz4KPHN0b3Agb2Zmc2V0PSIwLjY1OTciIHN0b3AtY29sb3I9IiNBMjUwRTkiLz4KPHN0b3Agb2Zmc2V0PSIwLjgwMjkiIHN0b3AtY29sb3I9IiM5NjQxRTEiLz4KPHN0b3Agb2Zmc2V0PSIwLjkzMDgiIHN0b3AtY29sb3I9IiM4NzJDRDciLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjN0MxRENGIi8+CjwvbGluZWFyR3JhZGllbnQ+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQxMl9saW5lYXJfNDIxXzE4MDQiIHgxPSIyOC41NDg3IiB5MT0iMTAuNjE0MyIgeDI9IjM4LjI5NDQiIHkyPSIxNS43NiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjRkYwMDBFIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0I4MDAwMCIvPgo8L2xpbmVhckdyYWRpZW50Pgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MTNfbGluZWFyXzQyMV8xODA0IiB4MT0iMzAuNjA3NiIgeTE9IjYuNjc4MzUiIHgyPSI0MC42Mjc0IiB5Mj0iMTEuOTY4NyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjQ0YwMDAwIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0ZGMDAwRSIvPgo8L2xpbmVhckdyYWRpZW50Pgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MTRfbGluZWFyXzQyMV8xODA0IiB4MT0iMjQuMDkzOSIgeTE9IjE4LjkyNDIiIHgyPSIzMy44MzYyIiB5Mj0iMjQuMDY4MSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjRkYwMDBFIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0I4MDAwMCIvPgo8L2xpbmVhckdyYWRpZW50Pgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MTVfbGluZWFyXzQyMV8xODA0IiB4MT0iMjUuOTAzOSIgeTE9IjE1LjQ5OTEiIHgyPSIzNS44ODQyIiB5Mj0iMjAuNzY4NiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjQ0YwMDAwIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0ZGMDAwRSIvPgo8L2xpbmVhckdyYWRpZW50Pgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MTZfbGluZWFyXzQyMV8xODA0IiB4MT0iMTguMTk3NCIgeTE9IjI5LjcyMzkiIHgyPSIyOC41IiB5Mj0iMzUuMTYzNiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjQ0YwMDAwIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0ZGMDAwRSIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo=");
}
/* =====================================================================
1) THE PILL — "✨ BIG UPGRADE COMING! →"
===================================================================== */
.ec-upgrade-pill {
position: relative;
display: inline-flex;
align-items: center;
gap: 9px;
background: linear-gradient(135deg, #5cf03a 0%, #30D90A 100%);
color: var(--ecu-navy);
font-family: 'Inter', system-ui, -apple-system, sans-serif;
font-weight: 800;
font-size: 13px;
letter-spacing: 0.4px;
padding: 11px 18px;
border: none;
border-radius: 999px;
cursor: pointer;
white-space: nowrap;
overflow: hidden;
isolation: isolate;
box-shadow: 0 4px 18px rgba(48, 217, 10, 0.40);
animation: ecu-breathe 4.5s ease-in-out infinite;
transition: transform 0.18s cubic-bezier(0.34,1.56,0.64,1), box-shadow 0.18s ease;
}
.ec-upgrade-pill:hover {
transform: translateY(-2px);
box-shadow: 0 10px 28px rgba(48, 217, 10, 0.55);
}
.ec-upgrade-pill:active { transform: translateY(0) scale(0.98); }
.ec-upgrade-pill:focus-visible {
outline: 3px solid rgba(48, 217, 10, 0.5);
outline-offset: 3px;
}
.ec-upgrade-pill .ecu-spark {
position: relative;
z-index: 2;
display: inline-block;
width: 22px;
height: 22px;
background: var(--ecu-party) center / contain no-repeat;
}
.ec-upgrade-pill .ecu-label { position: relative; z-index: 2; }
.ec-upgrade-pill .ecu-arrow {
position: relative;
z-index: 2;
display: inline-flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
margin-left: 2px;
border-radius: 50%;
background: var(--ecu-navy);
color: #fff;
font-size: 12px;
font-weight: 900;
animation: ecu-nudge 4.5s ease-in-out infinite;
transition: transform 0.2s ease;
}
.ec-upgrade-pill:hover .ecu-arrow { transform: translateX(3px); }
/* shine sweep — soft highlight glides across, then waits */
.ec-upgrade-pill::after {
content: "";
position: absolute;
top: 0;
left: -150%;
width: 70%;
height: 100%;
z-index: 1;
background: linear-gradient(100deg, transparent 0%, rgba(255,255,255,0.65) 50%, transparent 100%);
transform: skewX(-22deg);
animation: ecu-shine 4.5s ease-in-out infinite;
pointer-events: none;
}
@keyframes ecu-shine {
0% { left: -150%; }
22% { left: 150%; }
100% { left: 150%; }
}
@keyframes ecu-breathe {
0%, 100% { box-shadow: 0 4px 18px rgba(48,217,10,0.38); }
50% { box-shadow: 0 7px 24px rgba(48,217,10,0.55); }
}
@keyframes ecu-nudge {
0%, 84%, 100% { transform: translateX(0); }
90% { transform: translateX(3px); }
95% { transform: translateX(0); }
}
@keyframes ecu-twinkle {
0%, 100% { opacity: 1; transform: scale(1) rotate(0deg); }
50% { opacity: 0.6; transform: scale(0.85) rotate(-12deg); }
}
/* Compact size for the extension popup header (less vertical room) */
.ec-upgrade-pill--compact {
font-size: 11.5px;
padding: 8px 13px;
gap: 7px;
}
.ec-upgrade-pill--compact .ecu-arrow { width: 18px; height: 18px; font-size: 11px; }
.ec-upgrade-pill--compact .ecu-spark { width: 20px; height: 20px; }
@media (prefers-reduced-motion: reduce) {
.ec-upgrade-pill,
.ec-upgrade-pill::after,
.ec-upgrade-pill .ecu-arrow,
.ec-upgrade-pill .ecu-spark { animation: none !important; }
}
<div class="ec-modal-backdrop" id="ecUpgradeModal" hidden
role="dialog" aria-modal="true" aria-labelledby="ecBetaInviteTitle">
<div class="ec-modal" id="ecUpgradeCard">
<button class="ec-modal__x" data-ec-close aria-label="Close">×</button>
<div class="ec-modal__icon" aria-hidden="true"></div>
<span class="ec-modal__pill">EARLY ACCESS</span>
<h2 id="ecBetaInviteTitle">The NEW EmojiCopy!</h2>
<ul>
<li>Build your own lists or browse our collections</li>
<li>All-new search, way faster and more accurate</li>
<li>An action bar to stack and copy multiple emoji at once</li>
</ul>
<div class="ec-modal__perk">
<span class="perk-ico" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2 L14.5 8.5 L21.5 9 L16 13.5 L17.7 20.5 L12 16.8 L6.3 20.5 L8 13.5 L2.5 9 L9.5 8.5 Z" fill="#fff"/>
</svg>
</span>
<span class="perk-text"><b>Get 50% OFF Pro — FOR LIFE.</b>
First 500 annual Pro memberships lock in the founding price.</span>
</div>
<a href="/beta-signup" class="ec-modal__cta" data-ec-join>Enter Here</a>
<div class="ec-modal__footer">
<svg viewBox="0 0 177 31" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="EmojiCopy">
<g clip-path="url(#ecLogoClip)">
<path d="M40.5999 3.72449H53.7367V6.91999H44.2052V11.6995H52.1444V14.8675H44.2052V19.9797H53.9319V23.1752H40.5999V3.72449Z" fill="#1a1a2e"/>
<path d="M67.5307 10.0246C67.5307 10.0246 68.9607 7.89062 72.4669 7.89062C74.3892 7.87412 76.0804 8.71012 77.2189 9.70837C78.1237 10.5004 78.7892 11.7984 78.8717 12.9946C78.9817 14.5731 78.9569 23.1696 78.9569 23.1696H75.5469V15.3074C75.5469 12.6949 74.4084 11.3061 72.5357 11.3061C70.8582 11.3061 69.3979 12.4446 69.3979 14.8894V23.1696H65.6662V14.8894C65.6662 12.4446 64.2059 11.3061 62.5284 11.3061C60.6557 11.3061 59.5172 12.6949 59.5172 15.3074V23.1696H56.1072C56.1072 23.1696 56.0824 14.5731 56.1924 12.9946C56.2749 11.7984 56.9404 10.5004 57.8452 9.70837C58.9864 8.71012 60.6777 7.87412 62.5972 7.89062C66.1034 7.89062 67.5334 10.0246 67.5334 10.0246" fill="#1a1a2e"/>
<path d="M80.8242 15.8079C80.8242 11.3611 84.0939 8.22339 88.3977 8.22339C92.7014 8.22339 95.9739 11.3639 95.9739 15.8079C95.9739 20.2519 92.7042 23.3924 88.3977 23.3924C84.0912 23.3924 80.8242 20.2519 80.8242 15.8079ZM88.3977 20.3921C90.8012 20.3921 92.5062 18.5854 92.5062 15.8079C92.5062 13.0304 90.8012 11.2236 88.3977 11.2236C85.9942 11.2236 84.2892 13.0304 84.2892 15.8079C84.2892 18.5854 85.9942 20.3921 88.3977 20.3921Z" fill="#1a1a2e"/>
<path d="M94.9426 25.9775H95.9491C97.3736 25.9775 97.9071 25.477 97.9071 24.0332V8.44624H101.317V24.5337C101.317 27.3662 99.8349 28.8402 96.9556 28.8402H94.9426V25.9775ZM99.6094 2.00024C100.839 2.00024 101.875 2.94624 101.875 4.19474C101.875 5.44324 100.841 6.36174 99.6094 6.36174C98.3774 6.36174 97.3461 5.44599 97.3461 4.19474C97.3461 2.94349 98.3801 2.00024 99.6094 2.00024Z" fill="#1a1a2e"/>
<path d="M105.984 2.00024C107.213 2.00024 108.247 2.94624 108.247 4.19474C108.247 5.44324 107.213 6.36174 105.984 6.36174C104.755 6.36174 103.721 5.44599 103.721 4.19474C103.721 2.94349 104.755 2.00024 105.984 2.00024ZM104.279 8.44624H107.689V23.1725H104.279V8.44624Z" fill="#1a1a2e"/>
<path d="M109.757 13.476C109.757 7.55796 114.033 3.50171 119.569 3.50171C124.376 3.50171 128.207 6.61196 128.57 11.2815H124.937C124.406 8.33621 122.28 6.77971 119.569 6.77971C116.074 6.77971 113.475 9.39221 113.475 13.4485C113.475 17.5047 116.186 20.1172 119.569 20.1172C122.393 20.1172 124.516 18.4232 124.992 15.6155H128.597C128.207 20.2272 124.461 23.3952 119.514 23.3952C113.923 23.3952 109.76 19.339 109.76 13.476H109.757Z" fill="#1a1a2e"/>
<path d="M130.057 15.8079C130.057 11.3611 133.327 8.22339 137.631 8.22339C141.935 8.22339 145.207 11.3639 145.207 15.8079C145.207 20.2519 141.937 23.3924 137.631 23.3924C133.324 23.3924 130.057 20.2519 130.057 15.8079ZM137.631 20.3921C140.034 20.3921 141.739 18.5854 141.739 15.8079C141.739 13.0304 140.034 11.2236 137.631 11.2236C135.227 11.2236 133.522 13.0304 133.522 15.8079C133.522 18.5854 135.227 20.3921 137.631 20.3921Z" fill="#1a1a2e"/>
<path d="M158.11 8.72948C160.316 10.011 161.99 12.5795 161.99 15.808C161.99 20.3372 158.916 23.3925 155.115 23.3925C153.075 23.3925 151.315 22.5317 150.336 21.1402V28.8375H146.926V16.0637C146.926 14.972 146.882 13.7922 147.204 12.7417C147.465 11.8865 147.91 11.0917 148.493 10.4125C149.681 9.02923 151.4 8.15473 153.201 7.87698C154.799 7.63223 156.493 7.78348 158.11 8.72398V8.72548ZM154.389 20.3922C156.793 20.3922 158.525 18.5855 158.525 15.808C158.525 13.0305 156.793 11.2237 154.389 11.2237C151.986 11.2237 150.253 13.0305 150.253 15.808C150.253 18.5855 151.986 20.3922 154.389 20.3922Z" fill="#1a1a2e"/>
<path d="M163.22 25.9774H164.842C166.239 25.9774 166.855 25.5319 167.331 24.2559L167.721 23.2549L161.795 8.44617H165.455L169.481 19.2262L173.395 8.44617H177L170.348 25.5622C169.426 27.9519 167.972 28.9502 165.4 28.9502H163.22V25.9774Z" fill="#1a1a2e"/>
</g>
<path d="M15.4014 0C3.58082 0 0 3.14329 0 13.5082C0 20.232 1.50438 23.9143 5.78927 25.6743C6.63084 26.0181 7.05713 26.9531 6.79861 27.8166L6.17705 29.8819C5.99554 30.4786 6.61984 31.0011 7.18639 30.7234L14.0263 27.3216C14.4305 27.1181 14.8788 27.0163 15.3326 27.0163H15.3986C27.2192 27.0163 30.8 23.873 30.8 13.5109C30.8 3.14879 27.2219 0 15.4014 0ZM23.5284 17.405C22.5053 18.868 19.8458 20.815 15.4014 20.815C10.957 20.815 8.30024 18.868 7.2744 17.405C6.80961 16.7395 6.77386 15.8457 7.40916 15.3397C7.99771 14.8722 8.9053 15.0289 9.32058 15.4029C9.79087 15.8292 10.2337 16.2389 10.847 16.6377C11.8673 17.3005 13.3524 17.8945 15.4041 17.8945C17.4558 17.8945 18.9409 17.3005 19.9613 16.6377C20.5718 16.2389 21.0174 15.8319 21.4877 15.4029C21.9002 15.0289 22.8078 14.8694 23.3991 15.3397C24.0344 15.8484 23.9959 16.7395 23.5339 17.405H23.5284Z" fill="#30D90A"/>
<defs>
<clipPath id="ecLogoClip">
<rect width="136.4" height="26.95" fill="white" transform="translate(40.6 2)"/>
</clipPath>
</defs>
</svg>
</div>
</div>
</div>
:root {
--ecu-green: #30D90A; /* EmojiCopy logo green */
--ecu-green-deep: #1f9c06; /* darker — for text / hover / contrast on white */
--ecu-green-soft: #e4fbdb; /* light tint — for backgrounds */
--ecu-navy: #1a1a2e;
/* JoyPixels party-popper (🎉) artwork as a data URI.
Swap for your own asset path/version if preferred. */
--ecu-party: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODIiIGhlaWdodD0iODIiIHZpZXdCb3g9IjAgMCA4MiA4MiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTE2LjA3NzkgMzcuNDgwNUMxNi4wNzc5IDM3LjQ4MDUgMTYuMDc3OSAzNy40ODA1IDIuNTgwOTYgNzcuNzAyQzIuMzgwMzcgNzguMzAyNSAyLjkzMjY0IDc4Ljg4NzggMy41NDMzIDc4LjY2NjlDNDIuMjE1OSA2NC42NzQ4IDQyLjIxNTkgNjQuNjc0OCA0Mi4yMTU5IDY0LjY3NDhMMTYuMDc3OSAzNy40ODA1WiIgZmlsbD0idXJsKCNwYWludDBfbGluZWFyXzQyMV8xODA0KSIvPgo8cGF0aCBkPSJNMzQuODAxNyA0NS40MzY5QzQyLjE4NTYgNTIuOTU3OSA0NS45OTY5IDYxLjI2OTggNDMuMzE2OCA2NC4wMDA3QzQwLjYzNDIgNjYuNzMxNSAzMi40NjgyIDYyLjg1MTcgMjUuMDgxOCA1NS4zMzA3QzE3LjY5OCA0Ny44MTEgMTMuODg2NyAzOS40OTkxIDE2LjU2OTMgMzYuNzY4MkMxOS4yNTE5IDM0LjAzNjEgMjcuNDE1MyAzNy45MTg0IDM0LjgwMTcgNDUuNDM2OVoiIGZpbGw9IiNFODhBMzAiLz4KPHBhdGggb3BhY2l0eT0iMC4zIiBkPSJNMTMuMjQ2OSA2MS43ODE1TDEyLjU3MDIgNTcuODEyOEw5LjU5MTggNTYuODA5OEw5Ljg5MTQyIDU1LjkxODZMMTIuMzIxNCA1NC42NjQyTDEyLjM2NTggNTAuNjM5NkwxNS4yNDI3IDUzLjQ1M0wxOS4wNzY4IDUyLjI0OTVMMTcuMjk1NiA1NS44NTM4TDE5LjYyNjUgNTkuMTM0NEwxNS42NDY0IDU4LjU1MTdMMTMuMjQ2OSA2MS43ODE1WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggb3BhY2l0eT0iMC4zIiBkPSJNMTkuNjk2MiA2OS43NjEzTDE2LjExNDcgNzEuNTkwN0wxOS42NzM0IDcyLjgzMjRMMjQuNjk5NiA3MS4wMTE4TDI2LjQ3NyA2Ny40MTg5TDIyLjYyOSA2OC41ODE4TDE5Ljc4MjYgNjUuNzM5M0wxOS42OTYyIDY5Ljc2MTNaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBvcGFjaXR5PSIwLjMiIGQ9Ik0zLjAyMjk1IDc2LjM4NTZMNS40NzcwNCA3My42NzI1TDguOTc4NTQgNzQuNTUzNkw3LjE5NjA1IDcxLjQxMjZMOS4xMTgyIDY4LjM1NTVMNS40NDUzIDY5LjE2NTVMMy4wMjI5NSA3Ni4zODU2WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTM0LjY2ODMgNDUuNTcxOUM0MS45MTEyIDUyLjk0MzEgNDUuNzAyMiA2MS4wMzI4IDQzLjE0NjYgNjMuNjQxOEM0MC41ODQ1IDY2LjI0NyAzMi42MzgyIDYyLjM4NzUgMjUuMzk1MyA1NS4wMTVDMTguMTU0OSA0Ny42NDg5IDE0LjM2MTQgMzkuNTU5MiAxNi45MjIxIDM2Ljk1MTRDMTkuNDgwMyAzNC4zNDEyIDI3LjQyOTIgMzguMjAzMyAzNC42NjgzIDQ1LjU3MTlaIiBmaWxsPSJ1cmwoI3BhaW50MV9yYWRpYWxfNDIxXzE4MDQpIi8+CjxwYXRoIGQ9Ik01NC45Njg4IDEwLjQxMjJDNTcuNjQ2MyA4Ljk3MzgyIDY4LjAxNjIgMTguMTIyNCA2Mi42MzgzIDI1LjU1N0M2Mi4yNTg3IDI2LjA4NTIgNjUuMTkwMSAyNC4wMTQ1IDY1LjAwODYgMjQuNTU3OUM3Mi4wNjg3IDE2LjcxMTkgNTguNTI3NCA1LjA0OTU1IDU2Ljg5OTggNy40OTg1N0M1NS4xMzI1IDEwLjE2MDkgNTYuNzM0NyA3Ljc0OTk0IDU0Ljk2ODggMTAuNDEyMloiIGZpbGw9InVybCgjcGFpbnQyX2xpbmVhcl80MjFfMTgwNCkiLz4KPHBhdGggZD0iTTU2Ljg5NzYgNy40OTUxMkM1Ni4wOTY1IDEyLjA4NzIgNjkuNzQ3IDE0LjYwODYgNzQuOTAyOCA5LjY1MjEzQzcwLjQxMjMgMTkuMjAwNiA1NS43NDk5IDE2LjUzNDUgNTQuMTkyMSAxMS41NzA1QzUzLjgxODkgMTAuMzY1NiA1NS4xMzI5IDEwLjE1ODcgNTYuODk3NiA3LjQ5NTEyWiIgZmlsbD0idXJsKCNwYWludDNfbGluZWFyXzQyMV8xODA0KSIvPgo8cGF0aCBkPSJNNDcuNTM2NiAyMS43NzE3QzUwLjIwOTEgMjAuMzM3IDYxLjA0NjIgMjguODg2NCA1NS41MjEgMzguMDAzMkM1NS4xODA3IDM4LjU2NjkgNTcuNzYwNSAzNS4zNjYzIDU3LjU3NjQgMzUuOTE2QzY0LjYzNCAyOC4wNjg4IDUxLjA5NTIgMTYuNDA5IDQ5LjQ2NzYgMTguODU2N0M0Ny43MDA0IDIxLjUyMDMgNDkuMzA1MSAxOS4xMTA2IDQ3LjUzNjYgMjEuNzcxN1oiIGZpbGw9InVybCgjcGFpbnQ0X2xpbmVhcl80MjFfMTgwNCkiLz4KPHBhdGggZD0iTTQ5LjQ2NjggMTguODU4NEM0OC45NTE0IDIzLjM4MTkgNjEuMTM4MSAyNy4zMDg3IDY2LjMwOTEgMjIuNjQwNUM2MS40ODM0IDMzLjE5MDcgNDcuNzk4NiAyNy42NjY3IDQ2Ljc2NjQgMjIuOTMyNUM0Ni40OTYgMjEuNzA0OCA0Ny43MDA4IDIxLjUyMDcgNDkuNDY2OCAxOC44NTg0WiIgZmlsbD0idXJsKCNwYWludDVfbGluZWFyXzQyMV8xODA0KSIvPgo8cGF0aCBkPSJNNTguNTU0IDM0LjYwMzVDNTAuMTk1MSA1MS45NTQ4IDM0LjQ1ODcgNDIuODg4OCAyNi45MTM2IDUxLjYwNTdDMzYuMTA1MyAzNy43NTcxIDQ4LjcxNDggNDUuODIyOCA1OC41NTQgMzQuNjAzNVoiIGZpbGw9InVybCgjcGFpbnQ2X2xpbmVhcl80MjFfMTgwNCkiLz4KPHBhdGggZD0iTTY2LjU3NDEgNDEuNTQ3QzY4LjcyNiA0MS43NDY0IDcxLjI5NTcgNTEuMjU1NSA2NS4xODI3IDUzLjU1OThDNjQuNzQ4NSA1My43MjM2IDY3LjMwMjggNTMuNjQ0OSA2Ni45ODI5IDUzLjg5NjJDNzQuMjU2MyA1Mi4wMDk2IDcwLjc5MTcgMzkuNzYwNyA2OC44NjQ0IDQwLjU3NzFDNjYuNzcyMiA0MS40NjMzIDY4LjY2NjQgNDAuNjU4MyA2Ni41NzQxIDQxLjU0N1oiIGZpbGw9InVybCgjcGFpbnQ3X2xpbmVhcl80MjFfMTgwNCkiLz4KPHBhdGggZD0iTTY4Ljg2NDMgNDAuNTc2MkM2Ni41ODU0IDQyLjk4NTggNzMuNzA1MiA0OS44NDkyIDc4LjcxMzcgNDguOTI3NUM3Mi4yOTYgNTIuODM3OCA2NC42MzE1IDQ1LjQ5MiA2NS42NTg2IDQxLjkzMjFDNjUuOTA2MiA0MS4wNyA2Ni43Njk1IDQxLjQ2MjMgNjguODY0MyA0MC41NzYyWiIgZmlsbD0idXJsKCNwYWludDhfbGluZWFyXzQyMV8xODA0KSIvPgo8cGF0aCBkPSJNNTcuNjk1OCA0NS4zNzY0QzU5Ljg0NzggNDUuNTczMiA2Mi45MjUyIDU0LjkxMjIgNTYuMDY3IDU4LjE1NkM1NS42NDI5IDU4LjM1NjYgNTguNDI5NyA1Ny40NjkyIDU4LjEwNzIgNTcuNzI0NEM2NS4zODA2IDU1LjgzNjUgNjEuOTE1OSA0My41ODg5IDU5Ljk4NjIgNDQuNDA1MkM1Ny44OTUyIDQ1LjI5MjcgNTkuNzkxOSA0NC40ODkgNTcuNjk1OCA0NS4zNzY0WiIgZmlsbD0idXJsKCNwYWludDlfbGluZWFyXzQyMV8xODA0KSIvPgo8cGF0aCBkPSJNNTkuOTg3NSA0NC40MDQzQzU3LjkwNDEgNDYuODg3NiA2My42MDMzIDU0LjAxMTIgNjguNTA3NyA1My4yNjZDNjEuNDk4MyA1Ny42Mzk3IDU1LjUzNjQgNDguOTc4NiA1Ni43ODE4IDQ1Ljc2MTVDNTcuMTA0MyA0NC45Mjc0IDU3Ljg5MjcgNDUuMjkxNyA1OS45ODc1IDQ0LjQwNDNaIiBmaWxsPSJ1cmwoI3BhaW50MTBfbGluZWFyXzQyMV8xODA0KSIvPgo8cGF0aCBkPSJNNTkuMjA0NCA1Ny4zMjY5QzQ3LjQyMzkgNjQuMzUwMiA0MS42MzU5IDUyLjc4MzEgMzMuNzI5IDU0Ljk5NTlDNDQuNjI4MyA1MC4zODIzIDQ4Ljk1MzggNjAuMTI3NiA1OS4yMDQ0IDU3LjMyNjlaIiBmaWxsPSJ1cmwoI3BhaW50MTFfbGluZWFyXzQyMV8xODA0KSIvPgo8cGF0aCBkPSJNMzguODg4NiAxNC42MzMyQzM4Ljg3NTkgMTIuNTc1MyAzMC4wODI4IDkuMzcyMTEgMjcuNDA3OCAxNC45NzQ4QzI3LjIxNzQgMTUuMzcwOSAyNy40OTkyIDEyLjk2MTIgMjcuMjMzOSAxMy4yNDE4QzI5LjYwOTMgNi41MDkyMSA0MC45MTc0IDEwLjc4MjYgMzkuOTkxOSAxMi41NDFDMzguOTggMTQuNDUzIDM5Ljg5NTQgMTIuNzIxMyAzOC44ODg2IDE0LjYzMzJaIiBmaWxsPSJ1cmwoI3BhaW50MTJfbGluZWFyXzQyMV8xODA0KSIvPgo8cGF0aCBkPSJNMzkuOTkxNiAxMi41NDA4QzM3LjUyNzQgMTQuNTAyMyAzMS42MDk5IDcuMjA2MDMgMzIuODg0NSAyLjUzOTA2QzI4LjY2NyA4LjI5OTE0IDM0Ljk5NzEgMTYuMTUxNSAzOC40NDY2IDE1LjQ2ODRDMzkuMjg0NSAxNS4zMDIxIDM4Ljk3OTggMTQuNDUyOCAzOS45OTE2IDEyLjU0MDhaIiBmaWxsPSJ1cmwoI3BhaW50MTNfbGluZWFyXzQyMV8xODA0KSIvPgo8cGF0aCBkPSJNMzQuNTQ0MSAyMi43MjUzQzM0LjUzMTQgMjAuNjcyNCAyNS45NDI3IDE2Ljk5ODIgMjIuMzE2OCAyMy4yMzE4QzIyLjA5MDggMjMuNjE5MSAyMy4xNTczIDIxLjA0ODIgMjIuODkyIDIxLjMzNzZDMjUuMjY0OCAxNC42MDI1IDM2LjU3NjcgMTguODc1OSAzNS42NDc0IDIwLjYzM0MzNC42MzgxIDIyLjU0NjMgMzUuNTUwOSAyMC44MTQ2IDM0LjU0NDEgMjIuNzI1M1oiIGZpbGw9InVybCgjcGFpbnQxNF9saW5lYXJfNDIxXzE4MDQpIi8+CjxwYXRoIGQ9Ik0zNS42NDcgMjAuNjM0MUMzMy4xMzA3IDIyLjQwNjQgMjYuODUxMyAxNi40MzQ0IDI3Ljk0OTUgMTEuODQ4NkMyMy4yNDgzIDE4LjEzMTggMzAuOTU0NiAyNC40NzcxIDM0LjEwMTkgMjMuNTYxOEMzNC45MjA4IDIzLjMyMTggMzQuNjQwMiAyMi41NDYxIDM1LjY0NyAyMC42MzQxWiIgZmlsbD0idXJsKCNwYWludDE1X2xpbmVhcl80MjFfMTgwNCkiLz4KPHBhdGggZD0iTTIzLjM1NTEgMjAuMzMxMUMxNS43NTU0IDMwLjkxNTUgMjYuMjMyIDM3LjMzNDUgMjMuNDk2IDQ0LjYzOTdDMjguNzQ3IDM0LjY5MzggMTkuODc2NSAyOS44MDk3IDIzLjM1NTEgMjAuMzMxMVoiIGZpbGw9InVybCgjcGFpbnQxNl9saW5lYXJfNDIxXzE4MDQpIi8+CjxwYXRoIGQ9Ik0zNS40OTM1IDM1LjU5ODhMMzYuMTUzNyAzMi4zODhMMzMuNjM4NyAzMC4yODY4TDM2Ljg5NTEgMjkuOTIyNUwzOC4xMTY1IDI2Ljg4MThMMzkuNDY4NiAyOS44NjY2TDQyLjczNjUgMzAuMDg4OEw0MC4zMTkyIDMyLjI5NjZMNDEuMTE1MiAzNS40NzQzTDM4LjI2ODggMzMuODU2OUwzNS40OTM1IDM1LjU5ODhaIiBmaWxsPSIjRTYzNURFIi8+CjxwYXRoIGQ9Ik03My4yNzg2IDMyLjk4MjdMNzMuNjg0OCAzMS4wMDZMNzIuMTM3MiAyOS43MTM2TDc0LjE0MDYgMjkuNDg4OEw3NC44OTIyIDI3LjYxNjJMNzUuNzI1IDI5LjQ1MzNMNzcuNzM4NiAyOS41OTE3TDc2LjI0OTQgMzAuOTUxNEw3Ni43NDIgMzIuOTA3OEw3NC45ODg3IDMxLjkxMjVMNzMuMjc4NiAzMi45ODI3WiIgZmlsbD0iIzNDQzNFQyIvPgo8cGF0aCBkPSJNNDQuNTA3OCAxMS4wMTA2TDQ1Ljk4MzEgOS4xOTc2Nkw0NS4wODggNy4wMzkzOEw0Ny4yNjY2IDcuODg0OTJMNDkuMDQ1MyA2LjM2NTIzTDQ4LjkxMzMgOC42OTk5OUw1MC45MDc4IDkuOTE4NzhMNDguNjQ3OSAxMC41MTY4TDQ4LjEwNTggMTIuNzkxOEw0Ni44Mzg4IDEwLjgyNzhMNDQuNTA3OCAxMS4wMTA2WiIgZmlsbD0iI0E2RTYzOSIvPgo8cGF0aCBkPSJNNDkuMjMyOSA1Mi43MDc5TDUwLjcxMDcgNTAuODk2Mkw0OS44MTU2IDQ4LjczNzlMNTEuOTk1NSA0OS41ODIyTDUzLjc3MTcgNDguMDYyNUw1My42Mzk2IDUwLjM5NzNMNTUuNjM1NCA1MS42MTczTDUzLjM3NDMgNTIuMjE1M0w1Mi44MzA5IDU0LjQ4OTFMNTEuNTY2NCA1Mi41MjUxTDQ5LjIzMjkgNTIuNzA3OVoiIGZpbGw9IiNFODFDMjciLz4KPHBhdGggZD0iTTQ0LjMzMTIgNDUuMzMyTDQ2LjI0NTggNDguODEwN0w0My40NDYzIDUxLjYwNzZMNDIuMTA2OSA0Ny45ODE2TDQ0LjMzMTIgNDUuMzMyWiIgZmlsbD0iI0E2RTYzOSIvPgo8cGF0aCBkPSJNMjkuMzA0NCAzNy40MDQzTDMxLjIxODkgNDAuODgyOUwyOC40MjIgNDMuNjgyNEwyNy4wODAxIDQwLjA1NTJMMjkuMzA0NCAzNy40MDQzWiIgZmlsbD0iIzNDQzNFQyIvPgo8cGF0aCBkPSJNNjUuMjUwMSAzNi42ODkyTDYyLjkzMDYgMzkuMjEwNkw1OS44NzYgMzcuNjkwOUw2Mi40NzIzIDM1LjU5ODZMNjUuMjUwMSAzNi42ODkyWiIgZmlsbD0iI0U4MUMyNyIvPgo8cGF0aCBkPSJNMTkuODE5MyA4LjU1NDY5TDIyLjc0MzEgMTEuNTIxN0wyMC43MTY5IDE1LjE0MzhMMTguMzMwMSAxMS44NjQ1TDE5LjgxOTMgOC41NTQ2OVoiIGZpbGw9IiNFNjM1REUiLz4KPHBhdGggZD0iTTY1LjQ4NzQgNjEuMzk0NUw2Mi40NDkzIDYyLjk3NTFMNjAuMDk0MiA2MC41MDU4TDYzLjI0NzkgNTkuNDIyOUw2NS40ODc0IDYxLjM5NDVaIiBmaWxsPSIjQTZFNjM5Ii8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfNDIxXzE4MDQiIHgxPSIyMi40MzM5IiB5MT0iNzEuNTE1NSIgeDI9IjExLjk2MDIiIHkyPSI1My42NjI2IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiNEQjc2MDAiLz4KPHN0b3Agb2Zmc2V0PSIwLjIyODQiIHN0b3AtY29sb3I9IiNFMTg2MDgiLz4KPHN0b3Agb2Zmc2V0PSIwLjY3MjIiIHN0b3AtY29sb3I9IiNGMUFGMUYiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjRkZEMjMxIi8+CjwvbGluZWFyR3JhZGllbnQ+CjxyYWRpYWxHcmFkaWVudCBpZD0icGFpbnQxX3JhZGlhbF80MjFfMTgwNCIgY3g9IjAiIGN5PSIwIiByPSIxIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSgzMC4wMzIyIDUwLjI5NSkgc2NhbGUoMTQuMDM2IDE0LjAzNikiPgo8c3RvcCBzdG9wLWNvbG9yPSIjODUzQjFCIi8+CjxzdG9wIG9mZnNldD0iMC4xODMyIiBzdG9wLWNvbG9yPSIjN0QzOTFEIi8+CjxzdG9wIG9mZnNldD0iMC40Njc5IiBzdG9wLWNvbG9yPSIjNjczMzIxIi8+CjxzdG9wIG9mZnNldD0iMC44MTY4IiBzdG9wLWNvbG9yPSIjNDMyOTI4Ii8+CjxzdG9wIG9mZnNldD0iMC44NzI3IiBzdG9wLWNvbG9yPSIjM0QyNzI5Ii8+CjwvcmFkaWFsR3JhZGllbnQ+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQyX2xpbmVhcl80MjFfMTgwNCIgeDE9IjY3LjQ5MzkiIHkxPSIyMC45OTA5IiB4Mj0iNTMuOTI1OCIgeTI9IjExLjk4MTMiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzUzREFGMiIvPgo8c3RvcCBvZmZzZXQ9IjAuMjA5MyIgc3RvcC1jb2xvcj0iIzRFRDVGMSIvPgo8c3RvcCBvZmZzZXQ9IjAuNDU2MSIgc3RvcC1jb2xvcj0iIzQwQzdFRCIvPgo8c3RvcCBvZmZzZXQ9IjAuNzIxOCIgc3RvcC1jb2xvcj0iIzI4QUZFNyIvPgo8c3RvcCBvZmZzZXQ9IjAuOTk5MiIgc3RvcC1jb2xvcj0iIzA3OEVERSIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMwNzhFREUiLz4KPC9saW5lYXJHcmFkaWVudD4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDNfbGluZWFyXzQyMV8xODA0IiB4MT0iNzEuMTQyOSIgeTE9IjE1LjUzNTYiIHgyPSI1Ny4xOTI2IiB5Mj0iNi4yNzIxNiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjMDc4RURFIi8+CjxzdG9wIG9mZnNldD0iMC4wNzUyIiBzdG9wLWNvbG9yPSIjMTE5OUUyIi8+CjxzdG9wIG9mZnNldD0iMC4zMzE5IiBzdG9wLWNvbG9yPSIjMkZCQUVGIi8+CjxzdG9wIG9mZnNldD0iMC41Nzc5IiBzdG9wLWNvbG9yPSIjNDVEMkY4Ii8+CjxzdG9wIG9mZnNldD0iMC44MDYzIiBzdG9wLWNvbG9yPSIjNTJFMEZEIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzU3RTVGRiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50NF9saW5lYXJfNDIxXzE4MDQiIHgxPSI1OS44NjI2IiB5MT0iMzIuNjQ4NiIgeDI9IjQ2LjI5NjUiIHkyPSIyMy42NDAzIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiM1M0RBRjIiLz4KPHN0b3Agb2Zmc2V0PSIwLjIwOTMiIHN0b3AtY29sb3I9IiM0RUQ1RjEiLz4KPHN0b3Agb2Zmc2V0PSIwLjQ1NjEiIHN0b3AtY29sb3I9IiM0MEM3RUQiLz4KPHN0b3Agb2Zmc2V0PSIwLjcyMTgiIHN0b3AtY29sb3I9IiMyOEFGRTciLz4KPHN0b3Agb2Zmc2V0PSIwLjk5OTIiIHN0b3AtY29sb3I9IiMwNzhFREUiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMDc4RURFIi8+CjwvbGluZWFyR3JhZGllbnQ+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQ1X2xpbmVhcl80MjFfMTgwNCIgeDE9IjYzLjAyMTgiIHkxPSIyNy44Nzg0IiB4Mj0iNDkuMTI3MyIgeTI9IjE4LjY1MiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjMDc4RURFIi8+CjxzdG9wIG9mZnNldD0iMC4wNzUyIiBzdG9wLWNvbG9yPSIjMTE5OUUyIi8+CjxzdG9wIG9mZnNldD0iMC4zMzE5IiBzdG9wLWNvbG9yPSIjMkZCQUVGIi8+CjxzdG9wIG9mZnNldD0iMC41Nzc5IiBzdG9wLWNvbG9yPSIjNDVEMkY4Ii8+CjxzdG9wIG9mZnNldD0iMC44MDYzIiBzdG9wLWNvbG9yPSIjNTJFMEZEIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzU3RTVGRiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50Nl9saW5lYXJfNDIxXzE4MDQiIHgxPSI1MC4wMTQzIiB5MT0iNDcuOTM5MiIgeDI9IjM1LjY3MzYiIHkyPSIzOC40MTY2IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiM1N0U1RkYiLz4KPHN0b3Agb2Zmc2V0PSIwLjE5MzciIHN0b3AtY29sb3I9IiM1MkUwRkQiLz4KPHN0b3Agb2Zmc2V0PSIwLjQyMjEiIHN0b3AtY29sb3I9IiM0NUQyRjgiLz4KPHN0b3Agb2Zmc2V0PSIwLjY2ODEiIHN0b3AtY29sb3I9IiMyRkJBRUYiLz4KPHN0b3Agb2Zmc2V0PSIwLjkyNDgiIHN0b3AtY29sb3I9IiMxMTk5RTIiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMDc4RURFIi8+CjwvbGluZWFyR3JhZGllbnQ+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQ3X2xpbmVhcl80MjFfMTgwNCIgeDE9IjY5Ljg1ODUiIHkxPSI1Mi43NTI2IiB4Mj0iNjUuMzM2OSIgeTI9IjQyLjA3MDQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agb2Zmc2V0PSIwLjIzMDMiIHN0b3AtY29sb3I9IiNBQTVCRUYiLz4KPHN0b3Agb2Zmc2V0PSIwLjQ5MDYiIHN0b3AtY29sb3I9IiNBODU4RUUiLz4KPHN0b3Agb2Zmc2V0PSIwLjY1OTciIHN0b3AtY29sb3I9IiNBMjUwRTkiLz4KPHN0b3Agb2Zmc2V0PSIwLjgwMjkiIHN0b3AtY29sb3I9IiM5NjQxRTEiLz4KPHN0b3Agb2Zmc2V0PSIwLjkzMDgiIHN0b3AtY29sb3I9IiM4NzJDRDciLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjN0MxRENGIi8+CjwvbGluZWFyR3JhZGllbnQ+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQ4X2xpbmVhcl80MjFfMTgwNCIgeDE9Ijc0LjE2OTIiIHkxPSI1MC45NDM3IiB4Mj0iNjkuNTIwNSIgeTI9IjM5Ljk2MTIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzdDMURDRiIvPgo8c3RvcCBvZmZzZXQ9IjAuMDY5MiIgc3RvcC1jb2xvcj0iIzg3MkNENyIvPgo8c3RvcCBvZmZzZXQ9IjAuMTk3MSIgc3RvcC1jb2xvcj0iIzk2NDFFMSIvPgo8c3RvcCBvZmZzZXQ9IjAuMzQwMyIgc3RvcC1jb2xvcj0iI0EyNTBFOSIvPgo8c3RvcCBvZmZzZXQ9IjAuNTA5NCIgc3RvcC1jb2xvcj0iI0E4NThFRSIvPgo8c3RvcCBvZmZzZXQ9IjAuNzY5NyIgc3RvcC1jb2xvcj0iI0FBNUJFRiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50OV9saW5lYXJfNDIxXzE4MDQiIHgxPSI2MC43NDgxIiB5MT0iNTYuNjgxOCIgeDI9IjU2LjIyNjYiIHkyPSI0NS45OTk2IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIG9mZnNldD0iMC4yMzAzIiBzdG9wLWNvbG9yPSIjQUE1QkVGIi8+CjxzdG9wIG9mZnNldD0iMC40OTA2IiBzdG9wLWNvbG9yPSIjQTg1OEVFIi8+CjxzdG9wIG9mZnNldD0iMC42NTk3IiBzdG9wLWNvbG9yPSIjQTI1MEU5Ii8+CjxzdG9wIG9mZnNldD0iMC44MDI5IiBzdG9wLWNvbG9yPSIjOTY0MUUxIi8+CjxzdG9wIG9mZnNldD0iMC45MzA4IiBzdG9wLWNvbG9yPSIjODcyQ0Q3Ii8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzdDMURDRiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MTBfbGluZWFyXzQyMV8xODA0IiB4MT0iNjQuNDk3MiIgeTE9IjU1LjA4NTMiIHgyPSI1OS44NjYzIiB5Mj0iNDQuMTQ0OSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjN0MxRENGIi8+CjxzdG9wIG9mZnNldD0iMC4wNjkyIiBzdG9wLWNvbG9yPSIjODcyQ0Q3Ii8+CjxzdG9wIG9mZnNldD0iMC4xOTcxIiBzdG9wLWNvbG9yPSIjOTY0MUUxIi8+CjxzdG9wIG9mZnNldD0iMC4zNDAzIiBzdG9wLWNvbG9yPSIjQTI1MEU5Ii8+CjxzdG9wIG9mZnNldD0iMC41MDk0IiBzdG9wLWNvbG9yPSIjQTg1OEVFIi8+CjxzdG9wIG9mZnNldD0iMC43Njk3IiBzdG9wLWNvbG9yPSIjQUE1QkVGIi8+CjwvbGluZWFyR3JhZGllbnQ+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQxMV9saW5lYXJfNDIxXzE4MDQiIHgxPSI0OC44OTIiIHkxPSI2MS44OTM2IiB4Mj0iNDQuMTExOCIgeTI9IjUwLjYwMDUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agb2Zmc2V0PSIwLjIzMDMiIHN0b3AtY29sb3I9IiNBQTVCRUYiLz4KPHN0b3Agb2Zmc2V0PSIwLjQ5MDYiIHN0b3AtY29sb3I9IiNBODU4RUUiLz4KPHN0b3Agb2Zmc2V0PSIwLjY1OTciIHN0b3AtY29sb3I9IiNBMjUwRTkiLz4KPHN0b3Agb2Zmc2V0PSIwLjgwMjkiIHN0b3AtY29sb3I9IiM5NjQxRTEiLz4KPHN0b3Agb2Zmc2V0PSIwLjkzMDgiIHN0b3AtY29sb3I9IiM4NzJDRDciLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjN0MxRENGIi8+CjwvbGluZWFyR3JhZGllbnQ+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQxMl9saW5lYXJfNDIxXzE4MDQiIHgxPSIyOC41NDg3IiB5MT0iMTAuNjE0MyIgeDI9IjM4LjI5NDQiIHkyPSIxNS43NiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjRkYwMDBFIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0I4MDAwMCIvPgo8L2xpbmVhckdyYWRpZW50Pgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MTNfbGluZWFyXzQyMV8xODA0IiB4MT0iMzAuNjA3NiIgeTE9IjYuNjc4MzUiIHgyPSI0MC42Mjc0IiB5Mj0iMTEuOTY4NyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjQ0YwMDAwIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0ZGMDAwRSIvPgo8L2xpbmVhckdyYWRpZW50Pgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MTRfbGluZWFyXzQyMV8xODA0IiB4MT0iMjQuMDkzOSIgeTE9IjE4LjkyNDIiIHgyPSIzMy44MzYyIiB5Mj0iMjQuMDY4MSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjRkYwMDBFIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0I4MDAwMCIvPgo8L2xpbmVhckdyYWRpZW50Pgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MTVfbGluZWFyXzQyMV8xODA0IiB4MT0iMjUuOTAzOSIgeTE9IjE1LjQ5OTEiIHgyPSIzNS44ODQyIiB5Mj0iMjAuNzY4NiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjQ0YwMDAwIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0ZGMDAwRSIvPgo8L2xpbmVhckdyYWRpZW50Pgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MTZfbGluZWFyXzQyMV8xODA0IiB4MT0iMTguMTk3NCIgeTE9IjI5LjcyMzkiIHgyPSIyOC41IiB5Mj0iMzUuMTYzNiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjQ0YwMDAwIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0ZGMDAwRSIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo=");
}
/* =====================================================================
2) THE MODAL
===================================================================== */
.ec-modal-backdrop {
position: fixed;
inset: 0;
background: rgba(10, 20, 26, 0.82);
z-index: 9000;
display: flex;
align-items: center;
justify-content: center;
animation: ecu-fadein 0.25s ease;
padding: 20px;
}
.ec-modal-backdrop[hidden] { display: none; }
@keyframes ecu-fadein { from { opacity: 0; } to { opacity: 1; } }
.ec-modal {
background: #fff;
border-radius: 24px;
width: 520px;
max-width: 100%;
padding: 34px 44px 38px;
text-align: center;
position: relative;
box-shadow: 0 40px 100px rgba(0,0,0,0.45);
font-family: 'Inter', system-ui, -apple-system, sans-serif;
overflow: hidden;
animation: ecu-pop 0.32s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes ecu-pop {
from { transform: scale(0.92); opacity: 0; }
to { transform: scale(1); opacity: 1; }
}
.ec-modal::before {
content: "";
position: absolute;
top: -120px; left: 50%;
transform: translateX(-50%);
width: 620px; height: 260px;
background: radial-gradient(ellipse, rgba(48,217,10,0.20), transparent 62%);
pointer-events: none;
}
/* Single ✨ icon at the top (replaces the medallion) — bigger + green glow */
.ec-modal__icon {
position: relative;
width: 52px;
height: 52px;
margin: 0 auto 8px;
background: var(--ecu-party) center / contain no-repeat;
filter: drop-shadow(0 6px 14px rgba(0,0,0,0.14));
animation: ecu-bob 3.8s ease-in-out infinite;
}
@keyframes ecu-bob {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-4px); }
}
.ec-modal__pill {
display: inline-block;
/* pill sits at the top of the modal, surrounded by navy copy — green-on-green
was a lonely green island when only the gift box echoes it below. Keeping
the soft green tint as a subtle EmojiCopy nod, but switching the text to
navy so it reads as part of the heading group. */
background: var(--ecu-green-soft);
color: var(--ecu-navy);
padding: 6px 14px;
border-radius: 999px;
font: 800 10.5px/1 'Inter', sans-serif;
letter-spacing: 1.4px;
margin: 10px 0 0;
position: relative;
}
/* No accent color in the h2 — the logo green (bright or deep) is not used on main titles;
the title stays navy, with emphasis carried by caps/weight instead. */
/* Single CTA — replaces the email form. Full-width green pill, white text,
inline SVG arrow icon (no css ::after — the unicode arrow looked thin). */
.ec-modal__cta {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
width: 100%;
height: 56px;
padding: 0 28px;
border-radius: 999px;
/* match the app's standard green button — design-system tokens green-500 bg + metal-950 text */
background: #85FC64;
color: #0F1012;
font: 700 16px/1 'Inter', sans-serif;
text-decoration: none;
box-shadow: 0 6px 22px rgba(48,217,10,0.36);
transition: transform 0.18s cubic-bezier(0.34,1.56,0.64,1), box-shadow 0.18s ease;
}
.ec-modal__cta:hover {
text-decoration: none;
color: #0F1012;
transform: translateY(-2px);
box-shadow: 0 12px 30px rgba(48,217,10,0.50);
}
.ec-modal__cta:active { transform: translateY(0) scale(0.98); }
.ec-modal h2 {
margin: 14px 0 20px;
font: 800 31px/1.12 'Inter', sans-serif;
letter-spacing: -0.8px;
color: var(--ecu-navy);
position: relative;
}
.ec-modal ul {
list-style: none;
padding: 0;
margin: 0 0 32px;
text-align: left;
display: inline-block;
position: relative;
}
.ec-modal ul li {
padding: 10px 0 10px 32px;
font-size: 14.5px;
position: relative;
color: #2b2f33;
line-height: 1.4;
}
.ec-modal ul li::before {
content: "";
position: absolute;
left: 0;
top: 10px;
width: 20px;
height: 20px;
border-radius: 50%;
background: var(--ecu-green);
/* white check drawn with a background SVG */
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M6 10.5l2.6 2.6L14.2 7' fill='none' stroke='%23fff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: center;
}
/* Launch-perk callout — coupon-style band that breaks up the modal */
.ec-modal__perk {
position: relative;
display: flex; /* full content width — aligns with the bullets + form */
align-items: center;
gap: 13px;
text-align: left;
background: var(--ecu-green-soft);
border: 1.6px dashed var(--ecu-green);
border-radius: 14px;
padding: 16px 20px;
margin: 0 0 30px;
}
.ec-modal__perk .perk-ico {
flex-shrink: 0;
width: 38px; height: 38px;
border-radius: 10px;
background: var(--ecu-green);
display: flex;
align-items: center;
justify-content: center;
}
.ec-modal__perk .perk-ico svg { width: 20px; height: 20px; display: block; }
.ec-modal__perk .perk-text {
font: 500 13.5px/1.45 'Inter', sans-serif;
color: #2b2f33;
}
.ec-modal__perk .perk-text b {
color: var(--ecu-navy);
font-weight: 800;
}
.ec-modal__x {
position: absolute;
top: 16px; right: 18px;
font-size: 22px;
cursor: pointer;
color: #999;
background: none;
border: none;
z-index: 2;
line-height: 1;
}
/* ---- Logo footer ---- */
/* Centered column: the logo is always dead-center on the modal's axis (same
as B); alternate C stacks its small follow caption directly beneath it. */
.ec-modal__footer {
margin-top: 22px;
padding-top: 4px;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
}
.ec-modal__footer svg {
height: 22px;
width: auto;
opacity: 0.9;
}
// Pill → opens the modal. Modal closes on × / backdrop / Esc.
// No form, no counter — single CTA ([data-ec-join]) navigates the user to /beta-signup.
(function () {
const modal = document.getElementById('ecUpgradeModal');
if (!modal) return;
function openModal() { modal.hidden = false; document.body.style.overflow = 'hidden'; }
function closeModal() { modal.hidden = true; document.body.style.overflow = ''; }
document.querySelectorAll('[data-ec-open]').forEach(el =>
el.addEventListener('click', (e) => { e.preventDefault(); openModal(); })
);
modal.querySelectorAll('[data-ec-close]').forEach(el =>
el.addEventListener('click', closeModal)
);
modal.addEventListener('click', (e) => { if (e.target === modal) closeModal(); });
document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && !modal.hidden) closeModal(); });
})();
Grab a free account on the way in — Google or email, 30 seconds.
Jump Into the Beta<div class="ec-modal-backdrop" id="ecUpgradeModal" hidden
role="dialog" aria-modal="true" aria-labelledby="ecBetaInviteTitle">
<div class="ec-modal ec-modal--live" id="ecUpgradeCard">
<button class="ec-modal__x" data-ec-close aria-label="Close">×</button>
<div class="ec-modal__fan">
<div class="ec-modal__tiles" aria-hidden="true">
<span class="ec-modal__tile" style="--tf: rotate(-11deg) translateY(10px)"><span class="jp-font">🔥</span></span>
<span class="ec-modal__tile" style="--tf: rotate(-5deg) translateY(4px)"><span class="jp-font">✨</span></span>
<span class="ec-modal__tile ec-modal__tile--center" style="--tf: rotate(0deg) translateY(-4px)"><span class="jp-font">🎉</span></span>
<span class="ec-modal__tile" style="--tf: rotate(6deg) translateY(4px)"><span class="jp-font">❤️</span></span>
<span class="ec-modal__tile" style="--tf: rotate(12deg) translateY(10px)"><span class="jp-font">😂</span></span>
</div>
<span class="ec-modal__sticker">OPEN BETA</span>
</div>
<h2 id="ecBetaInviteTitle">NEW EmojiCopy is LIVE!</h2>
<ul>
<li>NEW Search Results (faster, re-built)</li>
<li>NEW Dynamic Copy Bar</li>
<li>NEW Favorites (add to list)</li>
</ul>
<p class="ec-modal__entry">Grab a <b>free account</b> on the way in — Google or email, 30 seconds.</p>
<a href="/beta-signup" class="ec-modal__cta" data-ec-join>Jump Into the Beta</a>
<div class="ec-modal__footer">
<a class="ec-modal__xfollow" target="_blank" rel="noopener"
href="https://x.com/intent/follow?screen_name=EmojiCopyApp">
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" 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.231 5.45-6.231zm-1.161 17.52h1.833L7.084 4.126H5.117l11.966 15.644z"/>
</svg>
<span>Follow <b>@EmojiCopyApp</b></span></a>
</div>
</div>
</div>
:root {
--ecu-green: #30D90A; /* EmojiCopy logo green */
--ecu-green-deep: #1f9c06; /* darker — for text / hover / contrast on white */
--ecu-green-soft: #e4fbdb; /* light tint — for backgrounds */
--ecu-navy: #1a1a2e;
}
/* =====================================================================
2) THE MODAL
===================================================================== */
.ec-modal-backdrop {
position: fixed;
inset: 0;
background: rgba(10, 20, 26, 0.82);
z-index: 9000;
display: flex;
align-items: center;
justify-content: center;
animation: ecu-fadein 0.25s ease;
padding: 20px;
}
.ec-modal-backdrop[hidden] { display: none; }
@keyframes ecu-fadein { from { opacity: 0; } to { opacity: 1; } }
.ec-modal {
background: #fff;
border-radius: 24px;
width: 520px;
max-width: 100%;
padding: 34px 44px 38px;
text-align: center;
position: relative;
box-shadow: 0 40px 100px rgba(0,0,0,0.45);
font-family: 'Inter', system-ui, -apple-system, sans-serif;
overflow: hidden;
animation: ecu-pop 0.32s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes ecu-pop {
from { transform: scale(0.92); opacity: 0; }
to { transform: scale(1); opacity: 1; }
}
.ec-modal::before {
content: "";
position: absolute;
top: -120px; left: 50%;
transform: translateX(-50%);
width: 620px; height: 260px;
background: radial-gradient(ellipse, rgba(48,217,10,0.20), transparent 62%);
pointer-events: none;
}
/* Single CTA — replaces the email form. Full-width green pill, white text,
inline SVG arrow icon (no css ::after — the unicode arrow looked thin). */
.ec-modal__cta {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
width: 100%;
height: 56px;
padding: 0 28px;
border-radius: 999px;
/* match the app's standard green button — design-system tokens green-500 bg + metal-950 text */
background: #85FC64;
color: #0F1012;
font: 700 16px/1 'Inter', sans-serif;
text-decoration: none;
box-shadow: 0 6px 22px rgba(48,217,10,0.36);
transition: transform 0.18s cubic-bezier(0.34,1.56,0.64,1), box-shadow 0.18s ease;
}
.ec-modal__cta:hover {
text-decoration: none;
color: #0F1012;
transform: translateY(-2px);
box-shadow: 0 12px 30px rgba(48,217,10,0.50);
}
.ec-modal__cta:active { transform: translateY(0) scale(0.98); }
.ec-modal h2 {
margin: 14px 0 20px;
font: 800 31px/1.12 'Inter', sans-serif;
letter-spacing: -0.8px;
color: var(--ecu-navy);
position: relative;
}
.ec-modal > p {
margin: 0 0 22px;
font-size: 15px;
color: #5a6066;
line-height: 1.55;
position: relative;
padding: 0 8px;
}
.ec-modal ul {
list-style: none;
padding: 0;
margin: 0 0 32px;
text-align: left;
display: inline-block;
position: relative;
}
.ec-modal ul li {
padding: 10px 0 10px 32px;
font-size: 14.5px;
position: relative;
color: #2b2f33;
line-height: 1.4;
}
.ec-modal ul li::before {
content: "";
position: absolute;
left: 0;
top: 10px;
width: 20px;
height: 20px;
border-radius: 50%;
background: var(--ecu-green);
/* white check drawn with a background SVG */
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M6 10.5l2.6 2.6L14.2 7' fill='none' stroke='%23fff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: center;
}
/* X-follow link — THE footer: one quiet centered line after the
CTA, so the modal ends on a single terminal beat (the wordmark logo is
deleted in C — the title already carries the brand on EmojiCopy's own
site, and two stacked signoffs read as a second footer). Href is the X
follow web intent, opened as a small popup by ec-upgrade-script (new-tab
fallback if blocked). */
.ec-modal__xfollow {
position: relative;
display: inline-flex;
align-items: center;
gap: 7px;
font: 600 13px 'Inter', sans-serif;
color: #8a9097;
text-decoration: none;
transition: color 0.15s ease;
}
.ec-modal__xfollow svg { width: 12px; height: 12px; display: block; fill: currentColor; }
.ec-modal__xfollow b { color: #5a6066; font-weight: 800; transition: color 0.15s ease; }
.ec-modal__xfollow:hover { color: var(--ecu-navy); text-decoration: none; }
.ec-modal__xfollow:hover b { color: var(--ecu-navy); }
/* ---- Variant D (.ec-modal--live) — "tile drop" announcement ----
D has ONE job: make the news feel like the product. Five tilted JoyPixels
tiles drop in wearing an OPEN BETA sticker (the approved celebration
recipe: tilted jp tiles + badge + green glow) — the modal DEMONSTRATES
"new EmojiCopy" instead of describing it. One benefit line carries the
pitch; the account requirement is one quiet line fused to the CTA (10px)
so it reads as the button's caption — a heads-up, not a hurdle. Ends on
the CTA: no footer wordmark (C precedent — the title carries the brand on
EmojiCopy's own site). Motion is entrance-only; after the tiles settle,
nothing on the card moves, so the CTA owns attention. Tile emoji MUST
render as JoyPixels (jp-font + joypixels.css) — Apple glyphs = bug. */
.ec-modal--live { padding: 36px 44px 44px; }
/* green pool sits behind the fan — wider + lower than the base glow; still
a tint, the CTA stays the card's one dominant green surface */
.ec-modal--live::before {
top: -70px;
height: 300px;
background: radial-gradient(ellipse, rgba(48,217,10,0.28), transparent 62%);
}
.ec-modal--live h2 { margin: 28px 0 14px; }
.ec-modal__fan { position: relative; margin: 0; }
.ec-modal__tiles {
display: flex;
align-items: flex-end;
justify-content: center;
height: 86px;
}
.ec-modal__tile {
--tf: none; /* per-tile resting transform, set inline on each tile */
width: 56px; height: 56px;
margin: 0 -5px;
display: flex;
align-items: center;
justify-content: center;
background: #fff;
border: 1px solid rgba(26, 26, 46, 0.08);
border-radius: 16px;
box-shadow: 0 8px 20px rgba(26, 26, 46, 0.14);
transform: var(--tf);
animation: ecu-tile-in 0.45s cubic-bezier(0.34, 1.56, 0.64, 1) backwards;
}
.ec-modal__tile .jp-font { font-size: 32px; line-height: 1; }
.ec-modal__tile--center { width: 64px; height: 64px; z-index: 1; }
.ec-modal__tile--center .jp-font { font-size: 38px; }
.ec-modal__tile:nth-child(1) { animation-delay: 0.00s; }
.ec-modal__tile:nth-child(2) { animation-delay: 0.06s; }
.ec-modal__tile:nth-child(3) { animation-delay: 0.12s; }
.ec-modal__tile:nth-child(4) { animation-delay: 0.18s; }
.ec-modal__tile:nth-child(5) { animation-delay: 0.24s; }
@keyframes ecu-tile-in {
from { opacity: 0; transform: translateY(-26px) scale(0.9) var(--tf); }
to { opacity: 1; transform: var(--tf); }
}
/* the beta badge rides the tiles like a sticker slapped on the stack */
.ec-modal__sticker {
position: absolute;
left: 50%; bottom: -8px;
transform: translateX(-50%) rotate(-3deg);
background: var(--ecu-green-soft);
color: var(--ecu-navy);
border: 2px solid #fff;
border-radius: 999px;
padding: 6px 14px;
font: 800 10.5px/1 'Inter', sans-serif;
letter-spacing: 1.4px;
box-shadow: 0 4px 12px rgba(26, 26, 46, 0.18);
z-index: 2;
animation: ecu-sticker-in 0.3s cubic-bezier(0.34, 1.56, 0.64, 1) 0.5s backwards;
}
@keyframes ecu-sticker-in {
from { opacity: 0; transform: translateX(-50%) rotate(-3deg) scale(0.6); }
to { opacity: 1; transform: translateX(-50%) rotate(-3deg) scale(1); }
}
/* three bullets — the pitch. Chosen for what an old-site user FEELS in
their current loop: search (felt every visit), multi-copy (upgrades the
click they're mid-way through), save favorites/combos (kills the daily
re-hunt). Ad-free deliberately NOT here — relief isn't the invite's
seller (it stays in B/C and the blog). Reuses the base green-check ul,
tightened like C's, with air above the CTA group. */
.ec-modal--live ul { margin: 0 0 30px; }
.ec-modal--live ul li { padding: 7px 0 7px 30px; }
.ec-modal--live ul li::before { top: 7px; }
/* account whisper — deliberately the quietest element on the card: no box,
no icon, no green. 10px from the CTA so requirement and action are
absorbed in the same glance. Sign-up methods are "Google or email" —
passwords are never mentioned (there are none: PIN+Google). */
.ec-modal--live .ec-modal__entry {
position: relative;
margin: 0 0 12px;
padding: 0;
font: 500 13px/1.5 'Inter', sans-serif;
color: #8a9097;
}
.ec-modal--live .ec-modal__entry b { color: #5a6066; font-weight: 700; }
/* quiet C-style follow line after the CTA (added 2026-07-20) — the one
element below the button; still a single terminal beat */
.ec-modal--live .ec-modal__footer { margin-top: 20px; padding-top: 0; }
@media (prefers-reduced-motion: reduce) {
.ec-modal__tile,
.ec-modal__sticker { animation: none !important; }
}
.ec-modal__x {
position: absolute;
top: 16px; right: 18px;
font-size: 22px;
cursor: pointer;
color: #999;
background: none;
border: none;
z-index: 2;
line-height: 1;
}
/* ---- Logo footer ---- */
/* Centered column: the logo is always dead-center on the modal's axis (same
as B); alternate C stacks its small follow caption directly beneath it. */
.ec-modal__footer {
margin-top: 22px;
padding-top: 4px;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
}
.ec-modal__footer svg {
height: 22px;
width: auto;
opacity: 0.9;
}
// Pill → opens the modal. Modal closes on × / backdrop / Esc.
// No form, no counter — single CTA ([data-ec-join]) navigates the user to /beta-signup.
(function () {
const modal = document.getElementById('ecUpgradeModal');
if (!modal) return;
function openModal() { modal.hidden = false; document.body.style.overflow = 'hidden'; }
function closeModal() { modal.hidden = true; document.body.style.overflow = ''; }
document.querySelectorAll('[data-ec-open]').forEach(el =>
el.addEventListener('click', (e) => { e.preventDefault(); openModal(); })
);
modal.querySelectorAll('[data-ec-close]').forEach(el =>
el.addEventListener('click', closeModal)
);
modal.addEventListener('click', (e) => { if (e.target === modal) closeModal(); });
document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && !modal.hidden) closeModal(); });
})();
// X follow — open the follow web intent in a small centered popup so
// the site stays put; if the popup is blocked, the link's target="_blank"
// takes over and it opens as a normal new tab instead.
(function () {
document.querySelectorAll('.ec-modal__xfollow').forEach(el =>
el.addEventListener('click', (e) => {
const w = 550, h = 480;
const left = Math.round(window.screenX + (window.outerWidth - w) / 2);
const top = Math.round(window.screenY + (window.outerHeight - h) / 2);
const win = window.open(el.href, 'ecXFollow',
`popup,width=${w},height=${h},left=${left},top=${top}`);
if (win) e.preventDefault();
})
);
})();
The same experience is coming to the extension.
Grab a free account.
Try the New EmojiCopy<div class="ec-modal-backdrop" id="ecUpgradeModalExt" hidden
role="dialog" aria-modal="true" aria-labelledby="ecBetaInviteTitleExtF">
<div class="ec-modal ec-modal--live ec-modal--ext ec-modal--extf" id="ecUpgradeCardExt">
<button class="ec-modal__x" data-ec-close aria-label="Close">×</button>
<div class="ec-modal__fan">
<div class="ec-modal__tiles" aria-hidden="true">
<span class="ec-modal__tile" style="--tf: rotate(-11deg) translateY(10px)"><span class="jp-font">🔥</span></span>
<span class="ec-modal__tile" style="--tf: rotate(-5deg) translateY(4px)"><span class="jp-font">✨</span></span>
<span class="ec-modal__tile ec-modal__tile--center" style="--tf: rotate(0deg) translateY(-4px)"><span class="jp-font">🎉</span></span>
<span class="ec-modal__tile" style="--tf: rotate(6deg) translateY(4px)"><span class="jp-font">❤️</span></span>
<span class="ec-modal__tile" style="--tf: rotate(12deg) translateY(10px)"><span class="jp-font">😂</span></span>
</div>
<span class="ec-modal__sticker">OPEN BETA</span>
</div>
<h2 id="ecBetaInviteTitleExtF">Try our new web app</h2>
<p>The same experience is coming to the extension.</p>
<ul>
<li>NEW Favorites (add to list)</li>
<li>NEW Search Results (faster, re-built)</li>
<li>NEW Save Combos (multi-emoji sets)</li>
</ul>
<p class="ec-modal__entry">Grab a <b>free account</b>.</p>
<a href="https://beta.emojicopy.com/?ref=extension" target="_blank" rel="noopener"
class="ec-modal__cta" data-ec-join>Try the New EmojiCopy</a>
<div class="ec-modal__footer">
<a class="ec-modal__xfollow" target="_blank" rel="noopener"
href="https://x.com/intent/follow?screen_name=EmojiCopyApp">
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" 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.231 5.45-6.231zm-1.161 17.52h1.833L7.084 4.126H5.117l11.966 15.644z"/>
</svg>
<span>Follow <b>@EmojiCopyApp</b></span></a>
</div>
</div>
</div>
:root {
--ecu-green: #30D90A; /* EmojiCopy logo green */
--ecu-green-deep: #1f9c06; /* darker — for text / hover / contrast on white */
--ecu-green-soft: #e4fbdb; /* light tint — for backgrounds */
--ecu-navy: #1a1a2e;
}
/* =====================================================================
2) THE MODAL
===================================================================== */
.ec-modal-backdrop {
position: fixed;
inset: 0;
background: rgba(10, 20, 26, 0.82);
z-index: 9000;
display: flex;
align-items: center;
justify-content: center;
animation: ecu-fadein 0.25s ease;
padding: 20px;
}
.ec-modal-backdrop[hidden] { display: none; }
@keyframes ecu-fadein { from { opacity: 0; } to { opacity: 1; } }
.ec-modal {
background: #fff;
border-radius: 24px;
width: 520px;
max-width: 100%;
padding: 34px 44px 38px;
text-align: center;
position: relative;
box-shadow: 0 40px 100px rgba(0,0,0,0.45);
font-family: 'Inter', system-ui, -apple-system, sans-serif;
overflow: hidden;
animation: ecu-pop 0.32s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes ecu-pop {
from { transform: scale(0.92); opacity: 0; }
to { transform: scale(1); opacity: 1; }
}
.ec-modal::before {
content: "";
position: absolute;
top: -120px; left: 50%;
transform: translateX(-50%);
width: 620px; height: 260px;
background: radial-gradient(ellipse, rgba(48,217,10,0.20), transparent 62%);
pointer-events: none;
}
/* Single CTA — replaces the email form. Full-width green pill, white text,
inline SVG arrow icon (no css ::after — the unicode arrow looked thin). */
.ec-modal__cta {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
width: 100%;
height: 56px;
padding: 0 28px;
border-radius: 999px;
/* match the app's standard green button — design-system tokens green-500 bg + metal-950 text */
background: #85FC64;
color: #0F1012;
font: 700 16px/1 'Inter', sans-serif;
text-decoration: none;
box-shadow: 0 6px 22px rgba(48,217,10,0.36);
transition: transform 0.18s cubic-bezier(0.34,1.56,0.64,1), box-shadow 0.18s ease;
}
.ec-modal__cta:hover {
text-decoration: none;
color: #0F1012;
transform: translateY(-2px);
box-shadow: 0 12px 30px rgba(48,217,10,0.50);
}
.ec-modal__cta:active { transform: translateY(0) scale(0.98); }
.ec-modal h2 {
margin: 14px 0 20px;
font: 800 31px/1.12 'Inter', sans-serif;
letter-spacing: -0.8px;
color: var(--ecu-navy);
position: relative;
}
.ec-modal > p {
margin: 0 0 22px;
font-size: 15px;
color: #5a6066;
line-height: 1.55;
position: relative;
padding: 0 8px;
}
.ec-modal ul {
list-style: none;
padding: 0;
margin: 0 0 32px;
text-align: left;
display: inline-block;
position: relative;
}
.ec-modal ul li {
padding: 10px 0 10px 32px;
font-size: 14.5px;
position: relative;
color: #2b2f33;
line-height: 1.4;
}
.ec-modal ul li::before {
content: "";
position: absolute;
left: 0;
top: 10px;
width: 20px;
height: 20px;
border-radius: 50%;
background: var(--ecu-green);
/* white check drawn with a background SVG */
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M6 10.5l2.6 2.6L14.2 7' fill='none' stroke='%23fff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: center;
}
/* X-follow link — THE footer: one quiet centered line after the
CTA, so the modal ends on a single terminal beat (the wordmark logo is
deleted in C — the title already carries the brand on EmojiCopy's own
site, and two stacked signoffs read as a second footer). Href is the X
follow web intent, opened as a small popup by ec-upgrade-script (new-tab
fallback if blocked). */
.ec-modal__xfollow {
position: relative;
display: inline-flex;
align-items: center;
gap: 7px;
font: 600 13px 'Inter', sans-serif;
color: #8a9097;
text-decoration: none;
transition: color 0.15s ease;
}
.ec-modal__xfollow svg { width: 12px; height: 12px; display: block; fill: currentColor; }
.ec-modal__xfollow b { color: #5a6066; font-weight: 800; transition: color 0.15s ease; }
.ec-modal__xfollow:hover { color: var(--ecu-navy); text-decoration: none; }
.ec-modal__xfollow:hover b { color: var(--ecu-navy); }
/* ---- Variant D (.ec-modal--live) — "tile drop" announcement ----
D has ONE job: make the news feel like the product. Five tilted JoyPixels
tiles drop in wearing an OPEN BETA sticker (the approved celebration
recipe: tilted jp tiles + badge + green glow) — the modal DEMONSTRATES
"new EmojiCopy" instead of describing it. One benefit line carries the
pitch; the account requirement is one quiet line fused to the CTA (10px)
so it reads as the button's caption — a heads-up, not a hurdle. Ends on
the CTA: no footer wordmark (C precedent — the title carries the brand on
EmojiCopy's own site). Motion is entrance-only; after the tiles settle,
nothing on the card moves, so the CTA owns attention. Tile emoji MUST
render as JoyPixels (jp-font + joypixels.css) — Apple glyphs = bug. */
.ec-modal--live { padding: 36px 44px 44px; }
/* green pool sits behind the fan — wider + lower than the base glow; still
a tint, the CTA stays the card's one dominant green surface */
.ec-modal--live::before {
top: -70px;
height: 300px;
background: radial-gradient(ellipse, rgba(48,217,10,0.28), transparent 62%);
}
.ec-modal--live h2 { margin: 28px 0 14px; }
.ec-modal__fan { position: relative; margin: 0; }
.ec-modal__tiles {
display: flex;
align-items: flex-end;
justify-content: center;
height: 86px;
}
.ec-modal__tile {
--tf: none; /* per-tile resting transform, set inline on each tile */
width: 56px; height: 56px;
margin: 0 -5px;
display: flex;
align-items: center;
justify-content: center;
background: #fff;
border: 1px solid rgba(26, 26, 46, 0.08);
border-radius: 16px;
box-shadow: 0 8px 20px rgba(26, 26, 46, 0.14);
transform: var(--tf);
animation: ecu-tile-in 0.45s cubic-bezier(0.34, 1.56, 0.64, 1) backwards;
}
.ec-modal__tile .jp-font { font-size: 32px; line-height: 1; }
.ec-modal__tile--center { width: 64px; height: 64px; z-index: 1; }
.ec-modal__tile--center .jp-font { font-size: 38px; }
.ec-modal__tile:nth-child(1) { animation-delay: 0.00s; }
.ec-modal__tile:nth-child(2) { animation-delay: 0.06s; }
.ec-modal__tile:nth-child(3) { animation-delay: 0.12s; }
.ec-modal__tile:nth-child(4) { animation-delay: 0.18s; }
.ec-modal__tile:nth-child(5) { animation-delay: 0.24s; }
@keyframes ecu-tile-in {
from { opacity: 0; transform: translateY(-26px) scale(0.9) var(--tf); }
to { opacity: 1; transform: var(--tf); }
}
/* the beta badge rides the tiles like a sticker slapped on the stack */
.ec-modal__sticker {
position: absolute;
left: 50%; bottom: -8px;
transform: translateX(-50%) rotate(-3deg);
background: var(--ecu-green-soft);
color: var(--ecu-navy);
border: 2px solid #fff;
border-radius: 999px;
padding: 6px 14px;
font: 800 10.5px/1 'Inter', sans-serif;
letter-spacing: 1.4px;
box-shadow: 0 4px 12px rgba(26, 26, 46, 0.18);
z-index: 2;
animation: ecu-sticker-in 0.3s cubic-bezier(0.34, 1.56, 0.64, 1) 0.5s backwards;
}
@keyframes ecu-sticker-in {
from { opacity: 0; transform: translateX(-50%) rotate(-3deg) scale(0.6); }
to { opacity: 1; transform: translateX(-50%) rotate(-3deg) scale(1); }
}
/* three bullets — the pitch. Chosen for what an old-site user FEELS in
their current loop: search (felt every visit), multi-copy (upgrades the
click they're mid-way through), save favorites/combos (kills the daily
re-hunt). Ad-free deliberately NOT here — relief isn't the invite's
seller (it stays in B/C and the blog). Reuses the base green-check ul,
tightened like C's, with air above the CTA group. */
.ec-modal--live ul { margin: 0 0 30px; }
.ec-modal--live ul li { padding: 7px 0 7px 30px; }
.ec-modal--live ul li::before { top: 7px; }
/* account whisper — deliberately the quietest element on the card: no box,
no icon, no green. 10px from the CTA so requirement and action are
absorbed in the same glance. Sign-up methods are "Google or email" —
passwords are never mentioned (there are none: PIN+Google). */
.ec-modal--live .ec-modal__entry {
position: relative;
margin: 0 0 12px;
padding: 0;
font: 500 13px/1.5 'Inter', sans-serif;
color: #8a9097;
}
.ec-modal--live .ec-modal__entry b { color: #5a6066; font-weight: 700; }
/* quiet C-style follow line after the CTA (added 2026-07-20) — the one
element below the button; still a single terminal beat */
.ec-modal--live .ec-modal__footer { margin-top: 20px; padding-top: 0; }
@media (prefers-reduced-motion: reduce) {
.ec-modal__tile,
.ec-modal__sticker { animation: none !important; }
}
/* ---- Extension compact overrides (.ec-modal--ext) — used by F ----
Stacks on --live (same recipe) and tightens for the popup context.
No boxed callouts (same rule as the account line) and no Pro/pricing
talk — the invite invites, the app converts. */
.ec-modal--ext { width: 430px; padding: 30px 34px 32px; }
.ec-modal--ext .ec-modal__fan { margin: 0; }
.ec-modal--ext h2 { font-size: 25px; letter-spacing: -0.5px; margin: 18px 0 16px; }
.ec-modal--ext .ec-modal__tiles { height: 72px; }
.ec-modal--ext .ec-modal__tile { width: 48px; height: 48px; border-radius: 14px; }
.ec-modal--ext .ec-modal__tile .jp-font { font-size: 27px; }
.ec-modal--ext .ec-modal__tile--center { width: 56px; height: 56px; }
.ec-modal--ext .ec-modal__tile--center .jp-font { font-size: 33px; }
.ec-modal--ext ul { margin: 0 0 22px; }
.ec-modal--ext ul li { padding: 6px 0 6px 30px; font-size: 13.5px; }
.ec-modal--ext ul li::before { top: 6px; }
.ec-modal--ext .ec-modal__entry { margin: 0 0 12px; font-size: 12.5px; }
.ec-modal--ext .ec-modal__cta { height: 52px; font-size: 15px; }
.ec-modal--ext .ec-modal__footer { margin-top: 16px; }
/* ---- Variant F (.ec-modal--extf) — E iterated on one principle: assume
only the TITLE and the CTA get read. "Try our new web app" -> "Open
EmojiCopy" is the complete message; one subline carries the reassurance
(same experience coming to this extension) for the few who linger. */
.ec-modal--extf h2 { margin: 18px 0 8px; }
.ec-modal--extf > p { margin: 0 0 18px; font-size: 14px; padding: 0; color: #5a6066; }
.ec-modal__x {
position: absolute;
top: 16px; right: 18px;
font-size: 22px;
cursor: pointer;
color: #999;
background: none;
border: none;
z-index: 2;
line-height: 1;
}
/* ---- Logo footer ---- */
/* Centered column: the logo is always dead-center on the modal's axis (same
as B); alternate C stacks its small follow caption directly beneath it. */
.ec-modal__footer {
margin-top: 22px;
padding-top: 4px;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
}
.ec-modal__footer svg {
height: 22px;
width: auto;
opacity: 0.9;
}
// Pill → opens the modal. Modal closes on × / backdrop / Esc.
// No form, no counter — single CTA ([data-ec-join]) opens beta.emojicopy.com/?ref=extension in a new tab.
(function () {
const modal = document.getElementById('ecUpgradeModalExt');
if (!modal) return;
function openModal() { modal.hidden = false; document.body.style.overflow = 'hidden'; }
function closeModal() { modal.hidden = true; document.body.style.overflow = ''; }
document.querySelectorAll('[data-ec-open]').forEach(el =>
el.addEventListener('click', (e) => { e.preventDefault(); openModal(); })
);
modal.querySelectorAll('[data-ec-close]').forEach(el =>
el.addEventListener('click', closeModal)
);
modal.addEventListener('click', (e) => { if (e.target === modal) closeModal(); });
document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && !modal.hidden) closeModal(); });
})();
// X follow — open the follow web intent in a small centered popup so
// the site stays put; if the popup is blocked, the link's target="_blank"
// takes over and it opens as a normal new tab instead.
(function () {
document.querySelectorAll('.ec-modal__xfollow').forEach(el =>
el.addEventListener('click', (e) => {
const w = 550, h = 480;
const left = Math.round(window.screenX + (window.outerWidth - w) / 2);
const top = Math.round(window.screenY + (window.outerHeight - h) / 2);
const win = window.open(el.href, 'ecXFollow',
`popup,width=${w},height=${h},left=${left},top=${top}`);
if (win) e.preventDefault();
})
);
})();