feat: init first beta

This commit is contained in:
Shuhard 2025-07-02 13:37:16 +03:00
parent 8d95d047ea
commit d684cf3cb1
126 changed files with 7907 additions and 351 deletions

4
.env.defaults Normal file
View File

@ -0,0 +1,4 @@
PROTOCOL=https
HOSTNAME=mssg.me
ADMIN_HOSTNAME=next.mssg.me
BLACK_FRIDAY_PROMO=

2
.gitignore vendored
View File

@ -31,7 +31,7 @@ yarn-error.log*
.pnpm-debug.log* .pnpm-debug.log*
# env files (can opt-in for committing if needed) # env files (can opt-in for committing if needed)
.env* .env
# vercel # vercel
.vercel .vercel

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"typescript.tsdk": "node_modules/typescript/lib"
}

5
env-setup.ts Normal file
View File

@ -0,0 +1,5 @@
import { config as dotenvDefaultsConfig } from 'dotenv-defaults';
dotenvDefaultsConfig();
export {};

153
messages/en.json Normal file
View File

@ -0,0 +1,153 @@
{
"Not Found": "Not Found",
"common": {
"and": "and",
"soon": "Soon"
},
"menu": {
"subheading1": "Growth tools",
"subheading2": "Manage tool",
"subheading3": "Resources",
"subheading4": "Company",
"platform": "Platform",
"page": "Page",
"widget": "Widget",
"qr": "QR code",
"pricing": "Pricing",
"blog": "Blog",
"faq": "FAQ",
"terms": "Terms of use",
"privacy": "Privacy policy"
},
"button": {
"login": "Login",
"trial": "Start for Free",
"start": "Get Started",
"get_started_for_free": "Start for free",
"try_trial": "Try for Free",
"view_faq": "View FAQ",
"how_it_works": "Watch how it works",
"more_about": "More about"
},
"posts_section": {
"heading_line_1": "Useful things",
"heading_line_2": "in simple words"
},
"page_pricing": {
"terms": "/month",
"sign_up": "Sign up Now",
"annual": "Annual",
"monthly": "Monthly"
},
"ie11Message": {
"heading": "Your browser is too old",
"message": "Update your internet browser to latest version to use mssg.me service"
},
"blog": {
"title": "Blog | mssg.me",
"description": "Latest news from mssg.me"
},
"single_article": {
"posts_section": {
"heading": "You may also like"
}
},
"http_error": {
"404": "Nothing found"
},
"404": {
"heading": "404 error",
"error": "The page doesnt exist",
"button": "Visit Homepage"
},
"cookies": {
"message": "We use cookies",
"link": "Details"
},
"top_pane": {
"message": "All messages in one app",
"button": "Details"
},
"buttons": {
"getStarted": "Get Started",
"getFreePage": "Get your free page"
},
"promo": {
"black_friday": "Black Friday Offer 🔥 35% off on yearly plans!"
},
"website_home": {
"head": {
"title": "Easy way to build website",
"description": "Create mobile website, page with links or online store in minutes."
},
"common": {
"sign_up_cta": "Start for free",
"cookies": {
"message": "We use cookies",
"link": "Details"
},
"terms": {
"terms": "Terms of Service",
"politics": "Privacy Policy"
},
"auth": {
"login": "Log in",
"signup": "Sign up"
}
},
"home": {
"intro": {
"title": {
"1": "Building Websites",
"2": "Made Simple"
},
"description": "The website builder to create your link in bio, landing page or online store in minutes."
},
"presentation": {
"title": "Build website for anything.",
"description": "Its simple. No coding. On your Phone."
},
"multi_link": {
"title": "MULTIPLE LINKS",
"subtitle": "Add unlimited links",
"description": "Connect followers to all of your content with just one link. Add a link to your website in Instagram bio, TikTok or other social networks."
},
"messengers": {
"title": "INSTANT MESSENGERS",
"subtitle": "Easy way to contact you",
"description": "Create a better customer engagement experience by providing a fast, convenient way of communication, so they can easily contact you in seconds."
},
"store": {
"title": "ONLINE STORE",
"subtitle": "Start selling online",
"description": "Launch a beautiful online store in minutes. Add your products, categories and start accept payments. Manage orders on the go with simple build in CRM system."
},
"builder": {
"title": "LANDING PAGE",
"subtitle": "Build custom website",
"description": "Create a custom landing page that you need. Build your website with simple tools in your way for you and your business."
},
"features": {
"title": "Amazing features",
"list": {
"domain": {
"title": "Custom domain",
"description": "Connect a domain to your website and get free SSL certificate."
},
"qr": {
"title": "QR-code",
"description": "Use build in QR-code for your website to drive visitors from offline."
},
"analytics": {
"title": "Insights",
"description": "Get useful insights about visits and click or integrate Google Analytics, Facebook and TikTok pixels to know more data."
}
}
},
"footer": {
"title": "Build your website in minutes",
"description": "Tell story. Sell products. Grow business."
}
}
}
}

153
messages/es.json Normal file
View File

@ -0,0 +1,153 @@
{
"Not Found": "No encontrado",
"common": {
"and": "y",
"soon": "Pronto"
},
"menu": {
"subheading1": "Herramientas de crecimiento",
"subheading2": "Gestionar herramienta",
"subheading3": "Recursos",
"subheading4": "Empresa",
"platform": "Plataforma",
"page": "Página",
"widget": "Widget",
"qr": "Código QR",
"pricing": "Precios",
"blog": "Blog",
"faq": "Preguntas frecuentes",
"terms": "Términos de uso",
"privacy": "Política de privacidad"
},
"button": {
"login": "Iniciar sesión",
"trial": "Comienza gratis",
"start": "Empezar",
"get_started_for_free": "Comienza gratis",
"try_trial": "Prueba gratis",
"view_faq": "Ver preguntas frecuentes",
"how_it_works": "Ver cómo funciona",
"more_about": "Más sobre"
},
"posts_section": {
"heading_line_1": "Cosas útiles",
"heading_line_2": "en palabras simples"
},
"page_pricing": {
"terms": "/mes",
"sign_up": "Regístrate ahora",
"annual": "Anual",
"monthly": "Mensual"
},
"ie11Message": {
"heading": "Tu navegador es demasiado antiguo",
"message": "Actualiza tu navegador de internet a la última versión para usar el servicio mssg.me"
},
"blog": {
"title": "Blog | mssg.me",
"description": "Últimas noticias de mssg.me"
},
"single_article": {
"posts_section": {
"heading": "También te puede gustar"
}
},
"http_error": {
"404": "Nada encontrado"
},
"404": {
"heading": "Error 404",
"error": "La página no existe",
"button": "Visitar página principal"
},
"cookies": {
"message": "Usamos cookies",
"link": "Detalles"
},
"top_pane": {
"message": "Todos los mensajes en una aplicación",
"button": "Detalles"
},
"buttons": {
"getStarted": "Empezar",
"getFreePage": "Obtén tu página gratis"
},
"promo": {
"black_friday": "Oferta de Black Friday 🔥 35% de descuento en planes anuales!"
},
"website_home": {
"head": {
"title": "Forma fácil de crear un sitio web",
"description": "Crea un sitio web móvil, una página con enlaces o una tienda en línea en minutos."
},
"common": {
"sign_up_cta": "Comienza gratis",
"cookies": {
"message": "Usamos cookies",
"link": "Detalles"
},
"terms": {
"terms": "Términos de servicio",
"politics": "Política de privacidad"
},
"auth": {
"login": "Iniciar sesión",
"signup": "Regístrate"
}
},
"home": {
"intro": {
"title": {
"1": "Tu sitio web.",
"2": "Tu manera."
},
"description": "Crea un sitio web móvil, una página con enlaces o una tienda en línea en minutos."
},
"presentation": {
"title": "Crea un sitio web para cualquier cosa.",
"description": "Es simple. Sin codificación. En tu teléfono."
},
"multi_link": {
"title": "MÚLTIPLES ENLACES",
"subtitle": "Agrega enlaces ilimitados",
"description": "Conecta a tus seguidores con todo tu contenido con un solo enlace. Agrega un enlace a tu sitio web en la biografía de Instagram, TikTok u otras redes sociales."
},
"messengers": {
"title": "MENSAJEROS INSTANTÁNEOS",
"subtitle": "Forma fácil de contactarte",
"description": "Crea una mejor experiencia de compromiso con el cliente proporcionando una forma rápida y conveniente de comunicación, para que puedan contactarte fácilmente en segundos."
},
"store": {
"title": "TIENDA EN LÍNEA",
"subtitle": "Comienza a vender en línea",
"description": "Lanza una hermosa tienda en línea en minutos. Agrega tus productos, categorías y comienza a aceptar pagos. Gestiona pedidos sobre la marcha con un simple sistema CRM integrado."
},
"builder": {
"title": "PÁGINA DE DESTINO",
"subtitle": "Crea un sitio web personalizado",
"description": "Crea una página de destino personalizada que necesites. Construye tu sitio web con herramientas simples a tu manera para ti y tu negocio."
},
"features": {
"title": "Características asombrosas",
"list": {
"domain": {
"title": "Dominio personalizado",
"description": "Conecta un dominio a tu sitio web y obtén un certificado SSL gratuito."
},
"qr": {
"title": "Código QR",
"description": "Usa el código QR integrado para tu sitio web y atrae visitantes desde fuera de línea."
},
"analytics": {
"title": "Perspectivas",
"description": "Obtén perspectivas útiles sobre visitas y clics o integra Google Analytics, Facebook y TikTok pixels para conocer más datos."
}
}
},
"footer": {
"title": "Crea tu sitio web en minutos",
"description": "Cuenta tu historia. Vende productos. Haz crecer tu negocio."
}
}
}
}

153
messages/pt.json Normal file
View File

@ -0,0 +1,153 @@
{
"Not Found": "Not Found",
"common": {
"and": "e",
"soon": "Em breve"
},
"menu": {
"subheading1": "Ferramentas de crescimento",
"subheading2": "Ferramenta de gerenciamento",
"subheading3": "Recursos",
"subheading4": "Empresa",
"platform": "Plataforma",
"page": "Página",
"widget": "Widget",
"qr": "Código QR",
"pricing": "Preços",
"blog": "Blog",
"faq": "Perguntas frequentes",
"terms": "Termos de uso",
"privacy": "Política de privacidade"
},
"button": {
"login": "Entrar",
"trial": "Começar grátis",
"start": "Começar",
"get_started_for_free": "Começar grátis",
"try_trial": "Experimentar grátis",
"view_faq": "Ver perguntas frequentes",
"how_it_works": "Veja como funciona",
"more_about": "Mais sobre"
},
"posts_section": {
"heading_line_1": "Coisas úteis",
"heading_line_2": "em palavras simples"
},
"page_pricing": {
"terms": "/mês",
"sign_up": "Escolha PRO",
"annual": "Anual",
"monthly": "Mensal"
},
"ie11Message": {
"heading": "O seu navegador é muito antigo",
"message": "Atualize o seu navegador de internet para a versão mais recente para usar o serviço mssg.me"
},
"blog": {
"title": "Blog | mssg.me",
"description": "Últimas notícias do mssg.me"
},
"single_article": {
"posts_section": {
"heading": "Você também pode gostar"
}
},
"http_error": {
"404": "Nada encontrado"
},
"404": {
"heading": "Erro 404",
"error": "A página não existe",
"button": "Visitar a página inicial"
},
"cookies": {
"message": "Nós utilizamos cookies",
"link": "Detalhes"
},
"top_pane": {
"message": "Todas as mensagens em um único aplicativo",
"button": "Detalhes"
},
"buttons": {
"getStarted": "Começar",
"getFreePage": "Obtenha sua página gratuita"
},
"promo": {
"black_friday": "Oferta da Black Friday 🔥 35% de desconto nos planos anuais!"
},
"website_home": {
"head": {
"title": "Forma fácil de criar um site",
"description": "Crie um site móvel, página com links ou loja online em minutos."
},
"common": {
"sign_up_cta": "Começar grátis",
"cookies": {
"message": "Nós utilizamos cookies",
"link": "Detalhes"
},
"terms": {
"terms": "Termos de uso",
"politics": "Política de privacidade"
},
"auth": {
"login": "Entrar",
"signup": "Cadastrar"
}
},
"home": {
"intro": {
"title": {
"1": "Seu site.",
"2": "Do seu jeito."
},
"description": "Crie um site móvel, página com links ou loja online em minutos."
},
"presentation": {
"title": "Crie um site para qualquer coisa.",
"description": "É simples. Sem programação. No seu celular."
},
"multi_link": {
"title": "LINKS MÚLTIPLOS",
"subtitle": "Adicione links ilimitados",
"description": "Conecte seguidores a todo o seu conteúdo com apenas um link. Adicione um link para o seu site na biografia do Instagram, TikTok ou outras redes sociais."
},
"messengers": {
"title": "MENSAGEIROS INSTANTÂNEOS",
"subtitle": "Forma fácil de entrar em contato com você",
"description": "Crie uma experiência de engajamento do cliente melhor, fornecendo uma forma rápida e conveniente de comunicação, para que eles possam entrar em contato com você facilmente em segundos."
},
"store": {
"title": "LOJA ONLINE",
"subtitle": "Comece a vender online",
"description": "Inicie uma bela loja online em minutos. Adicione seus produtos, categorias e comece a aceitar pagamentos. Gerencie pedidos em qualquer lugar com um simples sistema CRM integrado."
},
"builder": {
"title": "PÁGINA DE DESTINO",
"subtitle": "Crie um site personalizado",
"description": "Crie uma página de destino personalizada que você precisa. Construa seu site com ferramentas simples do seu jeito para você e seu negócio."
},
"features": {
"title": "Recursos incríveis",
"list": {
"domain": {
"title": "Domínio personalizado",
"description": "Conecte um domínio ao seu site e obtenha um certificado SSL gratuito."
},
"qr": {
"title": "Código QR",
"description": "Use o código QR integrado para o seu site para direcionar visitantes offline."
},
"analytics": {
"title": "Análises",
"description": "Obtenha informações úteis sobre visitas e cliques ou integre o Google Analytics, Facebook e TikTok pixels para obter mais dados."
}
}
},
"footer": {
"title": "Crie seu site em minutos",
"description": "Conte sua história. Venda produtos. Cresça seu negócio."
}
}
}
}

153
messages/ru.json Normal file
View File

@ -0,0 +1,153 @@
{
"Not Found": "Not Found",
"common": {
"and": "и",
"soon": "Скоро"
},
"menu": {
"subheading1": "Для роста",
"subheading2": "Управление",
"subheading3": "Ресурсы",
"subheading4": "Компания",
"platform": "Платформа",
"page": "Page",
"widget": "Widget",
"qr": "QR-код",
"pricing": "Тарифы",
"blog": "Блог",
"faq": "База знаний",
"terms": "Условия использования",
"privacy": "Политика конфиденциальности"
},
"button": {
"login": "Войти",
"trial": "Начать бесплатно",
"start": "Начать",
"get_started_for_free": "Начать бесплатно",
"try_trial": "Попробовать <br>бесплатно",
"view_faq": "База знаний",
"how_it_works": "Как это работает",
"more_about": "Узнать больше о"
},
"posts_section": {
"heading_line_1": "Простыми словами",
"heading_line_2": "о важных вещах"
},
"page_pricing": {
"terms": "/месяц",
"sign_up": "Выбрать PRO",
"annual": "За год",
"monthly": "Ежемесячно"
},
"blog": {
"title": "Блог | mssg.me",
"description": "Узнайте последние новости сервиса mssg.me"
},
"single_article": {
"posts_section": {
"heading": "Вам может быть интересно"
}
},
"ie11Message": {
"heading": "Ваш браузер устарел",
"message": "Обновите ваш браузер до последней версии, чтобы нормально пользоваться сервисом mssg.me "
},
"http_error": {
"404": "Ничего не найдено"
},
"404": {
"heading": "404 ошибка",
"error": "Страница не найдена",
"button": "Вернуться на главную"
},
"cookies": {
"message": "Мы используем cookies",
"link": "Детали"
},
"top_pane": {
"message": "Все сообщения в одном приложении",
"button": "Подробнее"
},
"buttons": {
"getStarted": "Начать",
"getFreePage": "Создать бесплатно"
},
"promo": {
"black_friday": "Черная пятница🔥 Скидка 35% при подписке на год!"
},
"website_home": {
"head": {
"title": "Простой способ создать свой сайт",
"description": "Создайте мобильный сайт, страницу с ссылками или онлайн магазин за минуты."
},
"common": {
"sign_up_cta": "Начать бесплатно",
"cookies": {
"message": "Мы используем cookies",
"link": "Детали"
},
"terms": {
"terms": "Условия использования",
"politics": "Политика конфиденциальности"
},
"auth": {
"login": "Войти",
"signup": "Начать"
}
},
"home": {
"intro": {
"title": {
"1": "Ваш веб-сайт.",
"2": "Ваши правила."
},
"description": "Создайте мобильный сайт, страницу с ссылками или онлайн магазин за минуты."
},
"presentation": {
"title": "Создайте сайт для чего угодно.",
"description": "Это просто. Без кода. На вашем телефоне."
},
"multi_link": {
"title": "МУЛЬТИССЫЛКА",
"subtitle": "Добавь много ссылок",
"description": "Покажите подписчикам весь ваш контент с помощью всего одной ссылки. Добавьте ссылку на свой сайт в био Instagram, TikTok или других соцетях."
},
"messengers": {
"title": "МЕССЕНДЖЕРЫ",
"subtitle": "Простой способ связи",
"description": "Улучшите взаимодействие с клиентами, предоставив быстрый и удобный способ связи, чтобы они смогли легко связаться с вами в считанные секунды."
},
"store": {
"title": "ИНТЕРНЕТ МАГАЗИН",
"subtitle": "Начните продавать онлайн",
"description": "Запустите красивый интернет-магазин за считанные минуты. Добавьте свои товары, категории и начните принимать платежи. Управляйте заказами на ходу с помощью простой встроенной CRM-системы."
},
"builder": {
"title": "МОБИЛЬНЫЙ ЛЕНДИНГ",
"subtitle": "Создайте уникальный сайт",
"description": "Создайте лендинг под ваши нужды с помощью простых инструментов, которые помогут вам и вашему бизнесу развиваться быстрее."
},
"features": {
"title": "Крутые функции",
"list": {
"domain": {
"title": "Свой домен",
"description": "Подключите домен к своему сайту и получите бесплатный SSL сертификат."
},
"qr": {
"title": "QR-код",
"description": "Используйте сгенерированый QR-код вашего сайта, чтобы привлекать клиентов из оффлайна."
},
"analytics": {
"title": "Аналитика",
"description": "Получайте полезные данные о посещениях и кликах. Или подключите Google Analytics, Facebook и TikTok pixel, чтобы иметь еще больше данных."
}
}
},
"footer": {
"title": "Создайте ваш сайт за минуты",
"description": "Расскажите историю. Продавайте товары. Взращивайте бизнес."
}
}
}
}

153
messages/th.json Normal file
View File

@ -0,0 +1,153 @@
{
"Not Found": "ไม่พบ",
"common": {
"and": "และ",
"soon": "เร็ว ๆ นี้"
},
"menu": {
"subheading1": "เครื่องมือการเติบโต",
"subheading2": "จัดการเครื่องมือ",
"subheading3": "ทรัพยากร",
"subheading4": "บริษัท",
"platform": "แพลตฟอร์ม",
"page": "หน้า",
"widget": "วิดเจ็ต",
"qr": "รหัส QR",
"pricing": "การตั้งราคา",
"blog": "บล็อก",
"faq": "คำถามที่พบบ่อย",
"terms": "ข้อกำหนดการใช้งาน",
"privacy": "นโยบายความเป็นส่วนตัว"
},
"button": {
"login": "เข้าสู่ระบบ",
"trial": "เริ่มฟรี",
"start": "เริ่มต้น",
"get_started_for_free": "เริ่มต้นฟรี",
"try_trial": "ลองฟรี",
"view_faq": "ดูคำถามที่พบบ่อย",
"how_it_works": "ดูวิธีการทำงาน",
"more_about": "เพิ่มเติมเกี่ยวกับ"
},
"posts_section": {
"heading_line_1": "สิ่งที่มีประโยชน์",
"heading_line_2": "ในคำง่าย ๆ"
},
"page_pricing": {
"terms": "/เดือน",
"sign_up": "สมัครตอนนี้",
"annual": "รายปี",
"monthly": "รายเดือน"
},
"ie11Message": {
"heading": "เบราว์เซอร์ของคุณเก่าเกินไป",
"message": "อัปเดตเบราว์เซอร์อินเทอร์เน็ตของคุณเป็นเวอร์ชันล่าสุดเพื่อใช้บริการ mssg.me"
},
"blog": {
"title": "บล็อก | mssg.me",
"description": "ข่าวล่าสุดจาก mssg.me"
},
"single_article": {
"posts_section": {
"heading": "คุณอาจชอบ"
}
},
"http_error": {
"404": "ไม่พบอะไร"
},
"404": {
"heading": "ข้อผิดพลาด 404",
"error": "หน้าไม่อยู่",
"button": "เยี่ยมชมหน้าแรก"
},
"cookies": {
"message": "เราใช้คุกกี้",
"link": "รายละเอียด"
},
"top_pane": {
"message": "ข้อความทั้งหมดในแอปเดียว",
"button": "รายละเอียด"
},
"buttons": {
"getStarted": "เริ่มต้น",
"getFreePage": "รับหน้าฟรีของคุณ"
},
"promo": {
"black_friday": "ข้อเสนอ Black Friday 🔥 ลด 35% สำหรับแผนรายปี!"
},
"website_home": {
"head": {
"title": "วิธีง่าย ๆ ในการสร้างเว็บไซต์",
"description": "สร้างเว็บไซต์มือถือ หน้าพร้อมลิงก์ หรือร้านค้าออนไลน์ในไม่กี่นาที"
},
"common": {
"sign_up_cta": "เริ่มต้นฟรี",
"cookies": {
"message": "เราใช้คุกกี้",
"link": "รายละเอียด"
},
"terms": {
"terms": "ข้อกำหนดการให้บริการ",
"politics": "นโยบายความเป็นส่วนตัว"
},
"auth": {
"login": "เข้าสู่ระบบ",
"signup": "สมัคร"
}
},
"home": {
"intro": {
"title": {
"1": "เว็บไซต์ของคุณ",
"2": "ในแบบของคุณ"
},
"description": "สร้างเว็บไซต์มือถือ หน้าพร้อมลิงก์ หรือร้านค้าออนไลน์ในไม่กี่นาที"
},
"presentation": {
"title": "สร้างเว็บไซต์สำหรับทุกสิ่ง",
"description": "มันง่าย ไม่มีการเขียนโค้ด บนโทรศัพท์ของคุณ"
},
"multi_link": {
"title": "ลิงก์หลายลิงก์",
"subtitle": "เพิ่มลิงก์ไม่จำกัด",
"description": "เชื่อมต่อผู้ติดตามกับเนื้อหาทั้งหมดของคุณด้วยลิงก์เดียว เพิ่มลิงก์ไปยังเว็บไซต์ของคุณใน Instagram bio, TikTok หรือเครือข่ายสังคมอื่น ๆ"
},
"messengers": {
"title": "ผู้ส่งสารทันที",
"subtitle": "วิธีง่าย ๆ ในการติดต่อคุณ",
"description": "สร้างประสบการณ์การมีส่วนร่วมของลูกค้าที่ดีขึ้นโดยให้วิธีการสื่อสารที่รวดเร็วและสะดวก เพื่อให้พวกเขาสามารถติดต่อคุณได้ในไม่กี่วินาที"
},
"store": {
"title": "ร้านค้าออนไลน์",
"subtitle": "เริ่มขายออนไลน์",
"description": "เปิดร้านค้าออนไลน์ที่สวยงามในไม่กี่นาที เพิ่มผลิตภัณฑ์ หมวดหมู่ และเริ่มรับชำระเงิน จัดการคำสั่งซื้อได้ทุกที่ด้วยระบบ CRM ที่ง่าย"
},
"builder": {
"title": "หน้าแลนดิ้ง",
"subtitle": "สร้างเว็บไซต์ที่กำหนดเอง",
"description": "สร้างหน้าแลนดิ้งที่กำหนดเองที่คุณต้องการ สร้างเว็บไซต์ของคุณด้วยเครื่องมือที่ง่ายในแบบของคุณสำหรับคุณและธุรกิจของคุณ"
},
"features": {
"title": "คุณสมบัติที่น่าทึ่ง",
"list": {
"domain": {
"title": "โดเมนที่กำหนดเอง",
"description": "เชื่อมต่อโดเมนกับเว็บไซต์ของคุณและรับใบรับรอง SSL ฟรี"
},
"qr": {
"title": "รหัส QR",
"description": "ใช้รหัส QR ที่สร้างขึ้นในตัวสำหรับเว็บไซต์ของคุณเพื่อดึงดูดผู้เข้าชมจากออฟไลน์"
},
"analytics": {
"title": "ข้อมูลเชิงลึก",
"description": "รับข้อมูลเชิงลึกที่เป็นประโยชน์เกี่ยวกับการเข้าชมและการคลิก หรือรวม Google Analytics, Facebook และ TikTok pixels เพื่อทราบข้อมูลเพิ่มเติม"
}
}
},
"footer": {
"title": "สร้างเว็บไซต์ของคุณในไม่กี่นาที",
"description": "บอกเล่าเรื่องราว ขายผลิตภัณฑ์ เติบโตธุรกิจ"
}
}
}
}

153
messages/uk.json Normal file
View File

@ -0,0 +1,153 @@
{
"Not Found": "Not Found",
"common": {
"and": "і",
"soon": "Скоро"
},
"menu": {
"subheading1": "Для розвитку",
"subheading2": "Управління",
"subheading3": "Ресурси",
"subheading4": "Компанія",
"platform": "Платформа",
"page": "Page",
"widget": "Widget",
"qr": "QR-код",
"pricing": "Тарифи",
"blog": "Блог",
"faq": "База знань",
"terms": "Умови використання",
"privacy": "Політика конфіденційності"
},
"button": {
"login": "Увійти",
"trial": "Почати безкоштовно",
"start": "Почати",
"get_started_for_free": "Почати безкоштовно",
"try_trial": "Спробувати <br>безкоштовно",
"view_faq": "База знань",
"how_it_works": "Як це працює",
"more_about": "Дізнатись більше про"
},
"posts_section": {
"heading_line_1": "Простими словами",
"heading_line_2": "про важливі речі"
},
"page_pricing": {
"terms": "/місяць",
"sign_up": "Обрати PRO",
"annual": "На рік",
"monthly": "Щомісяця"
},
"blog": {
"title": "Блог | mssg.me",
"description": "Дізнайтесь останні новини сервісу mssg.me"
},
"single_article": {
"posts_section": {
"heading": "Вам може бути цікаво"
}
},
"ie11Message": {
"heading": "Ваш браузер застарів",
"message": "Обновіть ваш браузер до останньої версії, щоб скористатися сервісом mssg.me "
},
"http_error": {
"404": "Нічого не знайдено"
},
"404": {
"heading": "404 помилка",
"error": "Сторінку не знайдено",
"button": "Повернутися на головну"
},
"cookies": {
"message": "Ми використовуємо cookies",
"link": "Деталі"
},
"top_pane": {
"message": "Всі повідомлення в одному застосунку",
"button": "Детальніше"
},
"buttons": {
"getStarted": "Почати",
"getFreePage": "Створити безкоштовно"
},
"promo": {
"black_friday": "Чорна п'ятниця 🔥 Знижка 35% при підписці на рік!"
},
"website_home": {
"head": {
"title": "Простий спосіб створити свій сайт",
"description": "Створіть мобільний сайт, сторінку з лінками або онлайн магазин за хвилини."
},
"common": {
"sign_up_cta": "Почати безкоштовно",
"cookies": {
"message": "Ми використовуємо cookies",
"link": "Деталі"
},
"terms": {
"terms": "Умови використання",
"politics": "Політика конфіденційності"
},
"auth": {
"login": "Увійти",
"signup": "Почати"
}
},
"home": {
"intro": {
"title": {
"1": "Ваш веб-сайт.",
"2": "Ваші правила."
},
"description": "Створіть мобільний сайт, сторінку з лінками або онлайн магазин за хвилини."
},
"presentation": {
"title": "Створіть сайт для чого завгодно.",
"description": "Це просто. Без коду. У вашому смартфоні."
},
"multi_link": {
"title": "МУЛЬТИЛІНК",
"subtitle": "Додайте багато лінків",
"description": "Покажіть підписникам увесь ваш контент за допомогою всього одного лінку. Додайте лінк свого сайту у біо Instagram, TikTok або у інших соцмережах."
},
"messengers": {
"title": "МЕСЕНДЖЕРИ",
"subtitle": "Простий спосіб зв'язку",
"description": "Покращіть взаємодію з клієнтами, надавши швидкий та зручний спосіб зв'язку, щоб вони змогли легко зв'язатися з вами за лічені секунди."
},
"store": {
"title": "ІНТЕРНЕТ МАГАЗИН",
"subtitle": "Почніть продавати онлайн",
"description": "Запустіть красивий інтернет-магазин за лічені хвилини. Додайте свої товари, категорії і почніть приймати платежі. Керуйте замовленнями на ходу за допомогою простої CRM-системи."
},
"builder": {
"title": "МОБІЛЬНИЙ ЛЕНДІНГ",
"subtitle": "Створіть унікальний сайт",
"description": "Створіть лендінг під ваші потреби за допомогою простих інструментів, котрі допоможуть вам і вашому бізнесу розвиватися швидше."
},
"features": {
"title": "Круті функції",
"list": {
"domain": {
"title": "Свій домен",
"description": "Підключіть домен до свого сайту і отримайте безкоштовний SSL сертифікат."
},
"qr": {
"title": "QR-код",
"description": "Використовуйте згенерований QR-код вашого сайту, щоб залучати клієнтів з офлайну."
},
"analytics": {
"title": "Аналітика",
"description": "Отримуйте корисні дані про перегляди та кліки. Або підключіть Google Analytics, Facebook і TikTok pixel, щоб мати ще більше даних."
}
}
},
"footer": {
"title": "Створіть ваш сайт за хвилини",
"description": "Розкажіть історію. Продавайте товари. Розвивайте бізнес."
}
}
}
}

View File

@ -1,7 +1,8 @@
import './env-setup';
import type { NextConfig } from "next"; import type { NextConfig } from "next";
import createNextIntlPlugin from 'next-intl/plugin';
const nextConfig: NextConfig = { const nextConfig: NextConfig = {};
/* config options here */
};
export default nextConfig; const withNextIntl = createNextIntlPlugin();
export default withNextIntl(nextConfig);

View File

@ -9,17 +9,26 @@
"lint": "next lint" "lint": "next lint"
}, },
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-svg-core": "^6.7.2",
"@fortawesome/free-brands-svg-icons": "^6.7.2",
"@fortawesome/free-solid-svg-icons": "^6.7.2",
"@fortawesome/react-fontawesome": "^0.2.2",
"clsx": "^2.1.1",
"dotenv-defaults": "^5.0.2",
"lax.js": "^2.0.3",
"next": "15.3.2",
"next-intl": "^4.1.0",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0", "react-dom": "^19.0.0"
"next": "15.3.2"
}, },
"devDependencies": { "devDependencies": {
"typescript": "^5", "@eslint/eslintrc": "^3",
"@types/dotenv-defaults": "^2.0.4",
"@types/node": "^20", "@types/node": "^20",
"@types/react": "^19", "@types/react": "^19",
"@types/react-dom": "^19", "@types/react-dom": "^19",
"eslint": "^9", "eslint": "^9",
"eslint-config-next": "15.3.2", "eslint-config-next": "15.3.2",
"@eslint/eslintrc": "^3" "typescript": "^5"
} }
} }

View File

@ -8,9 +8,33 @@ importers:
.: .:
dependencies: dependencies:
'@fortawesome/fontawesome-svg-core':
specifier: ^6.7.2
version: 6.7.2
'@fortawesome/free-brands-svg-icons':
specifier: ^6.7.2
version: 6.7.2
'@fortawesome/free-solid-svg-icons':
specifier: ^6.7.2
version: 6.7.2
'@fortawesome/react-fontawesome':
specifier: ^0.2.2
version: 0.2.2(@fortawesome/fontawesome-svg-core@6.7.2)(react@19.1.0)
clsx:
specifier: ^2.1.1
version: 2.1.1
dotenv-defaults:
specifier: ^5.0.2
version: 5.0.2
lax.js:
specifier: ^2.0.3
version: 2.0.3
next: next:
specifier: 15.3.2 specifier: 15.3.2
version: 15.3.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0) version: 15.3.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
next-intl:
specifier: ^4.1.0
version: 4.1.0(next@15.3.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(typescript@5.8.3)
react: react:
specifier: ^19.0.0 specifier: ^19.0.0
version: 19.1.0 version: 19.1.0
@ -21,6 +45,9 @@ importers:
'@eslint/eslintrc': '@eslint/eslintrc':
specifier: ^3 specifier: ^3
version: 3.3.1 version: 3.3.1
'@types/dotenv-defaults':
specifier: ^2.0.4
version: 2.0.4
'@types/node': '@types/node':
specifier: ^20 specifier: ^20
version: 20.17.50 version: 20.17.50
@ -89,6 +116,46 @@ packages:
resolution: {integrity: sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==} resolution: {integrity: sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@formatjs/ecma402-abstract@2.3.4':
resolution: {integrity: sha512-qrycXDeaORzIqNhBOx0btnhpD1c+/qFIHAN9znofuMJX6QBwtbrmlpWfD4oiUUD2vJUOIYFA/gYtg2KAMGG7sA==}
'@formatjs/fast-memoize@2.2.7':
resolution: {integrity: sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ==}
'@formatjs/icu-messageformat-parser@2.11.2':
resolution: {integrity: sha512-AfiMi5NOSo2TQImsYAg8UYddsNJ/vUEv/HaNqiFjnI3ZFfWihUtD5QtuX6kHl8+H+d3qvnE/3HZrfzgdWpsLNA==}
'@formatjs/icu-skeleton-parser@1.8.14':
resolution: {integrity: sha512-i4q4V4qslThK4Ig8SxyD76cp3+QJ3sAqr7f6q9VVfeGtxG9OhiAk3y9XF6Q41OymsKzsGQ6OQQoJNY4/lI8TcQ==}
'@formatjs/intl-localematcher@0.5.10':
resolution: {integrity: sha512-af3qATX+m4Rnd9+wHcjJ4w2ijq+rAVP3CCinJQvFv1kgSu1W6jypUmvleJxcewdxmutM8dmIRZFxO/IQBZmP2Q==}
'@formatjs/intl-localematcher@0.6.1':
resolution: {integrity: sha512-ePEgLgVCqi2BBFnTMWPfIghu6FkbZnnBVhO2sSxvLfrdFw7wCHAHiDoM2h4NRgjbaY7+B7HgOLZGkK187pZTZg==}
'@fortawesome/fontawesome-common-types@6.7.2':
resolution: {integrity: sha512-Zs+YeHUC5fkt7Mg1l6XTniei3k4bwG/yo3iFUtZWd/pMx9g3fdvkSK9E0FOC+++phXOka78uJcYb8JaFkW52Xg==}
engines: {node: '>=6'}
'@fortawesome/fontawesome-svg-core@6.7.2':
resolution: {integrity: sha512-yxtOBWDrdi5DD5o1pmVdq3WMCvnobT0LU6R8RyyVXPvFRd2o79/0NCuQoCjNTeZz9EzA9xS3JxNWfv54RIHFEA==}
engines: {node: '>=6'}
'@fortawesome/free-brands-svg-icons@6.7.2':
resolution: {integrity: sha512-zu0evbcRTgjKfrr77/2XX+bU+kuGfjm0LbajJHVIgBWNIDzrhpRxiCPNT8DW5AdmSsq7Mcf9D1bH0aSeSUSM+Q==}
engines: {node: '>=6'}
'@fortawesome/free-solid-svg-icons@6.7.2':
resolution: {integrity: sha512-GsBrnOzU8uj0LECDfD5zomZJIjrPhIlWU82AHwa2s40FKH+kcxQaBvBo3Z4TxyZHIyX8XTDxsyA33/Vx9eFuQA==}
engines: {node: '>=6'}
'@fortawesome/react-fontawesome@0.2.2':
resolution: {integrity: sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==}
peerDependencies:
'@fortawesome/fontawesome-svg-core': ~1 || ~6
react: '>=16.3'
'@humanfs/core@0.19.1': '@humanfs/core@0.19.1':
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
engines: {node: '>=18.18.0'} engines: {node: '>=18.18.0'}
@ -304,6 +371,9 @@ packages:
'@rushstack/eslint-patch@1.11.0': '@rushstack/eslint-patch@1.11.0':
resolution: {integrity: sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ==} resolution: {integrity: sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ==}
'@schummar/icu-type-parser@1.21.5':
resolution: {integrity: sha512-bXHSaW5jRTmke9Vd0h5P7BtWZG9Znqb8gSDxZnxaGSJnGwPLDPfS+3g0BKzeWqzgZPsIVZkM7m2tbo18cm5HBw==}
'@swc/counter@0.1.3': '@swc/counter@0.1.3':
resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
@ -313,6 +383,9 @@ packages:
'@tybys/wasm-util@0.9.0': '@tybys/wasm-util@0.9.0':
resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==}
'@types/dotenv-defaults@2.0.4':
resolution: {integrity: sha512-+KwZaAMQkt0uk5IH3F2zqjUsZqEi8ro0qEpi4dnYwpNfG3Mejf3PlCQooqMrICWkSg3gq9jgFCeAwFrbhDQmbQ==}
'@types/estree@1.0.7': '@types/estree@1.0.7':
resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==}
@ -583,6 +656,10 @@ packages:
client-only@0.0.1: client-only@0.0.1:
resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
clsx@2.1.1:
resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
engines: {node: '>=6'}
color-convert@2.0.1: color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'} engines: {node: '>=7.0.0'}
@ -639,6 +716,9 @@ packages:
supports-color: supports-color:
optional: true optional: true
decimal.js@10.5.0:
resolution: {integrity: sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==}
deep-is@0.1.4: deep-is@0.1.4:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
@ -658,6 +738,17 @@ packages:
resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dotenv-defaults@5.0.2:
resolution: {integrity: sha512-y5z4NhblzwNk8XBIYVzjLcFkANK0rxbRDO6kGOfH9QrVYIGVEX52IqwSprKVsaLHM9pnNkCSxazZF/JPydDPvA==}
dotenv@14.3.2:
resolution: {integrity: sha512-vwEppIphpFdvaMCaHfCEv9IgwcxMljMw2TnAQBB4VWPvzXQLTb82jwmdOKzlEVUL3gNFT4l4TPKO+Bn+sqcrVQ==}
engines: {node: '>=12'}
dotenv@8.6.0:
resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==}
engines: {node: '>=10'}
dunder-proto@1.0.1: dunder-proto@1.0.1:
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -963,6 +1054,9 @@ packages:
resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
intl-messageformat@10.7.16:
resolution: {integrity: sha512-UmdmHUmp5CIKKjSoE10la5yfU+AYJAaiYLsodbjL4lji83JNvgOQUjGaGhGrpFCb0Uh7sl7qfP1IyILa8Z40ug==}
is-array-buffer@3.0.5: is-array-buffer@3.0.5:
resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -1109,6 +1203,9 @@ packages:
resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==}
engines: {node: '>=0.10'} engines: {node: '>=0.10'}
lax.js@2.0.3:
resolution: {integrity: sha512-q2q0jVRwruvFdQZeeE3OwIszRIkey6CItPmB+BcTUFPgHd2R8LI+bntAI7d2GJEjheu79mzQ++MROkODuZoXlA==}
levn@0.4.1: levn@0.4.1:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
@ -1162,6 +1259,20 @@ packages:
natural-compare@1.4.0: natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
negotiator@1.0.0:
resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==}
engines: {node: '>= 0.6'}
next-intl@4.1.0:
resolution: {integrity: sha512-JNJRjc7sdnfUxhZmGcvzDszZ60tQKrygV/VLsgzXhnJDxQPn1cN2rVpc53adA1SvBJwPK2O6Sc6b4gYSILjCzw==}
peerDependencies:
next: ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0
typescript: ^5.0.0
peerDependenciesMeta:
typescript:
optional: true
next@15.3.2: next@15.3.2:
resolution: {integrity: sha512-CA3BatMyHkxZ48sgOCLdVHjFU36N7TF1HhqAHLFOkV6buwZnvMI84Cug8xD56B9mCuKrqXnLn94417GrZ/jjCQ==} resolution: {integrity: sha512-CA3BatMyHkxZ48sgOCLdVHjFU36N7TF1HhqAHLFOkV6buwZnvMI84Cug8xD56B9mCuKrqXnLn94417GrZ/jjCQ==}
engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
@ -1510,6 +1621,11 @@ packages:
uri-js@4.4.1: uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
use-intl@4.1.0:
resolution: {integrity: sha512-mQvDYFvoGn+bm/PWvlQOtluKCknsQ5a9F1Cj0hMfBjMBVTwnOqLPd6srhjvVdEQEQFVyHM1PfyifKqKYb11M9Q==}
peerDependencies:
react: ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0
which-boxed-primitive@1.1.1: which-boxed-primitive@1.1.1:
resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -1601,6 +1717,56 @@ snapshots:
'@eslint/core': 0.14.0 '@eslint/core': 0.14.0
levn: 0.4.1 levn: 0.4.1
'@formatjs/ecma402-abstract@2.3.4':
dependencies:
'@formatjs/fast-memoize': 2.2.7
'@formatjs/intl-localematcher': 0.6.1
decimal.js: 10.5.0
tslib: 2.8.1
'@formatjs/fast-memoize@2.2.7':
dependencies:
tslib: 2.8.1
'@formatjs/icu-messageformat-parser@2.11.2':
dependencies:
'@formatjs/ecma402-abstract': 2.3.4
'@formatjs/icu-skeleton-parser': 1.8.14
tslib: 2.8.1
'@formatjs/icu-skeleton-parser@1.8.14':
dependencies:
'@formatjs/ecma402-abstract': 2.3.4
tslib: 2.8.1
'@formatjs/intl-localematcher@0.5.10':
dependencies:
tslib: 2.8.1
'@formatjs/intl-localematcher@0.6.1':
dependencies:
tslib: 2.8.1
'@fortawesome/fontawesome-common-types@6.7.2': {}
'@fortawesome/fontawesome-svg-core@6.7.2':
dependencies:
'@fortawesome/fontawesome-common-types': 6.7.2
'@fortawesome/free-brands-svg-icons@6.7.2':
dependencies:
'@fortawesome/fontawesome-common-types': 6.7.2
'@fortawesome/free-solid-svg-icons@6.7.2':
dependencies:
'@fortawesome/fontawesome-common-types': 6.7.2
'@fortawesome/react-fontawesome@0.2.2(@fortawesome/fontawesome-svg-core@6.7.2)(react@19.1.0)':
dependencies:
'@fortawesome/fontawesome-svg-core': 6.7.2
prop-types: 15.8.1
react: 19.1.0
'@humanfs/core@0.19.1': {} '@humanfs/core@0.19.1': {}
'@humanfs/node@0.16.6': '@humanfs/node@0.16.6':
@ -1750,6 +1916,8 @@ snapshots:
'@rushstack/eslint-patch@1.11.0': {} '@rushstack/eslint-patch@1.11.0': {}
'@schummar/icu-type-parser@1.21.5': {}
'@swc/counter@0.1.3': {} '@swc/counter@0.1.3': {}
'@swc/helpers@0.5.15': '@swc/helpers@0.5.15':
@ -1761,6 +1929,11 @@ snapshots:
tslib: 2.8.1 tslib: 2.8.1
optional: true optional: true
'@types/dotenv-defaults@2.0.4':
dependencies:
'@types/node': 20.17.50
dotenv: 8.6.0
'@types/estree@1.0.7': {} '@types/estree@1.0.7': {}
'@types/json-schema@7.0.15': {} '@types/json-schema@7.0.15': {}
@ -2054,6 +2227,8 @@ snapshots:
client-only@0.0.1: {} client-only@0.0.1: {}
clsx@2.1.1: {}
color-convert@2.0.1: color-convert@2.0.1:
dependencies: dependencies:
color-name: 1.1.4 color-name: 1.1.4
@ -2110,6 +2285,8 @@ snapshots:
dependencies: dependencies:
ms: 2.1.3 ms: 2.1.3
decimal.js@10.5.0: {}
deep-is@0.1.4: {} deep-is@0.1.4: {}
define-data-property@1.1.4: define-data-property@1.1.4:
@ -2131,6 +2308,14 @@ snapshots:
dependencies: dependencies:
esutils: 2.0.3 esutils: 2.0.3
dotenv-defaults@5.0.2:
dependencies:
dotenv: 14.3.2
dotenv@14.3.2: {}
dotenv@8.6.0: {}
dunder-proto@1.0.1: dunder-proto@1.0.1:
dependencies: dependencies:
call-bind-apply-helpers: 1.0.2 call-bind-apply-helpers: 1.0.2
@ -2587,6 +2772,13 @@ snapshots:
hasown: 2.0.2 hasown: 2.0.2
side-channel: 1.1.0 side-channel: 1.1.0
intl-messageformat@10.7.16:
dependencies:
'@formatjs/ecma402-abstract': 2.3.4
'@formatjs/fast-memoize': 2.2.7
'@formatjs/icu-messageformat-parser': 2.11.2
tslib: 2.8.1
is-array-buffer@3.0.5: is-array-buffer@3.0.5:
dependencies: dependencies:
call-bind: 1.0.8 call-bind: 1.0.8
@ -2745,6 +2937,8 @@ snapshots:
dependencies: dependencies:
language-subtag-registry: 0.3.23 language-subtag-registry: 0.3.23
lax.js@2.0.3: {}
levn@0.4.1: levn@0.4.1:
dependencies: dependencies:
prelude-ls: 1.2.1 prelude-ls: 1.2.1
@ -2787,6 +2981,18 @@ snapshots:
natural-compare@1.4.0: {} natural-compare@1.4.0: {}
negotiator@1.0.0: {}
next-intl@4.1.0(next@15.3.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(typescript@5.8.3):
dependencies:
'@formatjs/intl-localematcher': 0.5.10
negotiator: 1.0.0
next: 15.3.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
react: 19.1.0
use-intl: 4.1.0(react@19.1.0)
optionalDependencies:
typescript: 5.8.3
next@15.3.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0): next@15.3.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
dependencies: dependencies:
'@next/env': 15.3.2 '@next/env': 15.3.2
@ -3246,6 +3452,13 @@ snapshots:
dependencies: dependencies:
punycode: 2.3.1 punycode: 2.3.1
use-intl@4.1.0(react@19.1.0):
dependencies:
'@formatjs/fast-memoize': 2.2.7
'@schummar/icu-type-parser': 1.21.5
intl-messageformat: 10.7.16
react: 19.1.0
which-boxed-primitive@1.1.1: which-boxed-primitive@1.1.1:
dependencies: dependencies:
is-bigint: 1.1.0 is-bigint: 1.1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1,37 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="2085.000000pt" height="2085.000000pt" viewBox="0 0 2085.000000 2085.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.11, written by Peter Selinger 2001-2013
</metadata>
<g transform="translate(0.000000,2085.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M3810 20839 c-1253 -93 -2390 -751 -3099 -1794 -367 -539 -588 -1134
-678 -1820 -17 -134 -18 -413 -18 -6795 0 -6382 1 -6661 18 -6795 125 -961
518 -1766 1189 -2434 657 -655 1496 -1055 2448 -1168 149 -17 420 -18 6755
-18 6335 0 6606 1 6755 18 795 94 1502 383 2105 861 853 677 1389 1632 1532
2731 17 134 18 419 18 6805 0 6386 -1 6671 -18 6805 -143 1100 -679 2055
-1532 2730 -650 516 -1420 812 -2270 875 -173 12 -13033 11 -13205 -1z m6735
-3044 c136 -29 293 -124 380 -231 59 -73 98 -144 132 -239 l28 -80 0 -3470 0
-3470 -28 -80 c-106 -300 -359 -485 -662 -485 -321 0 -595 217 -675 534 -20
78 -20 116 -20 3501 0 3385 0 3423 20 3501 53 212 194 381 392 474 124 58 290
75 433 45z m-2773 -954 c239 -61 418 -232 500 -477 l23 -69 0 -3470 0 -3470
-23 -70 c-137 -409 -576 -608 -954 -432 -178 83 -306 226 -375 423 l-28 79 0
3470 0 3470 28 80 c70 196 192 335 373 422 134 64 311 81 456 44z m5580 -950
c237 -61 419 -238 505 -491 17 -53 18 -178 21 -3490 2 -3030 1 -3444 -13
-3510 -18 -91 -87 -235 -148 -309 -204 -245 -551 -321 -832 -182 -152 76 -252
176 -325 326 -76 156 -70 -176 -70 3641 0 3360 0 3432 19 3506 63 247 259 444
503 508 99 26 241 26 340 1z m-8358 -1426 c192 -50 363 -194 451 -380 70 -149
65 91 65 -2886 0 -2683 3 -2936 36 -3188 154 -1200 793 -2239 1774 -2886 184
-122 350 -214 528 -295 1014 -459 2132 -474 3137 -42 77 33 1477 718 3110
1522 1634 804 3008 1476 3054 1492 322 114 688 -41 841 -357 52 -106 70 -187
70 -316 0 -207 -65 -365 -209 -509 -75 -75 -102 -94 -206 -147 -408 -206
-6042 -2970 -6140 -3011 -471 -199 -981 -331 -1505 -387 -204 -22 -646 -30
-860 -16 -1307 88 -2497 630 -3424 1557 -814 815 -1367 1920 -1535 3069 -59
407 -56 200 -56 3350 l0 2880 27 80 c74 217 244 390 453 460 111 37 270 41
389 10z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1 +0,0 @@
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>

Before

Width:  |  Height:  |  Size: 391 B

View File

@ -1 +0,0 @@
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="101.996" height="102" viewBox="0 0 101.996 102"><defs><radialGradient id="a" cx="13.551" cy="102.482" r="133.147" gradientUnits="userSpaceOnUse"><stop offset=".09" stop-color="#fa8f21"/><stop offset=".78" stop-color="#d82d7e"/></radialGradient><radialGradient id="b" cx="61.859" cy="107.051" r="104.938" gradientUnits="userSpaceOnUse"><stop offset=".64" stop-color="#8c3aaa" stop-opacity="0"/><stop offset="1" stop-color="#8c3aaa"/></radialGradient></defs><path fill="url(#a)" d="M34,51A17,17,0,1,1,51,68,17,17,0,0,1,34,51m-9.191,0A26.188,26.188,0,1,0,51,24.812,26.187,26.187,0,0,0,24.812,51M72.1,23.774a6.12,6.12,0,1,0,6.122-6.118h0a6.123,6.123,0,0,0-6.12,6.118M30.4,92.513a28.187,28.187,0,0,1-9.471-1.754,15.85,15.85,0,0,1-5.866-3.815,15.735,15.735,0,0,1-3.815-5.862A28.161,28.161,0,0,1,9.49,71.611c-.247-5.376-.3-6.991-.3-20.61s.053-15.23.3-20.61a28.374,28.374,0,0,1,1.754-9.471,15.85,15.85,0,0,1,3.815-5.866,15.718,15.718,0,0,1,5.866-3.815A28.161,28.161,0,0,1,30.4,9.484c5.376-.247,6.991-.3,20.6-.3s15.23.053,20.61.3a28.373,28.373,0,0,1,9.471,1.754,15.8,15.8,0,0,1,5.866,3.815,15.8,15.8,0,0,1,3.815,5.866,28.162,28.162,0,0,1,1.754,9.471c.247,5.38.3,6.991.3,20.61s-.049,15.23-.3,20.61a28.294,28.294,0,0,1-1.754,9.471,16.886,16.886,0,0,1-9.681,9.677,28.161,28.161,0,0,1-9.471,1.754c-5.376.247-6.991.3-20.61.3s-15.23-.049-20.6-.3M29.974.309A37.4,37.4,0,0,0,17.595,2.678,25.015,25.015,0,0,0,8.56,8.56a24.918,24.918,0,0,0-5.883,9.034A37.407,37.407,0,0,0,.309,29.974C.058,35.412,0,37.15,0,51S.058,66.588.309,72.026A37.405,37.405,0,0,0,2.678,84.405,24.931,24.931,0,0,0,8.56,93.44a25.076,25.076,0,0,0,9.034,5.883,37.43,37.43,0,0,0,12.379,2.369c5.441.247,7.176.309,21.026.309s15.588-.058,21.026-.309a37.405,37.405,0,0,0,12.379-2.369A26.075,26.075,0,0,0,99.322,84.405a37.3,37.3,0,0,0,2.369-12.379c.247-5.442.3-7.176.3-21.026s-.058-15.588-.3-21.026a37.394,37.394,0,0,0-2.369-12.379A25.08,25.08,0,0,0,93.44,8.56a24.955,24.955,0,0,0-9.03-5.883A37.347,37.347,0,0,0,72.03.309C66.593.062,64.854,0,51,0s-15.59.058-21.03.309" data-name="Path 14"/><path fill="url(#b)" d="M34,51A17,17,0,1,1,51,68,17,17,0,0,1,34,51m-9.191,0A26.188,26.188,0,1,0,51,24.812,26.187,26.187,0,0,0,24.812,51M72.1,23.774a6.12,6.12,0,1,0,6.122-6.118h0a6.123,6.123,0,0,0-6.12,6.118M30.4,92.513a28.187,28.187,0,0,1-9.471-1.754,15.85,15.85,0,0,1-5.866-3.815,15.735,15.735,0,0,1-3.815-5.862A28.161,28.161,0,0,1,9.49,71.611c-.247-5.376-.3-6.991-.3-20.61s.053-15.23.3-20.61a28.374,28.374,0,0,1,1.754-9.471,15.85,15.85,0,0,1,3.815-5.866,15.718,15.718,0,0,1,5.866-3.815A28.161,28.161,0,0,1,30.4,9.484c5.376-.247,6.991-.3,20.6-.3s15.23.053,20.61.3a28.373,28.373,0,0,1,9.471,1.754,15.8,15.8,0,0,1,5.866,3.815,15.8,15.8,0,0,1,3.815,5.866,28.162,28.162,0,0,1,1.754,9.471c.247,5.38.3,6.991.3,20.61s-.049,15.23-.3,20.61a28.294,28.294,0,0,1-1.754,9.471,16.886,16.886,0,0,1-9.681,9.677,28.161,28.161,0,0,1-9.471,1.754c-5.376.247-6.991.3-20.61.3s-15.23-.049-20.6-.3M29.974.309A37.4,37.4,0,0,0,17.595,2.678,25.015,25.015,0,0,0,8.56,8.56a24.918,24.918,0,0,0-5.883,9.034A37.407,37.407,0,0,0,.309,29.974C.058,35.412,0,37.15,0,51S.058,66.588.309,72.026A37.405,37.405,0,0,0,2.678,84.405,24.931,24.931,0,0,0,8.56,93.44a25.076,25.076,0,0,0,9.034,5.883,37.43,37.43,0,0,0,12.379,2.369c5.441.247,7.176.309,21.026.309s15.588-.058,21.026-.309a37.405,37.405,0,0,0,12.379-2.369A26.075,26.075,0,0,0,99.322,84.405a37.3,37.3,0,0,0,2.369-12.379c.247-5.442.3-7.176.3-21.026s-.058-15.588-.3-21.026a37.394,37.394,0,0,0-2.369-12.379A25.08,25.08,0,0,0,93.44,8.56a24.955,24.955,0,0,0-9.03-5.883A37.347,37.347,0,0,0,72.03.309C66.593.062,64.854,0,51,0s-15.59.058-21.03.309" data-name="Path 15"/></svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@ -0,0 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="256" height="256" viewBox="0 0 256 256" xml:space="preserve">
<desc>Created with Fabric.js 1.7.22</desc>
<defs>
</defs>
<g transform="translate(128 128) scale(0.72 0.72)" style="">
<g style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: none; fill-rule: nonzero; opacity: 1;" transform="translate(-175.05 -175.05000000000004) scale(3.89 3.89)" >
<path d="M 36.203 35.438 v -3.51 c -1.218 -0.173 -2.447 -0.262 -3.677 -0.268 c -15.047 0 -27.289 12.244 -27.289 27.291 c 0 9.23 4.613 17.401 11.65 22.342 c -4.712 -5.039 -7.332 -11.681 -7.328 -18.58 C 9.559 47.88 21.453 35.784 36.203 35.438" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(0,242,234); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
<path d="M 36.847 75.175 c 6.714 0 12.19 -5.341 12.44 -11.997 l 0.023 -59.417 h 10.855 c -0.232 -1.241 -0.349 -2.5 -0.35 -3.762 H 44.989 l -0.025 59.419 c -0.247 6.654 -5.726 11.993 -12.438 11.993 c -2.015 0.001 -4 -0.49 -5.782 -1.431 C 29.079 73.238 32.839 75.171 36.847 75.175 M 80.441 23.93 v -3.302 c -3.989 0.004 -7.893 -1.157 -11.232 -3.339 c 2.928 3.371 6.869 5.701 11.234 6.641" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(0,242,234); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
<path d="M 69.209 17.286 c -3.272 -3.744 -5.075 -8.549 -5.073 -13.522 h -3.972 C 61.203 9.318 64.472 14.205 69.209 17.286 M 32.526 46.486 c -6.88 0.008 -12.455 5.583 -12.463 12.463 c 0.004 4.632 2.576 8.88 6.679 11.032 c -1.533 -2.114 -2.358 -4.657 -2.358 -7.268 c 0.007 -6.88 5.582 -12.457 12.463 -12.465 c 1.284 0 2.515 0.212 3.677 0.577 V 35.689 c -1.218 -0.173 -2.447 -0.262 -3.677 -0.268 c -0.216 0 -0.429 0.012 -0.643 0.016 v 11.626 C 35.014 46.685 33.774 46.49 32.526 46.486" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(255,0,79); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
<path d="M 80.441 23.93 v 11.523 c -7.689 0 -14.81 -2.459 -20.627 -6.633 v 30.13 c 0 15.047 -12.24 27.289 -27.287 27.289 c -5.815 0 -11.207 -1.835 -15.639 -4.947 c 5.151 5.555 12.384 8.711 19.959 8.709 c 15.047 0 27.289 -12.242 27.289 -27.287 v -30.13 c 6.009 4.321 13.226 6.642 20.627 6.633 V 24.387 c -1.484 0 -2.927 -0.161 -4.323 -0.46" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(255,0,79); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
<path d="M 59.813 58.949 v -30.13 c 6.009 4.322 13.226 6.642 20.627 6.633 V 23.93 c -4.364 -0.941 -8.305 -3.272 -11.232 -6.644 c -4.737 -3.081 -8.006 -7.968 -9.045 -13.522 H 49.309 l -0.023 59.417 c -0.249 6.654 -5.726 11.995 -12.44 11.995 c -4.007 -0.004 -7.768 -1.938 -10.102 -5.194 c -4.103 -2.151 -6.676 -6.399 -6.681 -11.032 c 0.008 -6.88 5.583 -12.455 12.463 -12.463 c 1.282 0 2.513 0.21 3.677 0.577 V 35.438 C 21.453 35.784 9.559 47.88 9.559 62.713 c 0 7.173 2.787 13.703 7.328 18.58 c 4.578 3.223 10.041 4.95 15.639 4.945 C 47.574 86.238 59.813 73.996 59.813 58.949" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#03A9F4" d="M16 3.539a6.839 6.839 0 0 1-1.89.518 3.262 3.262 0 0 0 1.443-1.813 6.555 6.555 0 0 1-2.08.794 3.28 3.28 0 0 0-5.674 2.243c0 .26.022.51.076.748a9.284 9.284 0 0 1-6.761-3.431 3.285 3.285 0 0 0 1.008 4.384A3.24 3.24 0 0 1 .64 6.578v.036a3.295 3.295 0 0 0 2.628 3.223 3.274 3.274 0 0 1-.86.108 2.9 2.9 0 0 1-.621-.056 3.311 3.311 0 0 0 3.065 2.285 6.59 6.59 0 0 1-4.067 1.399c-.269 0-.527-.012-.785-.045A9.234 9.234 0 0 0 5.032 15c6.036 0 9.336-5 9.336-9.334 0-.145-.005-.285-.012-.424A6.544 6.544 0 0 0 16 3.539z"/></svg>

After

Width:  |  Height:  |  Size: 602 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="2500" height="1756" viewBox="5.368 13.434 53.9 37.855"><path fill="#FFF" d="M41.272 31.81c-4.942-2.641-9.674-5.069-14.511-7.604v15.165c5.09-2.767 10.455-5.301 14.532-7.561h-.021z"/><path fill="#E8E0E0" d="M41.272 31.81c-4.942-2.641-14.511-7.604-14.511-7.604l12.758 8.575c.001 0-2.324 1.289 1.753-.971z"/><path fill="#FF001C" d="M27.691 51.242c-10.265-.189-13.771-.359-15.926-.803-1.458-.295-2.725-.95-3.654-1.9-.718-.719-1.289-1.816-1.732-3.338-.38-1.268-.528-2.323-.739-4.9-.323-5.816-.4-10.571 0-15.884.33-2.934.49-6.417 2.682-8.449 1.035-.951 2.239-1.563 3.591-1.816 2.112-.401 11.11-.718 20.425-.718 9.294 0 18.312.317 20.426.718 1.689.317 3.273 1.267 4.203 2.492 2 3.146 2.035 7.058 2.238 10.118.084 1.458.084 9.737 0 11.195-.316 4.836-.57 6.547-1.288 8.321-.444 1.12-.823 1.711-1.479 2.366a7.085 7.085 0 0 1-3.76 1.922c-8.883.668-16.426.813-24.987.676zM41.294 31.81c-4.942-2.641-9.674-5.09-14.511-7.625v15.166c5.09-2.767 10.456-5.302 14.532-7.562l-.021.021z"/></svg>

After

Width:  |  Height:  |  Size: 1020 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +1,151 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg10"
width="824"
height="100"
viewBox="0 0 824 100"
sodipodi:docname="Logo for Google for Startups page.svg"
inkscape:version="1.0 (4035a4f, 2020-05-01)">
<metadata
id="metadata16">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs14">
<rect
id="rect3077"
height="85.826056"
width="527.49273"
y="-139.82897"
x="56.895925" />
<rect
id="rect3071"
height="48.400576"
width="87.966125"
y="-72.984995"
x="304.23219" />
<rect
x="74.790557"
y="-300.90154"
width="340.90579"
height="69.572611"
id="rect837" />
</defs>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1235"
inkscape:window-height="747"
id="namedview12"
showgrid="false"
inkscape:zoom="1.5716721"
inkscape:cx="358.79327"
inkscape:cy="-11.450355"
inkscape:window-x="45"
inkscape:window-y="25"
inkscape:window-maximized="1"
inkscape:current-layer="svg10"
inkscape:document-rotation="0"
showguides="true" />
<g
inkscape:label="Google"
transform="matrix(0.69853302,0,0,-0.69852941,1,3)"
id="use2460">
<path
id="path3053"
d="m 0.7,-52.6 c 0,29 24.3,52.5 53.3,52.5 16,0 27.4,-6.3 36,-14.5 L 79.8,-24.7 c -6.1,5.8 -14.4,10.3 -25.8,10.3 -21.1,0 -37.6,-17 -37.6,-38.1 0,-21.1 16.5,-38.1 37.6,-38.1 13.7,0 21.5,5.5 26.5,10.5 4.1,4.1 6.8,10 7.8,18 H 54 v 14.3 h 48.3 c 0.5,-2.6 0.8,-5.6 0.8,-9 0,-10.8 -2.9,-24.1 -12.4,-33.5 C 81.4,-99.9 69.6,-105 54,-105 25,-105 0.7,-81.5 0.7,-52.6 Z"
fill="#4285f4" />
<path
id="path3055"
d="m 142,-37.5 c -18.7,0 -33.9,-14.2 -33.9,-33.8 0,-19.5 15.2,-33.8 33.9,-33.8 18.7,0 33.9,14.3 33.9,33.8 0,19.6 -15.2,33.8 -33.9,33.8 z m 0,-54.2 c -10.2,0 -19.1,8.4 -19.1,20.5 0,12.2 8.8,20.5 19.1,20.5 10.2,0 19.1,-8.3 19.1,-20.5 0,-12.1 -8.9,-20.5 -19.1,-20.5 z"
fill="#ea4335" />
<path
id="path3057"
d="m 216,-37.5 c -18.7,0 -33.9,-14.2 -33.9,-33.8 0,-19.5 15.2,-33.8 33.9,-33.8 18.7,0 33.9,14.3 33.9,33.8 0,19.6 -15.2,33.8 -33.9,33.8 z m 0,-54.2 c -10.2,0 -19.1,8.4 -19.1,20.5 0,12.2 8.8,20.5 19.1,20.5 10.3,0 19.1,-8.3 19.1,-20.5 0,-12.1 -8.9,-20.5 -19.1,-20.5 z"
fill="#fbbc05" />
<path
id="path3059"
d="M 306.8,-39.5 V -45 h -0.5 c -3.3,4 -9.7,7.6 -17.8,7.6 -16.9,0 -32.4,-14.8 -32.4,-33.9 0,-18.9 15.5,-33.7 32.4,-33.7 8.1,0 14.5,3.6 17.8,7.7 h 0.5 v -4.9 c 0,-12.9 -6.9,-19.8 -18,-19.8 -9.1,0 -14.7,6.5 -17,12 l -12.9,-5.4 c 3.7,-9 13.6,-20 30,-20 17.4,0 32.1,10.2 32.1,35.2 v 60.7 z m -17,-52.2 c -10.2,0 -18.8,8.6 -18.8,20.4 0,11.9 8.6,20.6 18.8,20.6 10.1,0 18,-8.7 18,-20.6 0.1,-11.9 -7.9,-20.4 -18,-20.4 z"
fill="#4285f4" />
<polygon
id="polygon3061"
points="346,-103 331.2,-103 331.2,-3.7 346,-3.7 "
fill="#34a853" />
<path
id="path3063"
d="m 386.7,-91.7 c -7.6,0 -12.9,3.5 -16.4,10.2 l 45.2,18.7 -1.5,3.8 c -2.8,7.6 -11.4,21.5 -28.9,21.5 -17.4,0 -31.9,-13.7 -31.9,-33.8 0,-18.9 14.3,-33.8 33.5,-33.8 15.5,0 24.4,9.5 28.2,15 l -11.5,7.7 c -3.9,-5.6 -9.1,-9.3 -16.7,-9.3 z m -1.1,41.2 c 5.9,0 10.9,-2.9 12.5,-7.2 l -30.2,-12.5 c -0.4,13 10.1,19.7 17.7,19.7 z"
fill="#ea4335" />
<polygon
id="polygon3065"
points="0,-136 416,-136 416,0 0,0 "
fill="none" />
</g>
<g
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;white-space:pre;shape-inside:url(#rect3077);fill:#000000;fill-opacity:1;stroke:none"
id="text3075"
transform="matrix(2.2707104,0,0,2.2707104,183.62468,309.94175)"
aria-label="for Startups">
<path
id="path3099"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:ProductSans;-inkscape-font-specification:ProductSans;fill:#000000;fill-opacity:0.541176"
d="m 68.176484,-132.13108 q 2,0 3.28,0.68 l -1,3.24 q -0.96,-0.48 -2.16,-0.48 -1.36,0 -2.24,0.96 -0.84,0.92 -0.84,2.48 v 2.48 h 5.12 v 3.36 h -5.12 v 16.24 h -3.68 v -16.24 h -3.68 v -3.36 h 3.68 v -2.84 q 0,-2.92 1.84,-4.72 1.88,-1.8 4.8,-1.8 z" />
<path
id="path3101"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:ProductSans;-inkscape-font-specification:ProductSans;fill:#000000;fill-opacity:0.541176"
d="m 71.532109,-112.97108 q 0,-4.52 2.84,-7.48 2.88,-2.96 7.24,-2.96 4.36,0 7.2,2.96 2.88,2.96 2.88,7.48 0,4.56 -2.88,7.48 -2.84,2.96 -7.2,2.96 -4.36,0 -7.24,-2.96 -2.84,-2.96 -2.84,-7.48 z m 3.68,0 q 0,3.16 1.84,5.12 1.84,1.96 4.56,1.96 2.72,0 4.56,-1.96 1.84,-1.96 1.84,-5.12 0,-3.12 -1.84,-5.08 -1.88,-2 -4.56,-2 -2.68,0 -4.56,2 -1.84,1.96 -1.84,5.08 z" />
<path
id="path3103"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:ProductSans;-inkscape-font-specification:ProductSans;fill:#000000;fill-opacity:0.541176"
d="m 98.363359,-103.17108 h -3.68 v -19.6 h 3.52 v 3.2 h 0.16 q 0.56,-1.56 2.280001,-2.64 1.76,-1.12 3.44,-1.12 1.6,0 2.72,0.48 l -1.12,3.56 q -0.68,-0.28 -2.16,-0.28 -2.08,0 -3.640001,1.68 -1.52,1.68 -1.52,3.92 z" />
<path
id="path3105"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:ProductSans;-inkscape-font-specification:ProductSans;fill:#000000;fill-opacity:0.541176"
d="m 135.19086,-110.81108 q 0,3.76 -2.76,6.04 -2.8,2.24 -6.8,2.24 -3.56,0 -6.28,-2.08 -2.72,-2.08 -3.76,-5.68 l 3.52,-1.44 q 0.36,1.28 1,2.32 0.64,1.04 1.48,1.8 0.88,0.72 1.92,1.16 1.04,0.4 2.2,0.4 2.52,0 4.12,-1.28 1.6,-1.32 1.6,-3.48 0,-1.8 -1.32,-3.08 -1.24,-1.24 -4.64,-2.4 -3.44,-1.24 -4.28,-1.68 -4.56,-2.32 -4.56,-6.84 0,-3.16 2.52,-5.4 2.56,-2.24 6.28,-2.24 3.28,0 5.68,1.68 2.4,1.64 3.2,4.12 l -3.44,1.44 q -0.48,-1.6 -1.92,-2.64 -1.4,-1.08 -3.44,-1.08 -2.16,0 -3.64,1.2 -1.48,1.12 -1.48,2.92 0,1.48 1.16,2.56 1.28,1.08 5.56,2.56 4.36,1.48 6.2,3.64 1.88,2.12 1.88,5.24 z" />
<path
id="path3107"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:ProductSans;-inkscape-font-specification:ProductSans;fill:#000000;fill-opacity:0.541176"
d="m 145.72461,-102.85108 q -2.4,0 -4,-1.48 -1.56,-1.48 -1.6,-4.12 v -10.96 h -3.44 v -3.36 h 3.44 v -6 h 3.68 v 6 h 4.8 v 3.36 h -4.8 v 9.76 q 0,1.96 0.76,2.68 0.76,0.68 1.72,0.68 0.44,0 0.84,-0.08 0.44,-0.12 0.8,-0.28 l 1.16,3.28 q -1.44,0.52 -3.36,0.52 z" />
<path
id="path3109"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:ProductSans;-inkscape-font-specification:ProductSans;fill:#000000;fill-opacity:0.541176"
d="m 154.39461,-109.17108 q 0,1.44 1.2,2.4 1.24,0.96 2.88,0.96 2.32,0 4.12,-1.72 1.84,-1.72 1.84,-4.04 -1.72,-1.36 -4.8,-1.36 -2.24,0 -3.76,1.08 -1.48,1.08 -1.48,2.68 z m 4.76,-14.24 q 4.08,0 6.44,2.2 2.36,2.16 2.36,5.96 v 12.08 h -3.52 v -2.72 h -0.16 q -2.28,3.36 -6.08,3.36 -3.24,0 -5.44,-1.92 -2.16,-1.92 -2.16,-4.8 0,-3.04 2.28,-4.84 2.32,-1.8 6.16,-1.8 3.28,0 5.4,1.2 v -0.84 q 0,-1.92 -1.52,-3.24 -1.52,-1.36 -3.56,-1.36 -3.08,0 -4.88,2.6 l -3.24,-2.04 q 2.68,-3.84 7.92,-3.84 z" />
<path
id="path3111"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:ProductSans;-inkscape-font-specification:ProductSans;fill:#000000;fill-opacity:0.541176"
d="m 195.06523,-102.85108 q -2.4,0 -4,-1.48 -1.56,-1.48 -1.6,-4.12 v -10.96 h -3.44 v -3.36 h 3.44 v -6 h 3.68 v 6 h 4.8 v 3.36 h -4.8 v 9.76 q 0,1.96 0.76,2.68 0.76,0.68 1.72,0.68 0.44,0 0.84,-0.08 0.44,-0.12 0.8,-0.28 l 1.16,3.28 q -1.44,0.52 -3.36,0.52 z m -22.96,-19.92 h 3.52 v 3.2 h 0.16 q 1.64,-3.76 6.76,-3.76 l 0.76,0.08 v 3.84 l -1.64,-0.16 q -2.56,0 -4.24,1.6 -1.64,1.56 -1.64,4 v 10.8 h -3.68 z" />
<path
id="path3113"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:ProductSans;-inkscape-font-specification:ProductSans;fill:#000000;fill-opacity:0.541176"
d="m 218.68023,-103.17108 h -3.52 v -2.72 h -0.16 q -0.84,1.44 -2.6,2.4 -1.72,0.96 -3.6,0.96 -3.6,0 -5.56,-2.04 -1.92,-2.08 -1.92,-5.88 v -12.32 h 3.68 v 12.08 q 0.12,4.8 4.84,4.8 2.2,0 3.68,-1.76 1.48,-1.8 1.48,-4.28 v -10.84 h 3.68 z" />
<path
id="path3115"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:ProductSans;-inkscape-font-specification:ProductSans;fill:#000000;fill-opacity:0.541176"
d="m 232.79898,-105.89108 q 2.64,0 4.44,-2 1.8,-1.96 1.8,-5.08 0,-3.08 -1.8,-5.08 -1.8,-2 -4.44,-2 -2.68,0 -4.48,2 -1.76,2 -1.76,5.08 0,3.12 1.76,5.12 1.8,1.96 4.48,1.96 z m 0.6,3.36 q -2.16,0 -3.96,-0.92 -1.76,-0.92 -2.72,-2.44 h -0.16 l 0.16,2.72 v 8.640004 h -3.68 v -28.240004 h 3.52 v 2.72 h 0.16 q 0.96,-1.52 2.72,-2.44 1.8,-0.92 3.96,-0.92 3.88,0 6.56,3.04 2.76,3.08 2.76,7.4 0,4.36 -2.76,7.4 -2.68,3.04 -6.56,3.04 z" />
<path
id="path3117"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:ProductSans;-inkscape-font-specification:ProductSans;fill:#000000;fill-opacity:0.541176"
d="m 260.85523,-108.61108 q 0,2.56 -2.24,4.32 -2.24,1.76 -5.64,1.76 -2.96,0 -5.2,-1.52 -2.24,-1.56 -3.2,-4.08 l 3.28,-1.4 q 0.72,1.76 2.08,2.76 1.4,0.96 3.04,0.96 1.76,0 2.92,-0.76 1.2,-0.76 1.2,-1.8 0,-1.88 -2.88,-2.76 l -3.36,-0.84 q -5.72,-1.44 -5.72,-5.52 0,-2.68 2.16,-4.28 2.2,-1.64 5.6,-1.64 2.6,0 4.68,1.24 2.12,1.24 2.96,3.32 l -3.28,1.36 q -0.56,-1.24 -1.84,-1.92 -1.24,-0.72 -2.8,-0.72 -1.44,0 -2.6,0.72 -1.12,0.72 -1.12,1.76 0,1.68 3.16,2.4 l 2.96,0.76 q 5.84,1.44 5.84,5.88 z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="10px" height="10px" viewBox="0 0 10 10" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 52.2 (67145) - http://www.bohemiancoding.com/sketch -->
<title>icon-close-coockies</title>
<desc>Created with Sketch.</desc>
<g id="corporate-website-EN" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="homepage-(coockies)" transform="translate(-213.000000, -603.000000)" fill="#000000" fill-rule="nonzero">
<g id="Group-7" transform="translate(20.000000, 580.000000)">
<g id="Group-5" transform="translate(182.000000, 12.000000)">
<g id="icon-close-coockies" transform="translate(12.000000, 12.000000)">
<path d="M7.43431458,-0.565685425 C7.74673401,-0.878104858 8.25326599,-0.878104858 8.56568542,-0.565685425 C8.87810486,-0.253265992 8.87810486,0.253265992 8.56568542,0.565685425 L0.565685425,8.56568542 C0.253265992,8.87810486 -0.253265992,8.87810486 -0.565685425,8.56568542 C-0.878104858,8.25326599 -0.878104858,7.74673401 -0.565685425,7.43431458 L7.43431458,-0.565685425 Z" id="Path"></path>
<path d="M-0.565685425,0.565685425 C-0.878104858,0.253265992 -0.878104858,-0.253265992 -0.565685425,-0.565685425 C-0.253265992,-0.878104858 0.253265992,-0.878104858 0.565685425,-0.565685425 L8.56568542,7.43431458 C8.87810486,7.74673401 8.87810486,8.25326599 8.56568542,8.56568542 C8.25326599,8.87810486 7.74673401,8.87810486 7.43431458,8.56568542 L-0.565685425,0.565685425 Z" id="Path"></path>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +1,3 @@
<svg width="35" height="36" viewBox="0 0 35 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.80083 4.05287C6.80083 3.09358 7.56205 2.31593 8.50106 2.31593C9.44007 2.31593 10.2013 3.09358 10.2013 4.05287V20.2644C10.2013 21.2236 9.44007 22.0013 8.50106 22.0013C7.56205 22.0013 6.80083 21.2236 6.80083 20.2644V4.05287ZM20.4027 6.36879C20.4027 5.40951 21.1639 4.63185 22.1029 4.63185C23.0419 4.63185 23.8031 5.40951 23.8031 6.36879V22.5803C23.8031 23.5395 23.0419 24.3172 22.1029 24.3172C21.1639 24.3172 20.4027 23.5395 20.4027 22.5803V6.36879ZM13.6017 1.73694C13.6017 0.777657 14.363 0 15.302 0C16.241 0 17.0022 0.777657 17.0022 1.73694V17.9484C17.0022 18.9077 16.241 19.6854 15.302 19.6854C14.363 19.6854 13.6017 18.9077 13.6017 17.9484V1.73694ZM31.5667 24.4892C32.4127 24.073 33.4288 24.4363 33.8361 25.3007C34.2435 26.165 33.8879 27.203 33.0419 27.6192L18.6898 34.6786C12.2035 37.8691 4.41345 35.0837 1.29038 28.4573C0.44103 26.6551 0 24.6806 0 22.6803V9.84265C0 8.88337 0.761139 8.10575 1.70023 8.10575C2.63923 8.10575 3.40038 8.88337 3.40038 9.84265V22.6803C3.40038 24.1588 3.72638 25.6182 4.35424 26.9503C6.66254 31.848 12.4204 33.9068 17.2147 31.5486L31.5667 24.4892Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
public/img/ui/ua_flag.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -1 +0,0 @@
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>

Before

Width:  |  Height:  |  Size: 128 B

View File

@ -1 +0,0 @@
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>

Before

Width:  |  Height:  |  Size: 385 B

View File

@ -0,0 +1,90 @@
import { NextIntlClientProvider, hasLocale } from 'next-intl';
import { getTranslations } from 'next-intl/server';
import { notFound } from 'next/navigation';
import { routing } from '@/i18n/routing';
import { Inter } from "next/font/google";
import MainEffects from '@/app/ui/homepage/js/MainEffects';
import Template from './template';
import { GoogleTagManagerHead, GoogleTagManagerBody } from '@/app/ui/components/GoogleTagManager';
import '@/app/ui/homepage/css/index.css';
const interSans = Inter({
variable: "--font-inter-sans",
subsets: ["latin", "cyrillic"],
});
export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) {
const { locale } = await params;
const t = await getTranslations({ locale, namespace: 'website_home' });
// Get the base URL from environment variables
const protocol = process.env.PROTOCOL || 'https';
const hostname = process.env.HOSTNAME || 'www.mssg.me';
const baseUrl = `${protocol}://${hostname}`;
// Current page path (this is for the homepage)
const currentPath = '';
// Generate canonical URL
const canonicalUrl = locale === 'en'
? `${baseUrl}${currentPath}`
: `${baseUrl}/${locale}${currentPath}`;
// Generate alternate URLs for all locales
const alternateUrls: Record<string, string> = {};
routing.locales.forEach((loc) => {
alternateUrls[loc] = loc === 'en'
? `${baseUrl}${currentPath}`
: `${baseUrl}/${loc}${currentPath}`;
});
// Add x-default for users who don't match any specific language
alternateUrls['x-default'] = `${baseUrl}${currentPath}`;
return {
title: t('head.title'),
description: t('head.description'),
alternates: {
canonical: canonicalUrl,
languages: alternateUrls,
},
icons: {
other: [
{
rel: 'mask-icon',
url: '/favicons/safari-pinned-tab.svg',
color: '#000000',
}
]
}
};
}
export default async function LocaleLayout({
children,
params
}: {
children: React.ReactNode;
params: Promise<{locale: string}>;
}) {
const {locale} = await params;
if (!hasLocale(routing.locales, locale)) {
notFound();
}
return (
<html lang={locale} id="homepage">
<head>
<GoogleTagManagerHead gtmId="GTM-5MPBB4D" />
</head>
<body className={interSans.variable}>
<GoogleTagManagerBody gtmId="GTM-5MPBB4D" />
<Template>
<NextIntlClientProvider>{children}</NextIntlClientProvider>
<MainEffects />
</Template>
</body>
</html>
);
}

View File

@ -0,0 +1,355 @@
import { useLocale, useTranslations } from 'next-intl';
import Image from "next/image";
import { Link } from '@/i18n/navigation';
import { LocaleType } from '@/i18n/i18n';
const { BLACK_FRIDAY_PROMO } = process.env;
import LanguageSwitcher from '@/app/ui/components/LanguageSwitcher';
import { generateAuthUrl } from '@/app/helpers/generateAuthUrl';
export default function Home() {
const t = useTranslations();
const currentYear = new Date().getFullYear();
const locale = useLocale();
const loginUrl = generateAuthUrl(locale as LocaleType, 'login');
const signUpUrl = generateAuthUrl(locale as LocaleType, 'signup');
return (
<>
{BLACK_FRIDAY_PROMO && (
<div className="promo">
{t('promo.black_friday')}
</div>
)}
<div className="page-container">
<header className="header">
<Link href="/" className="logo">
<Image src="/img/ui/logo_home.svg" alt="mssg.me logo" width={34} height={35} />
</Link>
<ul className="auth-buttons">
<li>
<a href={loginUrl} className="right">{t('website_home.common.auth.login')}</a>
</li>
<li>
<a href={signUpUrl}>{t('website_home.common.auth.signup')}</a>
</li>
</ul>
</header>
<section className="section intro-section">
<div className="content">
<h1 className="main-title">
<span className="gradiented">{t('website_home.home.intro.title.1')}</span>
<span>{t('website_home.home.intro.title.2')}</span>
</h1>
<p>{t('website_home.home.intro.description')}</p>
<div className="button-container center">
<a href={signUpUrl} className="button">{t('website_home.common.sign_up_cta')}</a>
</div>
<div className="bbg-label"><span>backed by</span> <Image src="/img/ui/google_for_startups_logo.svg" alt="Google for startups logotype" width={260} height={32} /></div>
{/* <Link
href="https://apps.apple.com/us/app/mssg-me-website-builder/id6454930943?itsct=apps_box_badge&amp;itscg=30200"
style={{
display: "inline-block",
overflow: "hidden",
borderRadius: "13px",
width: "250px",
height: "83px",
marginTop: "20px"
}}
>
<Image
src="https://tools.applemediaservices.com/api/badges/download-on-the-app-store/black/en-us?size=250x83&amp;releaseDate=1705968000"
alt="Download on the App Store"
style={{
borderRadius: "13px",
width: "250px",
height: "83px"
}}
/>
</Link> */}
</div>
</section>
<section className="section presentation-section">
<div className="presentation-hero">
<Image
className="presentation-hero-left"
src="/img/home/presentation/presentation_left_378w.webp"
sizes="(max-width: 420px) 126px,
(max-width: 1920px) 252px,
378px"
alt="Contact me landing example"
width={253}
height={471}
/>
<Image
className="presentation-hero-right"
src="/img/home/presentation/presentation_right_378w.webp"
sizes="(max-width: 420px) 126px,
(max-width: 1920px) 252px,
378px"
alt="Shop landing example"
width={253}
height={471}
/>
<Image
className="presentation-hero-center"
src="/img/home/presentation/presentation_center_441w.webp"
sizes="(max-width: 420px) 147px,
(max-width: 1920px) 294px,
441px"
alt="Multilink landing example"
width={253}
height={471}
priority
/>
</div>
<div className="content section-content">
<h2 className="gradiented">{t('website_home.home.presentation.title')}</h2>
<p>{t('website_home.home.presentation.description')}</p>
<div className="button-container center">
<a href={signUpUrl} className="button">{t('website_home.common.sign_up_cta')}</a>
</div>
</div>
</section>
<section className="section multi-link-section">
<div className="multi-link-hero-container">
<div className="multi-link-hero">
<Image
src="/img/home/multilink/multilink_441w.webp"
sizes="(max-width: 420px) 147px,
(max-width: 1920px) 294px,
441px"
alt="Multi-link page example"
width={295}
height={550}
/>
<div className="multi-link-hero__icon instagram">
<div>
<div>
<Image src="/img/home/multilink/instagram.svg" alt="Instagram icon" width={57} height={57} />
</div>
</div>
</div>
<div className="multi-link-hero__icon youtube">
<div>
<div>
<Image src="/img/home/multilink/youtube.svg" alt="YouTube icon" width={43} height={30} />
</div>
</div>
</div>
<div className="multi-link-hero__icon tiktok">
<div>
<div>
<Image src="/img/home/multilink/tiktok.svg" alt="TikTok icon" width={42} height={42} />
</div>
</div>
</div>
<div className="multi-link-hero__icon twitter">
<div>
<div>
<Image src="/img/home/multilink/twitter.svg" alt="Twitter icon" width={27} height={27} />
</div>
</div>
</div>
</div>
</div>
<div className="content section-content">
<h2 className="gradiented section-title">{t('website_home.home.multi_link.title')}</h2>
<h3 className="section-subtitle">{t('website_home.home.multi_link.subtitle')}</h3>
<p>{t('website_home.home.multi_link.description')}</p>
<div className="button-container">
<a href={signUpUrl} className="button">{t('website_home.common.sign_up_cta')}</a>
</div>
</div>
</section>
<section className="section messengers-section">
<div className="messengers-hero-container">
<div className="messengers-hero">
<Image
src="/img/home/messengers/messengers_441w.webp"
sizes="(max-width: 420px) 147px,
(max-width: 1920px) 294px,
441px"
alt="Page with messengers example"
width={294}
height={548}
/>
<div className="icon-hey">
<Image
src="/img/home/messengers/hey_192w.webp"
sizes="(max-width: 420px) 64px,
(max-width: 1920px) 128px,
192px"
alt="Hey icon"
width={128}
height={128}
/>
</div>
<div className="message">
<Image
src="/img/home/messengers/message_501w.webp"
sizes="(max-width: 420px) 167px,
(max-width: 1920px) 334px,
501px"
alt="User message image"
width={338}
height={77}
/>
</div>
</div>
</div>
<div className="content section-content">
<h2 className="gradiented section-title">{t('website_home.home.messengers.title')}</h2>
<h3 className="section-subtitle">{t('website_home.home.messengers.subtitle')}</h3>
<p>{t('website_home.home.messengers.description')}</p>
<div className="button-container">
<a href={signUpUrl} className="button">{t('website_home.common.sign_up_cta')}</a>
</div>
</div>
</section>
<section className="section store-section">
<div className="store-hero-container">
<div className="store-hero">
<Image
src="/img/home/store/store_441w.webp"
sizes="(max-width: 420px) 147px,
(max-width: 1920px) 294px,
441px"
alt="Online store page example"
width={294}
height={549}
/>
<div className="icon-cart">
<Image
src="/img/home/store/cart_192w.webp"
sizes="(max-width: 420px) 64px,
(max-width: 1920px) 128px,
192px"
alt="Shopping cart icon"
width={129}
height={129}
/>
</div>
<div className="order">
<Image
src="/img/home/store/order_342w.webp"
sizes="(max-width: 420px) 114px,
(max-width: 1920px) 228px,
342px"
alt="Shopping cart icon"
width={228}
height={200}
/>
</div>
</div>
</div>
<div className="content section-content">
<h2 className="gradiented section-title">{t('website_home.home.store.title')}</h2>
<h3 className="section-subtitle">{t('website_home.home.store.subtitle')}</h3>
<p>{t('website_home.home.store.description')}</p>
<div className="button-container">
<a href={signUpUrl} className="button">{t('website_home.common.sign_up_cta')}</a>
</div>
</div>
</section>
<section className="section builder-section">
<div className="builder-hero-container">
<div className="builder-hero">
<Image
src="/img/home/builder/builder_441w.webp"
sizes="(max-width: 420px) 147px,
(max-width: 1920px) 294px,
441px"
alt="Website builder example"
width={264}
height={568}
/>
<div className="blocks">
<Image
src="/img/home/builder/blocks_333w.webp"
sizes="(max-width: 420px) 111px,
(max-width: 1920px) 222px,
333px"
alt="Website builder blocks"
width={198}
height={287}
/>
</div>
<div className="customize">
<Image
src="/img/home/builder/customize_486w.webp"
sizes="(max-width: 420px) 162px,
(max-width: 1920px) 324px,
486px"
alt="Website builder blocks customization"
width={291}
height={196}
/>
</div>
</div>
</div>
<div className="content section-content">
<h2 className="gradiented section-title">{t('website_home.home.builder.title')}</h2>
<h3 className="section-subtitle">{t('website_home.home.builder.subtitle')}</h3>
<p>{t('website_home.home.builder.description')}</p>
<div className="button-container">
<a href={signUpUrl} className="button">{t('website_home.common.sign_up_cta')}</a>
</div>
</div>
</section>
<section className="features-section">
<div className="content">
<h2 className="section-subtitle">{t('website_home.home.features.title')}</h2>
<ul className="features-list">
<li>
<h3 className="section-subtitle">{t('website_home.home.features.list.domain.title')}</h3>
<p>{t('website_home.home.features.list.domain.description')}</p>
</li>
<li>
<h3 className="section-subtitle">{t('website_home.home.features.list.qr.title')}</h3>
<p>{t('website_home.home.features.list.qr.description')}</p>
</li>
<li>
<h3 className="section-subtitle">{t('website_home.home.features.list.analytics.title')}</h3>
<p>{t('website_home.home.features.list.analytics.description')}</p>
</li>
</ul>
</div>
</section>
<section className="footer-cta-section">
<div className="content">
<h2 className="gradiented">{t('website_home.home.footer.title')}</h2>
<p>{t('website_home.home.footer.description')}</p>
<div className="button-container center">
<a href={signUpUrl} className="button">{t('website_home.common.sign_up_cta')}</a>
</div>
</div>
</section>
<footer className="footer">
<div className="content">
<ul className="footer-list">
<li>
<Link href="/privacy-policy">{t('website_home.common.terms.politics')}</Link>
</li>
<li>
<Link href="/terms-of-use">{t('website_home.common.terms.terms')}</Link>
</li>
</ul>
<ul className="footer-lang-chooser">
<LanguageSwitcher />
</ul>
<span className="copyright">mssg.me © {currentYear}</span>
<span className="made-in">Made in Ukraine <Image width="17" height="12" src="/img/ui/ua_flag.gif" alt="Ukrainian flag" unoptimized /></span>
<div className="bbg-label-footer"><span>backed by</span> <Image src="/img/ui/google_for_startups_logo.svg" alt="Google for startups logotype" width={160} height={19} /></div>
</div>
</footer>
</div>
<div className="cookie-message" id="cookie-message">
<span>{t('website_home.common.cookies.message')}</span>
<Link href="/privacy-policy">{t('website_home.common.cookies.link')}</Link>
<div className="close-cookie" id="close-cookie"></div>
</div>
</>
);
}

View File

@ -0,0 +1,3 @@
export default function Template({ children }: { children: React.ReactNode }) {
return <div>{children}</div>
}

View File

@ -0,0 +1,49 @@
import { useTranslations } from 'next-intl';
import { Link } from '@/i18n/navigation';
import LanguageSwitcher from '@/app/ui/components/LanguageSwitcher';
export default function Footer() {
const t = useTranslations();
return (
<>
<footer className="main-footer">
<div className="main-footer-content">
<nav className="main-footer-content-left">
<ul className="footer-nav-list">
<li>
<h6>{t('menu.subheading4')}</h6>
<ul className="footer-menu-list">
<li>
<Link href="/terms-of-use">{t('menu.terms')}</Link>
</li>
<li>
<Link href="/privacy-policy">{t('menu.privacy')}</Link>
</li>
</ul>
</li>
</ul>
<ul className="lang-chooser-list lang-chooser-list-mobile">
<LanguageSwitcher />
</ul>
</nav>
<div className="main-footer-content-right">
<ul className="footer-socials-list">
<li>
<Link href="https://t.me/mssgme" target="_blank" data-footer-social="Telegram">
<i className="fab fa-telegram"></i>
</Link>
</li>
</ul>
</div>
</div>
</footer>
<div className="cookie-message" id="cookie-message">
<span>{t('cookies.message')}</span>
<Link href="/privacy-policy">{t('cookies.link')}</Link>
<div className="close-cookie" id="close-cookie"></div>
</div>
</>
);
}

View File

@ -0,0 +1,43 @@
import { useLocale, useTranslations } from 'next-intl';
import { Link } from '@/i18n/navigation';
import Image from 'next/image';
import LanguageSwitcher from '@/app/ui/components/LanguageSwitcher';
import { generateAuthUrl } from '@/app/helpers/generateAuthUrl';
import { LocaleType } from '@/i18n/i18n';
export default function Header() {
const t = useTranslations();
const locale = useLocale();
const loginUrl = generateAuthUrl(locale as LocaleType, 'login');
return (
<header className="main-header">
<div className="main-header-content">
<div className="main-header-left">
<Link href="/" className="header-logo">
<Image src="/img/ui/logo_full.svg" alt="mssg.me logo" width={151} height={44} />
</Link>
</div>
<div className="main-header-right">
<div className="header-buttons">
<ul
className="lang-chooser-list lang-chooser-list-desktop"
style={{ margin: '0 10px 0 0', lineHeight: '26px' }}
>
<LanguageSwitcher />
</ul>
<Link href={loginUrl} className="button button-header button-outline">{t('button.login')}</Link>
</div>
<div className="mobile-menu-btn">
<div className="mobile-menu-btn-inner">
<div></div>
<div></div>
<div></div>
</div>
</div>
</div>
</div>
</header>
);
}

View File

@ -0,0 +1,5 @@
import { notFound } from 'next/navigation';
export default function CatchAllNotFound() {
notFound();
}

View File

@ -0,0 +1,188 @@
import { getTranslations, getLocale } from 'next-intl/server';
import Link from 'next/link';
import React from 'react';
import { Metadata } from 'next';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faFacebook, faTwitter } from '@fortawesome/free-brands-svg-icons';
interface PostCategory {
name: string;
}
interface Post {
id: number;
title: {
rendered: string;
};
content: {
rendered: string;
};
thumbnail_full_url: string;
thumbnail_article_1x: string;
thumbnail_article_2x: string;
post_categories: PostCategory[];
acf: {
time_to_read: string;
title?: string;
description?: string;
og_image?: string;
og_type?: string;
header_image?: {
sizes: {
article_header_image_1x: string;
article_header_image_2x: string;
};
};
};
slug: string;
link: string;
}
export async function generateMetadata({
params,
}: {
params: Promise<{ slug: string }>
}): Promise<Metadata> {
const { slug } = await params;
const locale = await getLocale();
try {
const data = await fetch(`https://w.mssg.me/${locale}/wp-json/wp/v2/posts?slug=${slug}`);
const post: Post[] = await data.json();
const pData = post[0];
if (!pData) {
return {
title: 'Post not found',
description: 'The requested blog post could not be found.'
};
}
const openGraphUrl = `https://mssg.me/${locale}/blog/${slug}`;
return {
title: pData.acf.title || pData.title.rendered,
description: pData.acf.description,
openGraph: {
siteName: 'mssg.me',
title: pData.acf.title || pData.title.rendered,
description: pData.acf.description,
url: openGraphUrl,
type: (pData.acf.og_type as 'website' | 'article') || 'article',
images: pData.acf.og_image ? [
{
url: pData.acf.og_image,
alt: pData.title.rendered,
}
] : undefined,
},
twitter: {
card: 'summary',
title: pData.acf.title || pData.title.rendered,
description: pData.acf.description,
images: pData.acf.og_image ? [pData.acf.og_image] : undefined,
},
};
} catch (error) {
console.error('Error generating metadata:', error);
return {
title: 'Blog Post',
description: 'Read our latest blog post on mssg.me'
};
}
}
export default async function Page({
params,
}: {
params: Promise<{ slug: string }>
}) {
const { slug } = await params;
const locale = await getLocale();
const t = await getTranslations({ locale });
const postsData = await fetch(`https://w.mssg.me/${locale}/wp-json/wp/v2/posts`);
const posts: Post[] = await postsData.json();
const data = await fetch(`https://w.mssg.me/${locale}/wp-json/wp/v2/posts?slug=${slug}`);
const post: Post[] = await data.json();
const pData = post[0];
return (
<div className="page-wrapper">
<main>
<section className="section-article">
<div className="common-content">
<div className="section-article-content">
<div className="section-article-header">
<div className="section-article-header-img">
<img
src={pData.acf.header_image ? pData.acf.header_image.sizes.article_header_image_1x : pData.thumbnail_full_url}
srcSet={[pData.acf.header_image ? pData.acf.header_image.sizes.article_header_image_1x : `${pData.thumbnail_full_url} 1x`, pData.acf.header_image ? pData.acf.header_image.sizes.article_header_image_2x : `${pData.thumbnail_full_url} 2x`].join(', ')}
alt={pData.title.rendered}
/>
</div>
<div className="section-article-header-heading">
<div className="section-article-header-heading-content">
<h1>{pData.title.rendered}</h1>
<span>
{pData.post_categories.map((cat: PostCategory, index: number) => (
<React.Fragment key={index}>
<span>{cat.name}</span> | {pData.acf.time_to_read}
</React.Fragment>
))}
</span>
</div>
</div>
</div>
<div className="section-article-text clearfix" dangerouslySetInnerHTML={{ __html: pData.content.rendered }} />
<ul className="article-share-list">
<li className="article-share-list-fb">
<a href={`https://www.facebook.com/sharer/sharer.php?u=https://www.mssg.me/${locale}/blog/${slug}`} target="_blank" data-share-social="Facebook" className="article-share-link">
<FontAwesomeIcon icon={faFacebook} />
Facebook
</a>
</li>
<li className="article-share-list-twitter">
<a href={`https://twitter.com/home?status=https://www.mssg.me/${locale}/blog/${slug}`} target="_blank" data-share-social="Twitter" className="article-share-link">
<FontAwesomeIcon icon={faTwitter} />
Twitter
</a>
</li>
</ul>
</div>
</div>
</section>
<section className="section-fp-news">
<div className="common-content">
<div className="section-fp-news-content section-fp-news-content-article">
<h3>{t('single_article.posts_section.heading')}</h3>
<ul className="section-fp-news-list">
{posts.filter((post: Post) => post.id !== pData.id).slice(0,3).map((element: Post, index: number) => (
<li key={index}>
<div className="section-fp-news-list-item-preview">
<img
src={element.thumbnail_article_1x}
srcSet={`${element.thumbnail_article_1x} 1x ` + `${element.thumbnail_article_2x} 2x`}
alt={element.title.rendered}
/>
</div>
<div className="section-fp-news-list-item-content">
<h4>{element.title.rendered}</h4>
<span>
{element.post_categories.map((cat: PostCategory, index: number) => (
<React.Fragment key={index}>
<span>{cat.name}</span> | {element.acf.time_to_read}
</React.Fragment>
))}
</span>
</div>
<Link href={`/blog/${element.slug}`} className="section-fp-news-list-item-link" />
</li>
))}
</ul>
</div>
</div>
</section>
</main>
</div>
);
}

View File

@ -0,0 +1,68 @@
import { getTranslations, getLocale } from 'next-intl/server';
import Link from 'next/link';
import React from 'react';
import { Metadata } from 'next';
interface PostCategory {
name: string;
}
interface Post {
title: {
rendered: string;
};
thumbnail_medium_url: string;
post_categories: PostCategory[];
acf: {
time_to_read: string;
};
slug: string;
}
export async function generateMetadata(): Promise<Metadata> {
const locale = await getLocale();
const t = await getTranslations({ locale });
return {
title: t('blog.title'),
description: t('blog.description'),
};
}
export default async function Page() {
const locale = await getLocale();
const data = await fetch(`https://w.mssg.me/${locale}/wp-json/wp/v2/posts`);
const posts: Post[] = await data.json();
return (
<div className="page-wrapper">
<section className="section-category-blog">
<div className="common-content">
<div className="section-category-blog-content">
<ul className="section-fp-news-list section-category-blog-list">
{posts.map((element: Post, index: number) =>
<li key={index}>
<div className="section-fp-news-list-item-preview">
<img src={element.thumbnail_medium_url} alt={element.title.rendered} />
</div>
<div className="section-fp-news-list-item-content">
<h4>{element.title.rendered}</h4>
<span>
{element.post_categories.map((cat: PostCategory, index: number) =>
<React.Fragment key={index}>
<span>{cat.name}</span> | {element.acf.time_to_read}
</React.Fragment>
)}
</span>
</div>
<Link href={`/blog/${element.slug}`} className="section-fp-news-list-item-link" />
</li>
)}
</ul>
</div>
</div>
</section>
</div>
);
}

View File

@ -0,0 +1,104 @@
import { getLocale } from 'next-intl/server';
interface AnswerBlock {
acf_fc_layout: string;
text?: string;
heading?: string;
content?: string;
}
interface Question {
question: string;
answer: AnswerBlock[];
}
interface FaqTopic {
topic_name: string;
topic_icon_new: string;
topic_icon_new_active: string;
topic_subheading?: string;
'qa-list': Question[];
}
interface PageData {
acf: {
faq_topics: FaqTopic[];
};
}
export default async function Page() {
const locale = await getLocale();
const data = await fetch(`https://w.mssg.me/${locale}/wp-json/wp/v2/pages/993`);
const pData: PageData = await data.json();
return (
<div className="page-wrapper">
<main>
<div className="page-faq">
<div className="common-content">
<div className="page-faq-content">
<article className="page-faq-container">
<div className="faq-container">
<div className="faq-container-left">
<ul className="faq-top-controls-list clearfix">
{
pData.acf.faq_topics.map((element: FaqTopic) => (
<li key={element.topic_name}>
<img src={element.topic_icon_new} className="default" alt={element.topic_name} />
<img src={element.topic_icon_new_active} className="active" alt={element.topic_name} />
<h2>{element.topic_name}</h2>
{/* <p>{element.topic_subheading}</p> */}
</li>
))
}
</ul>
</div>
<div className="faq-container-right">
<ul className="faq-sublists clearfix">
{pData.acf.faq_topics.map((element: FaqTopic, indexOuter: number) =>
<li key={indexOuter}>
<ul className="faq-panes-list">
{element['qa-list'].map((question: Question, index: number) =>
<li id={`${indexOuter+1}-${index+1}`} key={index}>
<div className="faq-panes-list-item-header">
<span className="faq-panes-list-item-counter"></span>
<h3>{question.question}</h3>
<span className="faq-panes-list-item-status"></span>
</div>
<div className="faq-panes-list-item-content">
{question.answer.map((block: AnswerBlock, index: number) => {
if (block.acf_fc_layout === 'text') {
return <div key={index} dangerouslySetInnerHTML={{ __html: block.text || '' }} />;
}
if (block.acf_fc_layout === 'accordeon') {
return (
<div key={index} style={{ marginBottom: 6 }}>
<div className="accordeon-header">
<h4 className="accordeon-heading">
{block.heading}
</h4>
<span className="faq-panes-list-item-status"></span>
</div>
<div className="accordeon-content" dangerouslySetInnerHTML={{ __html: block.content || '' }} />
</div>
)
}
})}
</div>
</li>
)}
</ul>
</li>
)}
</ul>
</div>
</div>
</article>
</div>
</div>
</div>
</main>
</div>
);
}

View File

@ -0,0 +1,97 @@
import { NextIntlClientProvider, hasLocale } from 'next-intl';
import { getTranslations } from 'next-intl/server';
import { notFound } from 'next/navigation';
import { routing } from '@/i18n/routing';
import { Inter } from "next/font/google";
import Template from './template';
import Header from './Header';
import Footer from './Footer';
import MainScripts from '@/app/ui/components/MainScripts';
import { GoogleTagManagerHead, GoogleTagManagerBody } from '@/app/ui/components/GoogleTagManager';
import '@/app/ui/wppages/css/index.css';
import '@/lib/fontawesome';
const interSans = Inter({
variable: "--font-inter-sans",
subsets: ["latin", "cyrillic"],
});
export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) {
const { locale } = await params;
const t = await getTranslations({ locale, namespace: 'website_home' });
// Get the base URL from environment variables
const protocol = process.env.PROTOCOL || 'https';
const hostname = process.env.HOSTNAME || 'www.mssg.me';
const baseUrl = `${protocol}://${hostname}`;
// Current page path (this is for the root page, adjust for specific pages)
const currentPath = '';
// Generate canonical URL
const canonicalUrl = locale === 'en'
? `${baseUrl}${currentPath}`
: `${baseUrl}/${locale}${currentPath}`;
// Generate alternate URLs for all locales
const alternateUrls: Record<string, string> = {};
routing.locales.forEach((loc) => {
alternateUrls[loc] = loc === 'en'
? `${baseUrl}${currentPath}`
: `${baseUrl}/${loc}${currentPath}`;
});
// Add x-default for users who don't match any specific language
alternateUrls['x-default'] = `${baseUrl}${currentPath}`;
return {
title: t('head.title'),
description: t('head.description'),
alternates: {
canonical: canonicalUrl,
languages: alternateUrls,
},
icons: {
other: [
{
rel: 'mask-icon',
url: '/favicons/safari-pinned-tab.svg',
color: '#000000',
}
]
}
};
}
export default async function LocaleLayout({
children,
params
}: {
children: React.ReactNode;
params: Promise<{locale: string}>;
}) {
const {locale} = await params;
if (!hasLocale(routing.locales, locale)) {
notFound();
}
return (
<html lang={locale} id="homepage">
<head>
<GoogleTagManagerHead gtmId="GTM-5MPBB4D" />
</head>
<body className={interSans.variable}>
<GoogleTagManagerBody gtmId="GTM-5MPBB4D" />
<Template>
<NextIntlClientProvider>
<Header />
{children}
<Footer />
<MainScripts />
</NextIntlClientProvider>
</Template>
</body>
</html>
);
}

View File

@ -0,0 +1,13 @@
import { getLocale } from 'next-intl/server';
export async function GET() {
const locale = await getLocale();
const data = await fetch(`https://w.mssg.me/${locale}/wp-json/wp/v2/pages/138`);
const pData = await data.json();
return new Response(pData.content.rendered, {
headers: {
'Content-Type': 'text/html; charset=utf-8',
},
});
}

View File

@ -0,0 +1,22 @@
import { getLocale } from 'next-intl/server';
export default async function Page() {
const locale = await getLocale();
const data = await fetch(`https://w.mssg.me/${locale}/wp-json/wp/v2/pages/138`);
const pData = await data.json();
return (
<div className="page-wrapper page-wrapper-doc">
<div className="page-default-wrapper">
<article className="page-default-content">
<h1>{pData.title.rendered}</h1>
<div className="clearfix">
<div dangerouslySetInnerHTML={{ __html: pData.content.rendered }} />
</div>
</article>
</div>
</div>
);
}

View File

@ -0,0 +1,3 @@
export default function Template({ children }: { children: React.ReactNode }) {
return <div>{children}</div>
}

View File

@ -0,0 +1,13 @@
import { getLocale } from 'next-intl/server';
export async function GET() {
const locale = await getLocale();
const data = await fetch(`https://w.mssg.me/${locale}/wp-json/wp/v2/pages/140`);
const pData = await data.json();
return new Response(pData.content.rendered, {
headers: {
'Content-Type': 'text/html; charset=utf-8',
},
});
}

View File

@ -0,0 +1,22 @@
import { getLocale } from 'next-intl/server';
export default async function Page() {
const locale = await getLocale();
const data = await fetch(`https://w.mssg.me/${locale}/wp-json/wp/v2/pages/140`);
const pData = await data.json();
return (
<div className="page-wrapper page-wrapper-doc">
<div className="page-default-wrapper">
<article className="page-default-content">
<h1>{pData.title.rendered}</h1>
<div className="clearfix">
<div dangerouslySetInnerHTML={{ __html: pData.content.rendered }} />
</div>
</article>
</div>
</div>
);
}

View File

@ -0,0 +1,41 @@
import { getTranslations, getLocale } from 'next-intl/server';
import Link from 'next/link';
import React from 'react';
import { Metadata } from 'next';
import '@/app/ui/wppages/css/index.css';
export async function generateMetadata(): Promise<Metadata> {
const locale = await getLocale();
const t = await getTranslations({ locale });
return {
title: t('404.heading'),
description: t('404.error'),
};
}
export default async function NotFound() {
const locale = await getLocale();
const t = await getTranslations({ locale });
return (
<html lang={locale}>
<body>
<div className="page-wrapper">
<div className="header-404">
<Link href="/" className="header-404-logo">
<img src="/img/ui/logo_full.svg" alt="mssg.me logo" />
</Link>
</div>
<div className="content-404">
<div className="content-404-block">
<h1>{t('404.heading')}</h1>
<p>{t('404.error')}</p>
<Link href="/" className="button button-outline">{t('404.button')}</Link>
</div>
</div>
</div>
</body>
</html>
);
}

BIN
src/app/apple-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,42 +0,0 @@
:root {
--background: #ffffff;
--foreground: #171717;
}
@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
}
}
html,
body {
max-width: 100vw;
overflow-x: hidden;
}
body {
color: var(--foreground);
background: var(--background);
font-family: Arial, Helvetica, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
a {
color: inherit;
text-decoration: none;
}
@media (prefers-color-scheme: dark) {
html {
color-scheme: dark;
}
}

View File

@ -0,0 +1,17 @@
import { LocaleType } from '@/i18n/i18n';
export const generateAuthUrl = (lang: LocaleType, type: 'login' | 'signup') => {
const utmMideumMap = {
login: 'login_click',
signup: 'sign_up_click',
}
const baseUrl = `/auth/${type}`;
const params = new URLSearchParams({
lang,
utm_source: 'website',
utm_medium: utmMideumMap[type],
utm_campaign: 'mssgme_website',
});
return `${baseUrl}?${params.toString()}`;
}

View File

@ -1,32 +0,0 @@
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={`${geistSans.variable} ${geistMono.variable}`}>
{children}
</body>
</html>
);
}

23
src/app/manifest.ts Normal file
View File

@ -0,0 +1,23 @@
import type { MetadataRoute } from 'next'
export default function manifest(): MetadataRoute.Manifest {
return {
name: 'mssg.me',
short_name: 'mssg.me',
display: 'standalone',
background_color: '#ffffff',
theme_color: '#ffffff',
icons: [
{
src: '/favicons/android-chrome-192x192.png',
sizes: '192x192',
type: 'image/png',
},
{
src: '/favicons/android-chrome-512x512.png',
sizes: '512x512',
type: 'image/png',
},
],
}
}

21
src/app/not-found.tsx Normal file
View File

@ -0,0 +1,21 @@
import Link from 'next/link';
import React from 'react';
export default function GlobalNotFound() {
return (
<div className="page-wrapper">
<div className="header-404">
<Link href="/" className="header-404-logo">
<img src="/img/ui/logo_full.svg" alt="mssg.me logo" />
</Link>
</div>
<div className="content-404">
<div className="content-404-block">
<h1>404 Error</h1>
<p>The page doesn't exist</p>
<Link href="/" className="button button-outline">Visit Homepage</Link>
</div>
</div>
</div>
);
}

BIN
src/app/opengraph-image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

View File

@ -1,168 +0,0 @@
.page {
--gray-rgb: 0, 0, 0;
--gray-alpha-200: rgba(var(--gray-rgb), 0.08);
--gray-alpha-100: rgba(var(--gray-rgb), 0.05);
--button-primary-hover: #383838;
--button-secondary-hover: #f2f2f2;
display: grid;
grid-template-rows: 20px 1fr 20px;
align-items: center;
justify-items: center;
min-height: 100svh;
padding: 80px;
gap: 64px;
font-family: var(--font-geist-sans);
}
@media (prefers-color-scheme: dark) {
.page {
--gray-rgb: 255, 255, 255;
--gray-alpha-200: rgba(var(--gray-rgb), 0.145);
--gray-alpha-100: rgba(var(--gray-rgb), 0.06);
--button-primary-hover: #ccc;
--button-secondary-hover: #1a1a1a;
}
}
.main {
display: flex;
flex-direction: column;
gap: 32px;
grid-row-start: 2;
}
.main ol {
font-family: var(--font-geist-mono);
padding-left: 0;
margin: 0;
font-size: 14px;
line-height: 24px;
letter-spacing: -0.01em;
list-style-position: inside;
}
.main li:not(:last-of-type) {
margin-bottom: 8px;
}
.main code {
font-family: inherit;
background: var(--gray-alpha-100);
padding: 2px 4px;
border-radius: 4px;
font-weight: 600;
}
.ctas {
display: flex;
gap: 16px;
}
.ctas a {
appearance: none;
border-radius: 128px;
height: 48px;
padding: 0 20px;
border: none;
border: 1px solid transparent;
transition:
background 0.2s,
color 0.2s,
border-color 0.2s;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
line-height: 20px;
font-weight: 500;
}
a.primary {
background: var(--foreground);
color: var(--background);
gap: 8px;
}
a.secondary {
border-color: var(--gray-alpha-200);
min-width: 158px;
}
.footer {
grid-row-start: 3;
display: flex;
gap: 24px;
}
.footer a {
display: flex;
align-items: center;
gap: 8px;
}
.footer img {
flex-shrink: 0;
}
/* Enable hover only on non-touch devices */
@media (hover: hover) and (pointer: fine) {
a.primary:hover {
background: var(--button-primary-hover);
border-color: transparent;
}
a.secondary:hover {
background: var(--button-secondary-hover);
border-color: transparent;
}
.footer a:hover {
text-decoration: underline;
text-underline-offset: 4px;
}
}
@media (max-width: 600px) {
.page {
padding: 32px;
padding-bottom: 80px;
}
.main {
align-items: center;
}
.main ol {
text-align: center;
}
.ctas {
flex-direction: column;
}
.ctas a {
font-size: 14px;
height: 40px;
padding: 0 16px;
}
a.secondary {
min-width: auto;
}
.footer {
flex-wrap: wrap;
align-items: center;
justify-content: center;
}
}
@media (prefers-color-scheme: dark) {
.logo {
filter: invert();
}
}

View File

@ -1,95 +0,0 @@
import Image from "next/image";
import styles from "./page.module.css";
export default function Home() {
return (
<div className={styles.page}>
<main className={styles.main}>
<Image
className={styles.logo}
src="/next.svg"
alt="Next.js logo"
width={180}
height={38}
priority
/>
<ol>
<li>
Get started by editing <code>src/app/page.tsx</code>.
</li>
<li>Save and see your changes instantly.</li>
</ol>
<div className={styles.ctas}>
<a
className={styles.primary}
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
className={styles.logo}
src="/vercel.svg"
alt="Vercel logomark"
width={20}
height={20}
/>
Deploy now
</a>
<a
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
className={styles.secondary}
>
Read our docs
</a>
</div>
</main>
<footer className={styles.footer}>
<a
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/file.svg"
alt="File icon"
width={16}
height={16}
/>
Learn
</a>
<a
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/window.svg"
alt="Window icon"
width={16}
height={16}
/>
Examples
</a>
<a
href="https://nextjs.org?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/globe.svg"
alt="Globe icon"
width={16}
height={16}
/>
Go to nextjs.org
</a>
</footer>
</div>
);
}

13
src/app/robots.ts Normal file
View File

@ -0,0 +1,13 @@
import type { MetadataRoute } from 'next'
export default function robots(): MetadataRoute.Robots {
const { HOSTNAME, PROTOCOL } = process.env;
return {
rules: {
userAgent: '*',
disallow: '',
},
sitemap: `${PROTOCOL}://${HOSTNAME}/sitemap.xml`,
}
}

88
src/app/sitemap.ts Normal file
View File

@ -0,0 +1,88 @@
import type { MetadataRoute } from 'next'
import { LOCALES, DEFAULT_LOCALE } from '../i18n/i18n'
interface BlogPost {
slug: string;
modified: string;
}
interface WordPressPost {
slug: string;
modified: string;
}
async function getBlogPosts(): Promise<BlogPost[]> {
try {
const response = await fetch(`https://w.mssg.me/${DEFAULT_LOCALE}/wp-json/wp/v2/posts?per_page=100`);
if (!response.ok) return [];
const posts = await response.json() as WordPressPost[];
return posts.map((post: WordPressPost) => ({
slug: post.slug,
modified: post.modified
}));
} catch (error) {
console.error('Failed to fetch blog posts:', error);
return [];
}
}
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const baseUrl = 'https://mssg.me';
const staticPages = ['', '/blog', '/faq-next', '/privacy-policy', '/terms-of-use'];
const sitemap: MetadataRoute.Sitemap = [];
// Add static pages for all locales
for (const page of staticPages) {
for (const locale of LOCALES) {
const url = locale === DEFAULT_LOCALE
? `${baseUrl}${page}`
: `${baseUrl}/${locale}${page}`;
sitemap.push({
url,
lastModified: new Date(),
changeFrequency: page === '' ? 'monthly' : 'weekly',
priority: page === '' ? 1.0 : (page === '/blog' ? 0.8 : 0.5),
alternates: {
languages: Object.fromEntries(
LOCALES.map(loc => [
loc,
loc === DEFAULT_LOCALE
? `${baseUrl}${page}`
: `${baseUrl}/${loc}${page}`
])
)
}
});
}
}
// Add blog posts for all locales
const blogPosts = await getBlogPosts();
for (const post of blogPosts) {
for (const locale of LOCALES) {
const url = locale === DEFAULT_LOCALE
? `${baseUrl}/blog/${post.slug}`
: `${baseUrl}/${locale}/blog/${post.slug}`;
sitemap.push({
url,
lastModified: new Date(post.modified),
changeFrequency: 'monthly',
priority: 0.6,
alternates: {
languages: Object.fromEntries(
LOCALES.map(loc => [
loc,
loc === DEFAULT_LOCALE
? `${baseUrl}/blog/${post.slug}`
: `${baseUrl}/${loc}/blog/${post.slug}`
])
)
}
});
}
}
return sitemap;
}

View File

@ -0,0 +1,36 @@
import Script from 'next/script';
interface GoogleTagManagerProps {
gtmId: string;
}
export function GoogleTagManagerHead({ gtmId }: GoogleTagManagerProps) {
return (
<Script
id="gtm-script"
strategy="afterInteractive"
dangerouslySetInnerHTML={{
__html: `
(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),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','${gtmId}');
`,
}}
/>
);
}
export function GoogleTagManagerBody({ gtmId }: GoogleTagManagerProps) {
return (
<noscript>
<iframe
src={`https://www.googletagmanager.com/ns.html?id=${gtmId}`}
height="0"
width="0"
style={{ display: 'none', visibility: 'hidden' }}
/>
</noscript>
);
}

View File

@ -0,0 +1,18 @@
'use client';
import { LOCALES } from '@/i18n/i18n';
import { useLocale } from 'next-intl';
import { Link, usePathname } from '@/i18n/navigation';
import clsx from 'clsx';
export default function LanguageSwitcher() {
const locale = useLocale();
const pathname = usePathname();
const visibleLocales = LOCALES.filter(lang => lang !== 'ru');
return visibleLocales.map((lang) => (
<li key={lang}>
<Link href={pathname} locale={lang} className={clsx('lang-chooser', lang === locale && 'active')}>{lang.toUpperCase()}</Link>
</li>
))
}

View File

@ -0,0 +1,402 @@
'use client';
import { useEffect } from 'react';
export default function MainScripts() {
useEffect(() => {
// Fixed header
const handleScroll = () => {
const header = document.querySelector('.main-header');
if (header) {
if (window.scrollY > 0) {
header.classList.add('fixed');
} else {
header.classList.remove('fixed');
}
}
};
window.addEventListener('scroll', handleScroll);
handleScroll(); // Initial check
// Share popup function
const windowPopup = (url: string, width: number, height: number) => {
const left = screen.width / 2 - width / 2;
const top = screen.height / 2 - height / 2;
window.open(
url,
'',
`menubar=no,toolbar=no,resizable=yes,scrollbars=yes,width=${width},height=${height},top=${top},left=${left}`
);
};
// Share popup on click
const shareLinks = document.querySelectorAll('.article-share-list > li > a');
const handleShareClick = (e: Event) => {
e.preventDefault();
const target = e.currentTarget as HTMLAnchorElement;
if (target?.href) {
windowPopup(target.href, 500, 300);
}
};
shareLinks.forEach(link => {
link.addEventListener('click', handleShareClick);
});
// FAQ slider functionality
const initFaqSlider = () => {
const topControls = document.querySelectorAll('.faq-top-controls-list > li');
const sliderList = document.querySelector('.faq-sublists') as HTMLElement;
const sliderListItems = document.querySelectorAll('.faq-sublists > li') as NodeListOf<HTMLElement>;
const questionPanes = document.querySelectorAll('.faq-panes-list > li');
const hash = location.hash.substr(2);
if (!topControls.length || !sliderList || !sliderListItems.length) return;
// Build initial state
topControls[0]?.classList.add('active');
sliderListItems[0]?.classList.add('active');
const parentWidth = sliderList.parentElement?.offsetWidth || 0;
sliderListItems.forEach(item => {
item.style.width = `${parentWidth}px`;
});
// Scroll to hash in URL
if (hash !== '') {
const listIndex = parseInt(hash.substring(0, hash.indexOf('-'))) - 1;
const questionItem = document.getElementById(hash);
if (listIndex >= 0 && questionItem) {
topControls.forEach((control, index) => {
control.classList.toggle('active', index === listIndex);
});
sliderListItems.forEach((item, index) => {
item.classList.toggle('active', index === listIndex);
});
const itemWidth = sliderListItems[0]?.offsetWidth || 0;
sliderList.style.transform = `translateX(-${listIndex * itemWidth}px)`;
questionItem.classList.add('opened');
const answer = questionItem.querySelector('.faq-panes-list-item-content') as HTMLElement;
if (answer) {
answer.style.display = 'block';
}
setTimeout(() => {
const header = document.querySelector('.main-header') as HTMLElement;
const headerHeight = header?.offsetHeight || 0;
window.scrollTo({
top: questionItem.offsetTop - headerHeight - 30,
behavior: 'smooth'
});
}, 1300);
}
}
// Fixed topics on desktop
const handleFaqScroll = () => {
if (window.innerWidth > 1239) {
const faqControls = document.querySelector('.faq-top-controls-list');
if (faqControls) {
if (window.scrollY > 70) {
faqControls.classList.add('fixed');
} else {
faqControls.classList.remove('fixed');
}
}
}
};
window.addEventListener('scroll', handleFaqScroll);
// Rebuild on resize
const handleResize = () => {
const parentWidth = sliderList.parentElement?.offsetWidth || 0;
sliderListItems.forEach(item => {
item.style.width = `${parentWidth}px`;
});
};
window.addEventListener('resize', handleResize);
// Top slider controls event
const handleTopControlClick = (e: Event) => {
const target = e.currentTarget as HTMLElement;
const thisIndex = Array.from(topControls).indexOf(target);
topControls.forEach((control, index) => {
control.classList.toggle('active', index === thisIndex);
});
sliderListItems.forEach((item, index) => {
item.classList.toggle('active', index === thisIndex);
});
const itemWidth = sliderListItems[0]?.offsetWidth || 0;
sliderList.style.transform = `translateX(-${thisIndex * itemWidth}px)`;
questionPanes.forEach(pane => {
pane.classList.remove('opened');
const answer = pane.querySelector('.faq-panes-list-item-content') as HTMLElement;
if (answer) {
answer.style.display = 'none';
}
});
if (window.scrollY > 0) {
window.scrollTo({ top: 0, behavior: 'smooth' });
}
};
topControls.forEach(control => {
control.addEventListener('click', handleTopControlClick);
});
// Question pane heading click
const questionHeadings = document.querySelectorAll('.faq-panes-list-item-header');
const handleQuestionClick = (e: Event) => {
const target = e.currentTarget as HTMLElement;
const parentLi = target.closest('li');
const answer = target.nextElementSibling as HTMLElement;
if (parentLi && answer) {
window.location.hash = `#q${parentLi.id}`;
if (parentLi.classList.contains('opened')) {
parentLi.classList.remove('opened');
answer.style.display = 'none';
} else {
parentLi.classList.add('opened');
answer.style.display = 'block';
}
}
};
questionHeadings.forEach(heading => {
heading.addEventListener('click', handleQuestionClick);
});
// Accordion functionality
const accordionHeaders = document.querySelectorAll('.accordeon-header');
const handleAccordionClick = (e: Event) => {
const target = e.currentTarget as HTMLElement;
const content = target.nextElementSibling as HTMLElement;
if (content) {
if (target.classList.contains('visible')) {
content.style.display = 'none';
} else {
content.style.display = 'block';
}
target.classList.toggle('visible');
}
};
accordionHeaders.forEach(header => {
header.addEventListener('click', handleAccordionClick);
});
return () => {
window.removeEventListener('scroll', handleFaqScroll);
window.removeEventListener('resize', handleResize);
topControls.forEach(control => {
control.removeEventListener('click', handleTopControlClick);
});
questionHeadings.forEach(heading => {
heading.removeEventListener('click', handleQuestionClick);
});
accordionHeaders.forEach(header => {
header.removeEventListener('click', handleAccordionClick);
});
};
};
// Initialize FAQ slider if container exists
const faqContainer = document.querySelector('.faq-container-right');
let faqCleanup: (() => void) | undefined;
if (faqContainer) {
faqCleanup = initFaqSlider();
}
// Pricing FAQ list
const pricingFaqItems = document.querySelectorAll('.section-page-pricing-faq-list > li');
if (pricingFaqItems.length > 0) {
const firstItem = pricingFaqItems[0];
const firstHeader = firstItem.querySelector('h4');
const firstContent = firstItem.querySelector('.section-page-pricing-faq-list-item-content') as HTMLElement;
if (firstHeader && firstContent) {
firstHeader.classList.add('active');
firstContent.style.display = 'block';
}
}
const handlePricingFaqClick = (e: Event) => {
const target = e.currentTarget as HTMLElement;
const content = target.nextElementSibling as HTMLElement;
if (content) {
if (target.classList.contains('active')) {
target.classList.remove('active');
content.style.display = 'none';
} else {
target.classList.add('active');
content.style.display = 'block';
}
}
};
const pricingFaqHeaders = document.querySelectorAll('.section-page-pricing-faq-list > li > h4');
pricingFaqHeaders.forEach(header => {
header.addEventListener('click', handlePricingFaqClick);
});
// Mobile menu
const handleMobileMenuClick = (e: Event) => {
const target = e.currentTarget as HTMLElement;
const mobileMenu = document.querySelector('.mobile-menu');
const body = document.body;
if (target.classList.contains('active')) {
target.classList.remove('active');
mobileMenu?.classList.remove('active');
body.classList.remove('overflow-hidden');
} else {
target.classList.add('active');
mobileMenu?.classList.add('active');
body.classList.add('overflow-hidden');
}
};
const mobileMenuBtn = document.querySelector('.mobile-menu-btn');
if (mobileMenuBtn) {
mobileMenuBtn.addEventListener('click', handleMobileMenuClick);
}
// Pricing switcher
const handleSwitcherClick = (e: Event) => {
const target = e.currentTarget as HTMLElement;
const priceEl = document.getElementById('price');
if (priceEl) {
const priceMonthly = priceEl.getAttribute('data-price-monthly');
const priceAnnually = priceEl.getAttribute('data-price-annually');
const price = target.classList.contains('active') ? priceAnnually : priceMonthly;
target.classList.toggle('active');
priceEl.innerHTML = price || '';
}
};
const switcher = document.getElementById('switcher');
if (switcher) {
switcher.addEventListener('click', handleSwitcherClick);
}
// Cookie functions
const setCookie = (name: string, value: string, days: number) => {
let expires = '';
if (days) {
const date = new Date();
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
expires = '; expires=' + date.toUTCString();
}
document.cookie = name + '=' + (value || '') + expires + '; path=/';
};
const getCookie = (name: string): string | null => {
const nameEQ = name + '=';
const ca = document.cookie.split(';');
for (let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) === ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
}
return null;
};
// Article links with images no underline
const articleText = document.querySelector('.section-article-text');
if (articleText) {
const articleLinks = articleText.querySelectorAll('a');
articleLinks.forEach(link => {
if (link.querySelector('img')) {
link.classList.add('no-underline');
}
});
}
// Language chooser
const handleLanguageChange = (e: Event) => {
const target = e.currentTarget as HTMLElement;
const destinationLang = target.getAttribute('data-lang');
if (destinationLang) {
setCookie('lang', destinationLang, 7);
}
};
const langChoosers = document.querySelectorAll('.lang-chooser');
langChoosers.forEach(chooser => {
chooser.addEventListener('click', handleLanguageChange);
});
// Cookie acceptance
const termsAccepted = getCookie('terms_accept');
const cookieMessage = document.getElementById('cookie-message');
if (!termsAccepted && cookieMessage) {
cookieMessage.classList.add('visible');
const handleCloseCookie = () => {
setCookie('terms_accept', 'true', 365);
if (window.innerWidth > 767) {
cookieMessage.style.transform = 'translateY(100px)';
cookieMessage.style.opacity = '0';
} else {
cookieMessage.style.transform = 'translateY(-100px)';
cookieMessage.style.opacity = '0';
}
setTimeout(() => {
cookieMessage.remove();
}, 400);
};
const closeCookieBtn = document.getElementById('close-cookie');
if (closeCookieBtn) {
closeCookieBtn.addEventListener('click', handleCloseCookie);
}
} else if (cookieMessage) {
cookieMessage.remove();
}
// Cleanup function
return () => {
window.removeEventListener('scroll', handleScroll);
shareLinks.forEach(link => {
link.removeEventListener('click', handleShareClick);
});
pricingFaqHeaders.forEach(header => {
header.removeEventListener('click', handlePricingFaqClick);
});
if (mobileMenuBtn) {
mobileMenuBtn.removeEventListener('click', handleMobileMenuClick);
}
if (switcher) {
switcher.removeEventListener('click', handleSwitcherClick);
}
langChoosers.forEach(chooser => {
chooser.removeEventListener('click', handleLanguageChange);
});
if (faqCleanup) {
faqCleanup();
}
};
}, []);
return null; // This component doesn't render anything
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,2 @@
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}
/*# sourceMappingURL=normalize.min.css.map */

View File

@ -0,0 +1,120 @@
"use client";
import { useEffect } from 'react';
import lax from 'lax.js';
function setCookie(name: string, value: string, days: number) {
let expires = '';
if (days) {
const date = new Date();
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
expires = '; expires=' + date.toUTCString();
}
document.cookie = name + '=' + (value || '') + expires + '; path=/';
}
function getCookie(name: string) {
const nameEQ = name + '=';
const ca = document.cookie.split(';');
for (let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
export default function MainEffects() {
useEffect(() => {
// Cookie message logic
const cookieMessageEl = document.getElementById('cookie-message');
const closeCookieIconEl = document.getElementById('close-cookie');
const termsAccepted = getCookie('terms_accept');
if (cookieMessageEl && closeCookieIconEl) {
if (!termsAccepted) {
cookieMessageEl.classList.add('visible');
closeCookieIconEl.addEventListener('click', function handler() {
setCookie('terms_accept', 'true', 365);
cookieMessageEl.classList.add('hide');
setTimeout(function() {
cookieMessageEl.remove();
}, 400);
closeCookieIconEl.removeEventListener('click', handler);
});
} else {
cookieMessageEl.remove();
}
}
const langClick = (e: Event) => {
const target = e.target as HTMLElement;
const lang = target.getAttribute('data-tolang');
if (lang === 'ru' || lang === 'en') {
setCookie('lang', lang, 7);
}
};
document.addEventListener('click', langClick);
// Lax.js logic
lax.init();
lax.addDriver('scrollY', () => window.scrollY);
lax.addElements(
'.presentation-hero-left, .presentation-hero-right',
{
scrollY: {
translateZ: [['elInY', 'elCenterY', 'elOutY'], [-50, -1, -1]],
translateY: [['elInY', 'elCenterY', 'elOutY'], [40, 0, -30]],
scale: [['elInY', 'elCenterY', 'elOutY'], [0.9, 1, 1]],
rotateX: [['elInY', 'elCenterY', 'elOutY'], [20, 0, 0]],
},
}
);
lax.addElements(
'.presentation-hero-center, .multi-link-hero > img, .messengers-hero > img, .store-hero > img, .builder-hero > img',
{
scrollY: {
translateY: [['elInY', 'elCenterY', 'elOutY'], [10, 0, -20]],
rotateX: [['elInY', 'elCenterY', 'elOutY'], [20, 0, 0]],
},
}
);
lax.addElements(
'.multi-link-hero__icon',
{
scrollY: {
translateZ: [['elInY', 'elCenterY', 'elOutY'], [50, 1, 1]],
rotateX: [['elInY', 'elCenterY', 'elOutY'], [20, 0, 0]],
},
}
);
lax.addElements(
'.icon-hey, .message, .icon-cart, .order, .customize',
{
scrollY: {
translateZ: [['elInY', 'elCenterY', 'elOutY'], [50, 1, 1]],
rotateX: [['elInY', 'elCenterY', 'elOutY'], [20, 0, 0]],
translateY: [['elInY', 'elCenterY', 'elOutY'], [80, 0, -60]],
},
}
);
lax.addElements(
'.blocks',
{
scrollY: {
translateZ: [['elInY', 'elCenterY', 'elOutY'], [-50, -1, -1]],
rotateX: [['elInY', 'elCenterY', 'elOutY'], [20, 0, 0]],
translateY: [['elInY', 'elCenterY', 'elOutY'], [80, 0, -60]],
},
}
);
setTimeout(function() {
document.querySelectorAll('.presentation-hero > img').forEach(function(el) {
el.classList.add('no-transition');
});
}, 600);
// Cleanup
return () => {
document.removeEventListener('click', langClick);
};
}, []);
return null;
}

View File

@ -0,0 +1,71 @@
/* PAGE - 404 */
.body-404 .main-header,
.body-404 .main-footer {
display: none;
}
.body-404 .page-wrapper {
display: flex;
flex-direction: column;
padding: 0;
min-height: 100vh;
}
.header-404 {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
width: 100%;
height: 114px;
}
a.header-404-logo,
.header-404-logo {
display: block;
height: 44px;
}
.header-404-logo > img {
display: block;
height: 100%;
width: auto;
}
.content-404 {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
flex-grow: 1;
padding: 0 20px;
}
.content-404-block {
width: 600px;
max-width: 100%;
text-align: center;
padding: 0 0 176px 0;
}
.content-404-block > h1 {
font-weight: bold;
font-size: 36px;
line-height: 42px;
margin: 0 0 10px 0;
}
.content-404-block > p {
font-size: 24px;
line-height: 30px;
margin: 0 0 40px 0;
}
.content-404-block > a.button {
font-weight: bold;
}
.body-404 #mssgme_widget {
display: none;
}

View File

@ -0,0 +1,237 @@
/* SINGLE - ARTICLE */
/* SINGLE - ARTICLE - Section*/
.section-article {
padding: 40px 0 25px 0;
overflow: hidden;
}
.section-article-content {
width: 1200px;
max-width: 100%;
margin: 0 auto;
}
.section-article-header {
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding: 0 40px 0 0;
}
.section-article-header-img {
width: calc(100% - 580px);
padding-top: 43%;
position: relative;
}
.section-article-header-img > img {
display: block;
width: 100%;
height: 100%;
border-radius: 6px;
position: absolute;
top: 0;
left: 0;
object-fit: cover;
}
.section-article-header-heading {
width: 500px;
max-width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
.section-article-header-heading-content > h1 {
font-weight: bold;
font-size: 38px;
line-height: 48px;
margin: 0 0 10px 0;
}
.section-article-header-heading-content > span {
display: block;
font-size: 16px;
line-height: 24px;
color: #8e8e93;
}
.section-article-text {
width: 800px;
max-width: 100%;
padding: 100px 0 50px 0;
margin: 0 auto;
font-size: 18px;
line-height: 30px;
}
.section-article-text p {
margin: 0 0 30px 0;
}
.section-article-text h1,
.section-article-text h2 {
font-weight: bold;
font-size: 26px;
line-height: 36px;
margin: 0 0 20px 0;
}
.section-article-text h3 {
font-weight: bold;
font-size: 22px;
line-height: 32px;
margin: 0 0 20px 0;
}
.section-article-text h4 {
font-weight: bold;
font-size: 18px;
line-height: 28px;
margin: 0 0 20px 0;
}
.section-article-text h5 {
font-weight: bold;
font-size: 14px;
line-height: 24px;
margin: 0 0 20px 0;
}
.section-article-text h6 {
font-weight: bold;
font-size: 14px;
line-height: 24px;
margin: 0 0 20px 0;
}
.section-article-text ol {
list-style-type: decimal;
margin: 30px 0 30px 20px;
}
.section-article-text ul {
list-style-type: disc;
margin: 30px 0 30px 20px;
}
.section-article-text a {
display: inline-block;
vertical-align: top;
position: relative;
color: #007aff;
}
.section-article-text a.no-underline::after {
display: none;
}
.section-article-text a::after {
content: '';
display: block;
width: 100%;
height: 2px;
background-color: #007aff;
position: absolute;
bottom: 0;
left: 0;
}
.section-article-text em {
display: inline-block;
vertical-align: top;
position: relative;
font-style: normal;
text-decoration: none;
background-color: #e4f0ff;
}
.section-article-text img,
.section-article-text video,
.section-article-text iframe {
width: auto;
max-width: 100%;
height: auto;
margin: 30px auto;
}
.section-article-text img.full-width-img {
max-width: 100vw;
width: 100vw;
margin-left: calc((100% - 100vw) / 2);
}
.section-article-text p img,
.section-article-text a img {
margin-bottom: 0;
margin-top: 0;
}
.aligncenter {
display: block;
margin: 30px auto;
}
.article-share-list {
width: 800px;
max-width: 100%;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.article-share-list > li {
width: 154px;
height: 46px;
border-radius: 6px;
background-color: #111;
text-align: center;
font-weight: 500;
font-size: 15px;
line-height: 46px;
color: #fff;
margin: 0 5px;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.article-share-list > li:hover {
transform: translateY(-2px);
box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.2);
}
.article-share-list > li > a {
display: block;
width: 100%;
height: 100%;
color: #fff;
}
.article-share-list > li > a > svg {
margin: 0 4px 0 0;
font-size: 20px;
position: relative;
top: 2px;
}
.article-share-list > li.article-share-list-fb {
background-color: #4f78a3;
}
.article-share-list > li.article-share-list-twitter {
background-color: #1da1f2;
}
.article-share-list > li.article-share-list-vk {
background-color: #4f78a3;
}
.section-fp-news-content-article > h3 {
text-align: center;
margin: 0 0 60px 0;
}

View File

@ -0,0 +1,116 @@
/* BASIC STYLES */
/* ------------ */
* {
-webkit-box-sizing: border-box;
box-sizing: border-box;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
::-moz-selection {
background: #111;
color: #fff;
}
::selection {
background: #111;
color: #fff;
}
html,
body {
width: 100%;
max-width: 100vw;
background-color: #fafafa;
}
body {
font-family: 'Helvetica Neue', sans-serif;
font-size: 16px;
line-height: 26px;
font-weight: normal;
font-style: normal;
color: #111;
}
a,
a:hover,
a:focus,
a:active,
a:visited {
text-decoration: none;
outline: none;
color: #111;
}
ul,
ol {
margin: 0;
padding: 0;
list-style: none;
}
input,
textarea,
select {
border: none;
border-radius: 0;
outline: none;
padding: 0;
margin: 0;
display: block;
width: 100%;
background-color: rgba(255, 255, 255, 0);
}
textarea {
resize: none;
}
button {
background: transparent;
border-radius: 0;
border: none;
outline: none;
padding: 0;
}
.clearfix::before,
.clearfix::after {
content: '';
display: table;
}
.clearfix::after {
clear: both;
}
.overflow-hidden {
overflow: hidden;
height: 100%;
}
.text-center {
text-align: center;
}
.page-wrapper {
position: relative;
min-height: calc(100vh - 200px);
padding: 114px 0 0 0;
}
.page-wrapper > main {
width: 100%;
}
.common-content {
padding: 0 20px;
}
.mobile-only {
display: none;
}
.desktop-only {
display: block;
}

View File

@ -0,0 +1,165 @@
/* CATEGORY - BLOG */
.section-fp-news {
padding: 55px 0 60px 0;
}
.section-fp-news-content {
width: 1120px;
max-width: 100%;
margin: 0 auto;
}
.section-fp-news-content > h3 {
font-weight: bold;
font-size: 36px;
line-height: 46px;
margin: 0 0 60px 0;
padding: 0 0 0 30px;
}
.section-fp-news-content > h3 > span {
color: #666;
}
.section-fp-news-list {
width: 100%;
display: flex;
flex-wrap: wrap;
}
.section-fp-news-list > li {
position: relative;
width: 350px;
max-width: 100%;
margin: 0 35px 0 0;
box-shadow: 0 0 20px 0 rgba(31, 45, 61, 0.05);
background-color: #ffffff;
border-radius: 6px;
overflow: hidden;
transition: transform 0.6s ease, box-shadow 0.6s ease;
}
.section-fp-news-list > li:hover {
transform: translateY(-5px);
box-shadow: 0 5px 40px 0 rgba(31, 45, 61, 0.15);
}
.section-fp-news-list > li:last-of-type {
margin: 0;
}
.section-fp-news-list > li > a {
display: block;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.section-fp-news-list-item-preview {
width: 100%;
padding-top: 50%;
position: relative;
overflow: hidden;
}
.section-fp-news-list-item-preview > img {
display: block;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
object-fit: cover;
}
.section-fp-news-list-item-content {
padding: 30px;
}
.section-fp-news-list-item-content > h4 {
font-weight: bold;
font-size: 18px;
line-height: 26px;
margin: 0 0 6px 0;
}
.section-fp-news-list-item-content > span {
display: block;
font-size: 13px;
line-height: 18px;
color: #8e8e93;
}
.section-fp-intro-content-subheading {
font-size: 24px;
line-height: 34px;
margin: 0;
text-align: center;
}
.section-fp-intro-content .cta-tutorial {
display: block;
}
.section-category-blog {
padding: 80px 0 60px 0;
}
.section-category-blog-content {
width: 1120px;
max-width: 100%;
margin: 0 auto;
}
.section-category-blog-list {
justify-content: flex-start;
}
.section-category-blog-list > li {
margin: 0 35px 35px 0;
}
.section-category-blog-list > li:nth-of-type(3n),
.section-category-blog-list > li:last-of-type {
margin: 0 0 35px 0;
}
.blog-pagination {
margin: 45px 0 0 0;
text-align: center;
}
.blog-pagination-list {
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: center;
font-weight: 500;
font-size: 16px;
line-height: 30px;
}
.blog-pagination-list > li {
margin: 0 3px;
}
.blog-pagination-list > li > a {
display: block;
width: 34px;
height: 34px;
border: 2px solid transparent;
border-radius: 4px;
transition: color 0.3s ease;
}
.blog-pagination-list > li.active > a {
border-color: #111;
pointer-events: none;
}
.blog-pagination-list > li:not(.active) > a:hover {
color: #007aff;
}

View File

@ -0,0 +1,57 @@
/* COOKIE MESSAGE */
.cookie-message {
display: none;
padding: 8px 52px 8px 20px;
background-color: #fff;
border-radius: 10px;
box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.1);
position: fixed;
bottom: 24px;
left: 20px;
z-index: 1000;
font-size: 13px;
line-height: 20px;
transition: transform 0.3s ease, opacity 0.3s ease;
}
.cookie-message.visible {
display: block;
}
.cookie-message > span {
display: block;
}
.cookie-message > a {
display: inline-block;
vertical-align: top;
font-weight: 500;
color: #007aff;
transition: color 0.3s ease;
}
.cookie-message > a:hover {
color: #0061e6;
}
.close-cookie {
display: block;
width: 32px;
height: 32px;
border-radius: 4px;
background-color: #f5f5f5;
position: absolute;
top: calc(50% - 16px);
right: 10px;
cursor: pointer;
background-image: url('/img/ui/icon-close-coockies.svg');
background-size: 8px 8px;
background-position: center;
background-repeat: no-repeat;
transition: background-color 0.3s ease;
}
.close-cookie:hover {
background-color: #f1f1f1;
}

View File

@ -0,0 +1,113 @@
/* PAGE - DEFAULT */
.page-default-wrapper {
padding: 50px 25px;
}
.page-default-content {
width: 800px;
max-width: 100%;
margin: 0 auto;
}
.page-default-content > h1 {
font-weight: bold;
font-size: 38px;
line-height: 48px;
margin: 0 0 20px 0;
}
.page-default-content-text {
width: 800px;
max-width: 100%;
padding: 0 0 50px 0;
margin: 0 auto;
font-size: 18px;
line-height: 30px;
}
.page-default-content-text p {
margin: 0 0 30px 0;
}
.page-default-content-text h1,
.page-default-content-text h2 {
font-weight: bold;
font-size: 26px;
line-height: 36px;
margin: 0 0 20px 0;
}
.page-default-content-text h3 {
font-weight: bold;
font-size: 22px;
line-height: 32px;
margin: 0 0 20px 0;
}
.page-default-content-text h4 {
font-weight: bold;
font-size: 18px;
line-height: 28px;
margin: 0 0 20px 0;
}
.page-default-content-text h5 {
font-weight: bold;
font-size: 14px;
line-height: 24px;
margin: 0 0 20px 0;
}
.page-default-content-text h6 {
font-weight: bold;
font-size: 14px;
line-height: 24px;
margin: 0 0 20px 0;
}
.page-default-content-text ol {
list-style-type: decimal;
margin: 30px 0 30px 20px;
}
.page-default-content-text ul {
list-style-type: disc;
margin: 30px 0 30px 20px;
}
.page-default-content-text a {
display: inline-block;
vertical-align: top;
position: relative;
color: #007aff;
}
.page-default-content-text a::after {
content: '';
display: block;
width: 100%;
height: 2px;
background-color: #007aff;
position: absolute;
bottom: 0;
left: 0;
}
.page-default-content-text em {
display: inline-block;
vertical-align: top;
position: relative;
font-style: normal;
text-decoration: none;
background-color: #e4f0ff;
}
.page-default-content-text img,
.page-default-content-text video,
.page-default-content-text iframe {
width: 100%;
max-width: 100%;
height: auto;
margin: 0 30px;
}

View File

@ -0,0 +1,336 @@
/* PAGE - FAQ */
.page-faq {
padding: 50px 0;
overflow: hidden;
}
.page-faq-content {
width: 1120px;
max-width: 100%;
margin: 0 auto;
}
.page-faq-container {
overflow: hidden;
width: 1120px;
max-width: 100%;
margin: 0 auto;
}
.faq-container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.faq-container-left {
position: relative;
z-index: 1;
width: 430px;
max-width: 100%;
}
.faq-container-right {
width: 670px;
max-width: 100%;
}
.faq-top-controls-list.fixed {
position: fixed;
width: 100%;
max-width: 430px;
top: 94px;
}
.faq-top-controls-list > li {
position: relative;
min-height: 70px;
padding: 24px 40px 16px 90px;
border-radius: 6px;
margin: 0 0 10px 0;
cursor: pointer;
transition: background-color 0.3s ease, box-shadow 0.3s ease, color 0.3s ease;
}
.faq-top-controls-list > li:hover {
background-color: rgba(255, 255, 255, 0.8);
}
.faq-top-controls-list > li:last-of-type {
margin: 0;
}
.faq-top-controls-list > li.active {
color: #007aff;
background-color: #fff;
box-shadow: 0 0 30px 0 rgba(31, 45, 61, 0.03);
}
.faq-top-controls-list > li > img {
display: block;
width: 70px;
height: auto;
position: absolute;
top: 0;
left: 0;
transition: opacity 0.3s ease;
}
.faq-top-controls-list > li > img.active {
opacity: 0;
pointer-events: none;
}
.faq-top-controls-list > li.active > img.default {
opacity: 0;
pointer-events: none;
}
.faq-top-controls-list > li.active > img.active {
opacity: 1;
pointer-events: auto;
}
.faq-top-controls-list > li > h2 {
font-weight: 500;
font-size: 18px;
line-height: 24px;
margin: 0 0 2px 0;
}
.faq-top-controls-list > li > p {
font-size: 13px;
line-height: 20px;
opacity: 0.5;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
margin: 0;
}
.faq-sublists {
width: 10000px;
transition: -webkit-transform 1s ease;
transition: transform 1s ease;
transition: transform 1s ease, -webkit-transform 1s ease;
}
.faq-sublists > li {
float: left;
width: 670px;
max-width: 100%;
opacity: 0;
pointer-events: none;
transform: scale(0.9);
transition: opacity 0.3s ease, transform 1s ease;
}
.faq-sublists > li.active {
opacity: 1;
-webkit-transform: scale(1);
transform: scale(1);
pointer-events: auto;
transition: opacity 0.5s ease, transform 1s ease;
}
.faq-panes-list {
counter-reset: faqlist;
}
.faq-panes-list > li {
margin: 0 0 10px 0;
}
.faq-panes-list > li:last-of-type {
margin: 0;
}
.faq-panes-list-item-header {
position: relative;
padding: 20px 115px 20px 55px;
background-color: #fff;
border-radius: 6px;
box-shadow: 0 0 30px 0 rgba(31, 45, 61, 0.03);
cursor: pointer;
}
.faq-panes-list-item-header > h3 {
font-weight: 500;
font-size: 16px;
line-height: 22px;
margin: 0;
}
.accordeon-header {
position: relative;
padding: 10px 40px 10px 15px;
background-color: #fff;
border-radius: 6px;
box-shadow: 0 0 30px 0 rgba(31, 45, 61, 0.03);
cursor: pointer;
}
.faq-panes-list-item-content h4.accordeon-heading {
font-weight: 500;
font-size: 16px;
margin: 0;
}
.accordeon-header > .faq-panes-list-item-status {
right: 15px;
top: 13px;
}
.accordeon-header:hover .faq-panes-list-item-status {
background-color: #007aff;
}
.faq-panes-list > li.opened .accordeon-header.visible > .faq-panes-list-item-status::after {
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
}
.accordeon-content {
padding: 15px;
display: none;
}
.faq-panes-list-item-counter {
display: block;
position: absolute;
top: 0;
left: 30px;
font-size: 13px;
line-height: 62px;
opacity: 0.5;
}
.faq-panes-list-item-counter::before {
counter-increment: faqlist;
content: counter(faqlist, decimal-leading-zero);
}
.faq-panes-list-item-status {
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #dedede;
position: absolute;
top: 21px;
right: 30px;
transition: background-color 0.3s ease;
}
.faq-panes-list-item-header:hover .faq-panes-list-item-status {
background-color: #007aff;
}
.faq-panes-list-item-status::before {
content: '';
display: block;
width: 10px;
height: 2px;
border-radius: 1px;
background-color: #fff;
position: absolute;
top: calc(50% - 1px);
left: calc(50% - 5px);
}
.faq-panes-list-item-status::after,
.faq-panes-list > li.opened .accordeon-header > .faq-panes-list-item-status::after {
content: '';
display: block;
width: 2px;
height: 10px;
border-radius: 1px;
background-color: #fff;
position: absolute;
top: calc(50% - 5px);
left: calc(50% - 1px);
transform: none;
transition: transform 0.3s ease;
}
.faq-panes-list > li.opened .faq-panes-list-item-status::after {
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
}
.faq-panes-list-item-content {
display: none;
padding: 20px 55px 10px 55px;
font-size: 15px;
line-height: 24px;
}
.faq-panes-list-item-content p {
margin: 0 0 20px 0;
}
.faq-panes-list-item-content > *:last-child {
margin-bottom: 0;
}
.faq-panes-list-item-content img,
.faq-panes-list-item-content iframe,
.faq-panes-list-item-content video {
display: block;
max-width: 100%;
height: auto;
margin: 20px auto;
}
.faq-panes-list-item-content h1,
.faq-panes-list-item-content h2,
.faq-panes-list-item-content h3,
.faq-panes-list-item-content h4,
.faq-panes-list-item-content h5,
.faq-panes-list-item-content h6 {
font-size: 17px;
line-height: 26px;
margin: 0 0 20px 0;
}
.faq-panes-list-item-content ol,
.faq-panes-list-item-content ul {
margin: 0 0 20px 16px;
}
.faq-panes-list-item-content ol {
list-style-type: decimal;
}
.faq-panes-list-item-content ul {
list-style-type: square;
}
.faq-panes-list-item-content ol li,
.faq-panes-list-item-content ul li {
margin: 0 0 10px 0;
}
.faq-panes-list-item-content ol li:last-of-type,
.faq-panes-list-item-content ul li:last-of-type {
margin: 0;
}
.faq-panes-list-item-content strong,
.faq-panes-list-item-content b {
font-weight: 500;
}
.faq-panes-list-item-content em {
font-style: normal;
font-weight: 500;
background-color: #d5e6fb;
text-decoration: none;
}
.faq-panes-list-item-content a {
font-weight: 500;
color: #007aff;
text-decoration: underline;
}

View File

@ -0,0 +1,130 @@
/* FOOTER */
.main-footer {
padding: 40px 20px 50px 20px;
overflow: hidden;
}
.main-footer-content {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
width: 1040px;
max-width: 100%;
margin: 0 auto;
}
.main-footer-content-left {
padding: 8px 0 0 0;
}
.footer-nav-list {
display: flex;
flex-wrap: wrap;
}
.footer-nav-list > li {
max-width: 100%;
margin: 0 88px 0 0;
}
.footer-nav-list > li:last-of-type {
margin: 0;
}
.footer-nav-list > li > h6 {
font-weight: normal;
font-size: 17px;
line-height: 24px;
color: #8e8e93;
margin: 0 0 17px 0;
}
.footer-menu-list {
font-weight: 500;
font-size: 16px;
line-height: 30px;
}
.footer-menu-list > li > a {
max-width: 100%;
display: inline-block;
vertical-align: top;
transition: color 0.3s ease;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.footer-menu-list > li > a:hover {
color: #007aff;
}
.footer-socials-list {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
}
.footer-socials-list > li {
width: 40px;
height: 40px;
margin: 0 0 0 15px;
}
.footer-socials-list > li:first-of-type {
margin: 0;
}
.footer-socials-list > li > a {
display: block;
width: 100%;
height: 100%;
font-size: 24px;
line-height: 40px;
text-align: center;
}
.footer-socials-list > li > a > i {
transition: transform 0.3s ease;
}
.footer-socials-list > li > a:hover > i {
transform: translateY(-3px);
}
.lang-chooser-list {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
margin: 35px 0 0 0;
font-weight: 500;
font-size: 16px;
line-height: 22px;
}
.lang-chooser-list > li > a {
display: block;
padding: 10px 3px;
color: #8e8e93;
transition: color 0.3s ease;
}
.lang-chooser-list > li > a:hover,
.lang-chooser-list > li > a.active {
color: #111;
}
.lang-chooser-list > li > a.active {
pointer-events: none;
}
.lang-chooser-list-mobile {
display: none;
}
.main-footer-content-right {
display: flex;
align-items: flex-end;
justify-content: center;
}

View File

@ -0,0 +1,308 @@
/* HEADER */
.main-header {
position: fixed;
z-index: 100;
width: 100%;
height: 114px;
background-color: #fafafa;
will-change: transform;
padding: 34px 20px;
transition: box-shadow 0.3s ease, padding 0.3s ease, height 0.3s ease;
}
.main-header.fixed {
box-shadow: 0 0 20px 0 rgba(31, 45, 61, 0.1);
padding: 13px 20px;
height: 78px;
}
.main-header-content {
width: 1200px;
max-width: 100%;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
}
.main-header-left {
display: flex;
flex-wrap: wrap;
align-items: center;
}
.header-logo {
display: block;
height: 44px;
margin: 0 60px 0 0;
}
.header-logo > img {
display: block;
height: 100%;
width: auto;
}
.header-menu-list {
display: flex;
flex-wrap: wrap;
height: 100%;
}
.header-menu-list > li {
position: relative;
height: 100%;
}
.header-menu-list > li:last-of-type,
.header-menu-list > li:only-of-type {
margin: 0;
}
.header-menu-list > li > a,
.header-menu-list > li > span {
position: relative;
display: block;
height: 100%;
padding: 0 20px;
font-weight: 500;
font-size: 18px;
line-height: 50px;
cursor: pointer;
transition: color 0.3s ease;
}
.header-menu-list > li:not(.with-submenu) > a:hover {
color: #007aff;
}
.header-menu-list > li.with-submenu > a,
.header-menu-list > li.with-submenu > span {
padding-right: 41px;
}
.header-menu-list > li.with-submenu > a::after,
.header-menu-list > li.with-submenu > span::after {
box-sizing: border-box;
content: '';
display: block;
width: 10px;
height: 10px;
background-image: url('/img/ui/icon-arrow.svg');
-webkit-background-size: contain;
background-size: contain;
background-position: center;
background-repeat: no-repeat;
position: absolute;
right: 20px;
top: 21px;
transition: transform 0.3s ease;
}
.header-menu-list > li.with-submenu:hover > a::after,
.header-menu-list > li.with-submenu:hover > span::after {
transform: rotate(-180deg);
}
.header-buttons {
display: flex;
flex-wrap: wrap;
}
.header-submenu {
display: flex;
width: 100%;
width: 300px;
background-color: #fff;
padding: 19px 9px 16px 9px;
position: absolute;
top: 50px;
left: -10px;
border-radius: 10px;
border: 1px solid #ededde;
opacity: 0;
pointer-events: none;
transform: translateY(-10px) scale(0.9);
transition: transform 0.3s ease, opacity 0.3s ease;
}
.header-menu-list > li.with-submenu:hover .header-submenu {
opacity: 1;
pointer-events: auto;
transform: translateY(0) scale(1);
}
.header-submenu-column {
width: 50%;
padding: 0 20px;
}
.header-submenu-column > h6 {
font-weight: 500;
font-size: 14px;
line-height: 20px;
color: #007aff;
margin: 0 0 3px 0;
}
.header-submenu-column:last-of-type > h6 {
color: #5856d6;
}
.header-submenu-column > ul {
font-weight: bold;
font-size: 18px;
line-height: 30px;
}
.header-submenu-column > ul > li > a {
display: inline-block;
vertical-align: top;
transition: color 0.3s ease;
}
.header-submenu-column > ul > li > a:hover {
color: #007aff;
}
/* PRODUCTHUNT HEADER */
.producthunt-header {
width: 100%;
height: 60px;
padding: 0 30px;
background-color: #fff;
position: absolute;
top: 0;
left: 0;
display: flex;
justify-content: space-between;
align-items: center;
transition: transform 0.3s ease;
border-bottom: 1px solid #eee;
}
.main-header-with-product-hunt ~ .page-wrapper {
padding: 174px 0 0 0;
}
.producthunt-header-left {
display: flex;
align-items: center;
font-size: 16px;
line-height: 20px;
color: #000;
flex: 1;
}
.producthunt-logo {
display: block;
width: 40px;
height: 40px;
margin: 0 20px 0 0;
}
.producthunt-header-left > span {
display: block;
max-width: calc(100% - 60px);
}
.producthunt-header-left > span > i {
border: #cb5c3b dashed 1px;
padding: 2px 7px 3px;
margin: 0px 4px;
background: rgba(255, 255, 255, 0.15);
font-weight: 500;
font-style: normal;
}
.producthunt-header-right > .button-blue {
background-color: #000;
padding: 6px 20px;
}
.producthunt-header-right > .button-blue > i {
display: none;
}
.main-header-with-product-hunt {
padding-top: 80px;
height: 174px;
}
.main-header-with-product-hunt.fixed .producthunt-header {
transform: translateY(-100%);
}
@media (max-width: 1279px) {
.main-header.main-header-with-product-hunt {
padding-top: 80px;
height: 174px;
}
.main-header.main-header-with-product-hunt.fixed {
height: 78px;
}
}
@media (max-width: 767px) {
.producthunt-header {
padding: 0 10px;
}
.producthunt-logo {
margin: 0 10px 0 0;
}
.producthunt-header-right > .button-blue {
padding: 6px 7px;
}
.producthunt-header-right > .button-blue > span,
.producthunt-header-left > span > span {
display: block;
}
.producthunt-header-right > .button-blue > i {
display: none;
}
.main-header.main-header-with-product-hunt {
height: 130px;
}
.main-header-with-product-hunt ~ .page-wrapper {
padding: 130px 0 0 0;
}
.main-header.main-header-with-product-hunt.fixed {
height: 54px;
}
.main-header-with-product-hunt .mobile-menu-btn {
height: 74px;
top: 60px;
transition: top 0.3s ease;
}
.main-header-with-product-hunt.fixed .mobile-menu-btn {
height: 54px;
top: 0;
}
.main-header-with-product-hunt + .mobile-menu {
padding: 130px 0 0 0;
}
.main-header-with-product-hunt.fixed + .mobile-menu {
padding: 70px 0 0 0;
}
}
@media (max-width: 374px) {
.producthunt-header-left {
font-size: 13px;
}
}

View File

@ -0,0 +1,14 @@
@import 'normalize.css';
@import 'basic.css';
@import 'ui.css';
@import 'cookie.css';
@import 'header.css';
@import 'footer.css';
@import 'category.css';
@import 'pricing.css';
@import 'article.css';
@import 'default.css';
@import 'faq.css';
@import '404.css';
@import 'mobile.css';
@import 'mediaq.css';

View File

@ -0,0 +1,676 @@
@media all and (max-width: 1279px) {
/* Main */
.common-content {
width: 1024px;
max-width: 100%;
margin: 0 auto;
padding: 0 30px;
}
/* Header */
.main-header {
padding: 34px 30px;
}
.main-header.fixed {
padding: 13px 30px;
}
/* Footer */
.main-footer {
padding: 40px 30px 50px 30px;
}
.footer-nav-list > li {
margin: 0 60px 0 0;
}
/* CATEGORY - BLOG */
.section-category-blog {
padding: 20px 0 60px 0;
}
/* SINGLE - BLOG */
.section-article-header-img {
padding-top: 33%;
}
.section-fp-news-list > li {
width: 298px;
}
/* PAGE - FAQ */
.faq-container-left {
width: 350px;
}
.faq-container-right {
width: 604px;
}
}
@media all and (max-width: 1023px) {
/* Main */
.common-content {
width: 768px;
max-width: 100%;
margin: 0 auto;
padding: 0 20px;
}
/* Header */
.header-logo {
width: 44px;
overflow: hidden;
margin: 0 10px 0 0;
}
.header-buttons a.button-outline {
display: block;
}
/* Footer */
.main-footer {
padding: 40px 20px 50px 20px;
}
.main-footer-content-right {
width: 100%;
margin: 40px 0 0 0;
}
.main-footer-content-left {
margin: 0 auto;
}
.footer-socials-list {
justify-content: center;
}
.lang-chooser-list {
justify-content: center;
margin: 10px 0 0 0;
}
/* CATEGORY - BLOG */
.section-category-blog-list > li:last-of-type {
display: block;
}
.section-category-blog-list > li:nth-of-type(2n) {
margin: 0 0 35px 0;
}
.section-category-blog-list > li:nth-of-type(3n):not(:last-of-type) {
margin: 0 35px 35px 0;
}
/* SINGLE - BLOG */
.section-article-header-heading {
width: 400px;
}
.section-article-header-img {
width: calc(100% - 450px);
}
.section-fp-news-list > li {
width: 346px;
}
.section-fp-news-list > li:last-of-type {
display: none;
}
.section-fp-news-list > li:nth-of-type(2) {
margin: 0;
}
.section-fp-news-content > h3 {
padding: 0;
}
/* PAGE - FAQ */
.faq-container-left {
width: 300px;
}
.faq-container-right {
width: 417px;
}
/* PAGE - PRICING */
.pricing-plans-list > li {
width: 230px;
}
}
@media all and (max-width: 767px) {
/* MAIN */
.common-content {
width: 375px;
max-width: 100%;
padding: 0 20px;
}
.page-wrapper {
padding: 70px 0 0 0;
min-height: auto;
}
.button-large {
font-size: 16px;
line-height: 22px;
}
.cta-tutorial,
a.cta-tutorial {
font-size: 18px;
line-height: 24px;
text-decoration: underline;
}
.cta-tutorial > img {
margin: 2px 0 0 6px;
}
/* UI */
.soon-label-desktop {
display: none;
}
.soon-label-mobile {
display: block;
margin: 0;
position: absolute;
top: -13px;
right: 31px;
}
.mobile-only {
display: block;
}
.desktop-only {
display: none;
}
/* HEADER */
.main-header {
height: 70px;
/* padding: 18px 65px 18px 15px; */
padding: 18px 15px;
}
.main-header.fixed {
height: 54px;
/* padding: 10px 65px 10px 15px; */
padding: 10px 15px;
}
.header-logo {
width: auto;
height: 34px;
}
.header-logo + nav {
display: none;
}
.button-header {
margin: 0;
padding: 4px 10px 4px 10px;
font-size: 14px;
line-height: 20px;
}
.mobile-menu-btn {
/* display: flex; */
display: none;
flex-wrap: wrap;
justify-content: center;
align-items: center;
width: 70px;
height: 100%;
position: absolute;
top: 0;
right: 0;
}
.mobile-menu-btn-inner {
width: 22px;
height: 16px;
position: relative;
}
.mobile-menu-btn-inner > div {
width: 100%;
height: 2px;
background-color: #111;
position: absolute;
left: 0;
border-radius: 1px;
transition: transform 0.6s ease, opacity 0.6s ease;
}
.mobile-menu-btn-inner > div:nth-of-type(1) {
transform-origin: 100% 0;
top: 0;
}
.mobile-menu-btn-inner > div:nth-of-type(2) {
top: calc(50% - 1px);
}
.mobile-menu-btn-inner > div:nth-of-type(3) {
transform-origin: 100% 100%;
bottom: 0;
}
.mobile-menu-btn.active .mobile-menu-btn-inner > div:nth-of-type(1) {
transform: rotate(-45deg) translateY(-1px);
}
.mobile-menu-btn.active .mobile-menu-btn-inner > div:nth-of-type(2) {
transform: scale(0);
opacity: 0;
}
.mobile-menu-btn.active .mobile-menu-btn-inner > div:nth-of-type(3) {
transform: rotate(45deg) translateY(1px);
}
.mobile-menu {
display: block;
width: 100%;
height: 100%;
background-color: #fafafa;
padding: 70px 0 0 0;
position: fixed;
top: 0;
left: 0;
z-index: 99;
transform: translateY(-100%);
transition: transform 0.6s ease;
pointer-events: none;
will-change: transform;
}
.mobile-menu.active {
transform: translateY(0);
pointer-events: auto;
}
.mobile-menu nav {
font-weight: bold;
font-size: 24px;
line-height: 32px;
padding: 20px 35px 0 35px;
height: 100%;
padding-bottom: 100px;
overflow: auto;
}
.mobile-menu nav > ul {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.mobile-menu nav > ul > li {
margin: 0 0 40px 0;
width: 50%;
}
.mobile-menu nav > ul > li:nth-of-type(2n) {
padding: 0 0 0 35px;
}
.mobile-menu nav > ul > li > span {
display: block;
font-size: 18px;
line-height: 24px;
color: #007aff;
margin: 0 0 6px 0;
}
.mobile-menu nav > ul > li > ul > li {
margin: 0 0 6px 0;
}
.mobile-menu nav > ul > li > ul > li:last-of-type {
margin: 0;
}
.mobile-menu > a {
position: absolute;
left: 38px;
bottom: 38px;
width: calc(100% - 76px);
padding: 17px 10px 19px 10px;
text-align: center;
background-color: #fafafa;
}
/* FOOTER */
.main-footer {
padding: 30px 20px 20px 20px;
}
.main-footer-content {
width: 100%;
display: flex;
flex-direction: column-reverse;
}
.main-footer-content-right {
/* margin: 0 0 60px 0; */
margin: 0 0 20px 0;
display: none;
}
.main-footer-content-left {
width: 100%;
padding: 0;
}
.footer-nav-list {
width: 335px;
max-width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding: 0;
margin: 0 auto;
}
.footer-nav-list > li {
margin: 0 0 30px 0;
/* width: 50%; */
width: 100%;
text-align: center;
}
.footer-nav-list > li > h6 {
margin: 0 0 10px 0;
display: none;
}
.footer-menu-list {
font-size: 12px;
line-height: 25px;
opacity: 0.5;
}
.page-wrapper.page-wrapper-home {
min-height: calc(100vh - 100px);
}
.page-wrapper.page-wrapper-home .common-content {
padding: 0 25px;
}
.lang-chooser-list-desktop {
/* display: none; */
display: flex;
font-size: 14px;
line-height: 12px !important;
}
.lang-chooser-list-mobile {
width: 335px;
max-width: 100%;
margin: 0 auto;
/* display: flex; */
display: none;
justify-content: flex-start;
transform: translateX(-10px);
}
/* PAGE - PRICING */
.section-page-pricing {
padding: 20px 0;
}
.section-pricing-cta-block {
margin: 30px 0 40px 0;
}
.pricing-plans-list {
flex-direction: column;
justify-content: center;
align-items: center;
}
.pricing-plans-list > li {
width: 320px;
max-width: 100%;
margin: 0 0 30px 0;
}
.pricing-plans-list > li:last-of-type {
margin: 0;
}
.section-dropdown > ul {
width: 100%;
}
.plan-content-card {
min-height: auto;
}
.section-page-pricing-faq {
padding: 20px 0 50px 0;
}
.section-page-pricing-faq-content > h3 {
font-size: 28px;
line-height: 32px;
text-align: left;
margin: 0 0 40px 0;
padding: 0 10px;
}
.section-page-pricing-faq-list > li > h4 {
font-size: 18px;
line-height: 28px;
padding: 10px 70px 10px 20px;
}
.section-page-pricing-faq-list-item-content {
padding: 20px 20px 30px 20px;
}
/* SINGLE - BLOG */
.section-article {
padding: 0 0 30px 0;
}
.section-article-header {
display: block;
padding: 0;
}
.section-article-header-img {
width: calc(100% + 40px);
padding-top: 86%;
margin: 0 0 26px -20px;
}
.section-article-header-img > img {
border-radius: 0;
}
.section-article-header-heading {
width: 100%;
padding: 0 5px;
}
.section-article-header-heading-content > h1 {
font-size: 22px;
line-height: 30px;
margin: 0 0 8px 0;
}
.section-article-header-heading-content > span {
font-size: 15px;
line-height: 22px;
}
.section-article-text {
padding: 30px 5px 0 5px;
}
.article-share-list {
margin: 30px 0 0 0;
}
.article-share-list > li > a {
font-size: 0;
}
.article-share-list > li {
width: calc(33% - 14px);
}
.article-share-list > li > a > i {
line-height: 42px;
font-size: 26px;
margin: 0;
}
.section-fp-news-content-article .section-fp-news-content > h3 {
padding: 0;
font-size: 18px;
line-height: 28px;
text-align: center;
margin: 0 0 30px 0;
}
.section-fp-news {
padding: 15px 0 30px 0;
}
.section-fp-news-content > h3 {
padding: 0 0 0 10px;
font-size: 28px;
line-height: 36px;
margin: 0 0 60px 0;
}
.section-fp-news-list {
display: block;
width: calc(100% + 14px);
margin: 0 0 0 -7px;
}
.section-fp-news-list > li,
.section-fp-news-list > li:nth-of-type(2) {
width: 100%;
margin: 0 0 10px 0;
}
.section-fp-news-list > li:last-of-type {
display: block;
}
.section-fp-news-list-item-preview {
padding-top: 91%;
}
.section-fp-news-list-item-content {
padding: 30px 25px;
}
.section-fp-news-list-item-content > h4 {
font-size: 22px;
line-height: 28px;
}
.section-fp-news-list-item-content > span {
font-size: 15px;
line-height: 20px;
}
/* PAGE - FAQ */
.page-faq {
padding: 20px 0;
}
.faq-container-left {
width: 100%;
margin: 0 0 20px 0;
}
.faq-top-controls-list > li {
width: 100%;
float: none;
margin: 0 0 10px 0;
min-height: auto;
padding: 10px 20px 10px 50px;
}
.faq-top-controls-list > li > img {
height: 46px;
width: auto;
}
.faq-panes-list-item-status {
right: 15px;
}
.faq-panes-list-item-counter {
left: 15px;
}
.faq-panes-list-item-header {
padding: 20px 50px 20px 40px;
}
.faq-panes-list-item-content {
padding: 20px 10px 10px 10px;
}
}
@media all and (max-width: 374px) {
.common-content {
padding: 0 15px;
}
.mobile-menu nav {
padding: 20px 25px 0 25px;
}
.mobile-menu nav > ul > li:nth-of-type(2n) {
padding: 0 0 0 25px;
}
.mobile-menu > a {
width: calc(100% - 50px);
left: 25px;
bottom: 25px;
}
.button-large {
padding: 17px 30px 19px 30px;
}
.section-fp-news-list-item-preview {
padding-top: 70%;
}
}

View File

@ -0,0 +1,6 @@
/* HIDDEN MOBILE ELEMENTS */
.mobile-menu-btn,
.mobile-menu {
display: none;
}

351
src/app/ui/wppages/css/normalize.css vendored Executable file
View File

@ -0,0 +1,351 @@
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
/* Document
========================================================================== */
/**
* 1. Correct the line height in all browsers.
* 2. Prevent adjustments of font size after orientation changes in iOS.
*/
html {
line-height: 1.15; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/* Sections
========================================================================== */
/**
* Remove the margin in all browsers.
*/
body {
margin: 0;
}
/**
* Render the `main` element consistently in IE.
*/
main {
display: block;
}
/**
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/* Grouping content
========================================================================== */
/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/
hr {
box-sizing: content-box; /* 1 */
height: 0; /* 1 */
overflow: visible; /* 2 */
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
pre {
font-family: monospace; /* 1 */
font-size: 1em; /* 2 */
}
/* Text-level semantics
========================================================================== */
/**
* Remove the gray background on active links in IE 10.
*/
a {
background-color: transparent;
}
/**
* 1. Remove the bottom border in Chrome 57-
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/
abbr[title] {
border-bottom: none; /* 1 */
text-decoration: underline; /* 2 */
text-decoration: underline dotted; /* 2 */
}
/**
* Add the correct font weight in Chrome, Edge, and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
samp {
font-family: monospace; /* 1 */
font-size: 1em; /* 2 */
}
/**
* Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/* Embedded content
========================================================================== */
/**
* Remove the border on images inside links in IE 10.
*/
img {
border-style: none;
}
/* Forms
========================================================================== */
/**
* 1. Change the font styles in all browsers.
* 2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
line-height: 1.15; /* 1 */
margin: 0; /* 2 */
}
/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/
button,
input {
/* 1 */
overflow: visible;
}
/**
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/
button,
select {
/* 1 */
text-transform: none;
}
/**
* Correct the inability to style clickable types in iOS and Safari.
*/
button,
[type='button'],
[type='reset'],
[type='submit'] {
-webkit-appearance: button;
}
/**
* Remove the inner border and padding in Firefox.
*/
button::-moz-focus-inner,
[type='button']::-moz-focus-inner,
[type='reset']::-moz-focus-inner,
[type='submit']::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* Restore the focus styles unset by the previous rule.
*/
button:-moz-focusring,
[type='button']:-moz-focusring,
[type='reset']:-moz-focusring,
[type='submit']:-moz-focusring {
outline: 1px dotted ButtonText;
}
/**
* Correct the padding in Firefox.
*/
fieldset {
padding: 0.35em 0.75em 0.625em;
}
/**
* 1. Correct the text wrapping in Edge and IE.
* 2. Correct the color inheritance from `fieldset` elements in IE.
* 3. Remove the padding so developers are not caught out when they zero out
* `fieldset` elements in all browsers.
*/
legend {
box-sizing: border-box; /* 1 */
color: inherit; /* 2 */
display: table; /* 1 */
max-width: 100%; /* 1 */
padding: 0; /* 3 */
white-space: normal; /* 1 */
}
/**
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
progress {
vertical-align: baseline;
}
/**
* Remove the default vertical scrollbar in IE 10+.
*/
textarea {
overflow: auto;
}
/**
* 1. Add the correct box sizing in IE 10.
* 2. Remove the padding in IE 10.
*/
[type='checkbox'],
[type='radio'] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/
[type='number']::-webkit-inner-spin-button,
[type='number']::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Correct the odd appearance in Chrome and Safari.
* 2. Correct the outline style in Safari.
*/
[type='search'] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/**
* Remove the inner padding in Chrome and Safari on macOS.
*/
[type='search']::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* 1. Correct the inability to style clickable types in iOS and Safari.
* 2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
/* Interactive
========================================================================== */
/*
* Add the correct display in Edge, IE 10+, and Firefox.
*/
details {
display: block;
}
/*
* Add the correct display in all browsers.
*/
summary {
display: list-item;
}
/* Misc
========================================================================== */
/**
* Add the correct display in IE 10+.
*/
template {
display: none;
}
/**
* Add the correct display in IE 10.
*/
[hidden] {
display: none;
}

View File

@ -0,0 +1,433 @@
/* PAGE - PRICING */
/* PAGE - PRICING - Plans */
.section-page-pricing {
padding: 40px 0 50px 0;
}
.section-page-pricing-content {
width: 990px;
max-width: 100%;
margin: 0 auto;
}
.pricing-plans-list {
display: flex;
flex-wrap: wrap;
justify-content: center;
flex-direction: row;
}
.pricing-plans-list > li {
width: 214px;
max-width: 100%;
position: relative;
margin: 0 50px 0 50px;
}
.plan-header {
padding: 0 25px 5px 0;
}
.plan-header > h2 {
font-weight: bold;
font-size: 22px;
line-height: 28px;
margin: 0 0 15px 0;
}
.plan-header .starts-from {
font-size: 14px;
color: rgba(0, 0, 0, 0.6);
display: inline-block;
width: 100%;
margin-bottom: 8px;
}
.plan-price-block {
width: 100%;
display: flex;
flex-wrap: wrap;
}
.plan-price-block p {
font-size: 14px;
color: rgba(0, 0, 0, 0.6);
}
.plan-price {
display: block;
font-size: 24px;
line-height: 36px;
}
.plan-price i {
font-style: normal;
display: inline-block;
font-size: 46px;
font-weight: bold;
margin-left: 5px;
margin-right: 10px;
position: relative;
top: 2px;
}
.plan-price-description {
display: block;
font-size: 14px;
line-height: 14px;
margin: 3px 0 0 8px;
}
/*.plan-content-card {*/
/*padding: 25px;*/
/*border-radius: 6px;*/
/*background-color: #ededed;*/
/*position: relative;*/
/*min-height: 280px;*/
/*}*/
.plan-content-card-products-list > li {
margin: 0 0 26px 0;
}
.plan-content-card-products-list > li:last-of-type {
margin: 0;
}
.plan-content-card-products-list > li > h3 {
font-weight: bold;
font-size: 18px;
line-height: 24px;
margin: 0 0 12px 0;
}
.features-list {
font-size: 14px;
line-height: 20px;
}
.features-list > li {
margin: 0 0 12px 0;
font-size: 16px;
font-weight: normal;
line-height: 22px;
}
.features-list > li > span {
display: block;
opacity: 0.6;
font-size: 14px;
line-height: 16px;
font-weight: normal;
margin-top: 8px;
margin-bottom: 22px;
}
.features-list > li:last-of-type {
margin: 0;
}
.features-list > li > a {
text-decoration: underline;
}
.features-list > li i {
display: inline-block;
vertical-align: top;
padding: 1px 6px 2px 6px;
border-radius: 100px;
background-color: #c7c7cc;
font-weight: 500;
font-style: normal;
font-size: 12px;
line-height: 16px;
color: #fff;
margin: 0 0 0 3px;
}
a.plan-card-button {
display: flex;
flex-wrap: wrap;
width: calc(100% - 50px);
height: 50px;
justify-content: center;
align-items: center;
background-color: #c7c7cc;
border-radius: 4px;
font-weight: bold;
font-size: 16px;
line-height: 22px;
color: #fff;
text-align: center;
position: absolute;
bottom: 25px;
left: 25px;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
a.plan-card-button:hover {
transform: translateY(-2px);
box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.1);
}
a.plan-card-button > span {
display: block;
width: 100%;
font-weight: normal;
font-size: 13px;
line-height: 18px;
margin: -12px 0 0 0;
}
a.plan-card-button-blue {
background-color: #007aff;
}
a.plan-card-button-blue:hover {
box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.2);
}
.section-pricing-cta-block {
margin: 10px 0 40px 0;
text-align: center;
}
.section-pricing-cta-block .button {
width: 100%;
}
/* PAGE - PRICING - FAQ */
.section-page-pricing-faq {
padding: 50px 0 100px 0;
}
.section-page-pricing-faq-content {
width: 690px;
max-width: 100%;
margin: 0 auto;
}
.section-page-pricing-faq-content > h3 {
font-weight: bold;
font-size: 44px;
line-height: 50px;
text-align: center;
margin: 0 0 30px 0;
}
.section-page-pricing-faq-list {
width: 600px;
margin: 0 auto;
max-width: 100%;
}
.section-page-pricing-faq-list > li {
margin: 0 0 10px 0;
}
.section-page-pricing-faq-list > li:last-of-type {
margin: 0;
}
.section-page-pricing-faq-list > li > h4 {
display: flex;
flex-wrap: wrap;
align-items: center;
position: relative;
font-weight: bold;
font-size: 24px;
line-height: 34px;
min-height: 80px;
margin: 0;
padding: 10px 80px 10px 20px;
background-color: #ededed;
border-radius: 6px;
cursor: pointer;
}
.section-page-pricing-faq-list > li > h4::before,
.section-page-pricing-faq-list > li > h4::after {
content: '';
width: 14px;
height: 1px;
background-color: #111;
position: absolute;
top: 50%;
right: 33px;
transition: transform 0.3s ease;
}
.section-page-pricing-faq-list > li > h4.active::after {
transform: rotate(-90deg);
}
.section-page-pricing-faq-list-item-content {
font-size: 16px;
line-height: 24px;
display: none;
padding: 20px 80px 30px 20px;
overflow: hidden;
}
.section-page-pricing-faq-list-item-content p {
margin: 0 0 16px 0;
}
.section-page-pricing-faq-list-item-content p:last-of-type {
margin: 0;
}
.section-page-pricing-faq-list-item-content a {
text-decoration: underline;
}
.section-page-pricing-faq-list-item-content ol {
list-style-type: decimal;
padding: 0 0 0 18px;
}
.section-page-pricing-faq-ps {
width: 600px;
max-width: 100%;
font-size: 16px;
line-height: 24px;
padding: 0 80px 0 20px;
margin: 40px auto 0 auto;
}
.section-dropdown {
width: 100%;
background: url('/static/website/img/icons/chevron-down.svg');
background-repeat: no-repeat;
background-position: right 3px top 14px;
background-size: 18px;
position: relative;
}
.section-dropdown.open {
background: url('/static/website/img/icons/chevron-up.svg');
background-repeat: no-repeat;
background-position: right 3px top 14px;
background-size: 18px;
}
.section-dropdown > span {
font-size: 14px;
color: rgba(0, 0, 0, 0.6);
cursor: pointer;
}
.section-dropdown > span > i {
display: inline-block;
color: #007aff;
font-style: normal;
width: 100%;
position: relative;
top: -5px;
}
.section-dropdown > ul {
background: black;
color: white;
border-radius: 4px;
padding: 10px;
font-size: 14px;
width: 215px;
position: absolute;
top: 56px;
left: 0;
height: 0px;
opacity: 0;
z-index: -1;
transition: all 0.3s ease;
}
.section-dropdown > ul > li {
font-weight: bold;
}
.section-dropdown > ul > li:first-of-type {
font-weight: normal;
}
.section-dropdown > ul > li:last-of-type {
font-weight: normal;
text-align: center;
padding-top: 10px;
}
.section-dropdown > ul > li:last-of-type > a {
color: #007aff;
display: inline-block;
width: 100%;
}
.section-dropdown > ul > li > span {
float: right;
}
.section-dropdown.open > ul {
height: 286px;
opacity: 1;
z-index: 1;
}
.free .plan-header > h2 {
margin-bottom: 47px;
}
.free .plan-header {
padding: 0 25px 3px 0;
}
.free .plan-header p {
font-size: 14px;
color: rgba(0, 0, 0, 0.6);
margin: 8px 0 24px 0;
}
.switch-section {
text-align: center;
margin-bottom: 30px;
}
.switcher {
display: inline-block;
position: relative;
border-radius: 36px;
background: #fff;
box-shadow: 0 2px 30px 0 rgba(0, 0, 0, 0.08);
padding: 6px;
margin-top: 32px;
}
.switcher div {
float: left;
padding: 7px 24px 5px 24px;
text-align: center;
cursor: pointer;
position: relative;
z-index: 2;
min-width: 141px;
line-height: 16px;
font-size: 16px;
transition: all 0.3s cubic-bezier(0.39, 0.58, 0.57, 1);
}
.switcher div:nth-child(1) {
color: #fff;
}
.switcher:after {
content: ' ';
display: block;
width: 141px;
height: 28px;
position: absolute;
top: 6px;
left: 7px;
border-radius: 36px;
background: #3eb991;
z-index: 1;
transform: translate3d(0, 0, 0);
transition: all 0.3s ease;
}
.switcher.active:after {
transform: translate3d(140px, 0, 0);
}
.switcher.active div:nth-child(1) {
color: #000;
}
.switcher.active div:nth-child(2) {
color: #fff;
}
.switcher:before {
content: attr(data-discount);
position: absolute;
color: #e13434;
font-size: 12px;
font-weight: bold;
width: 141px;
left: 6px;
top: -26px;
text-align: center;
}

View File

@ -0,0 +1,165 @@
/* UI */
.button {
display: inline-block;
vertical-align: top;
border: 2px solid #262a34;
padding: 10px 26px;
border-radius: 4px;
font-weight: 500;
font-size: 16px;
line-height: 22px;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.button:hover {
transform: translateY(-2px);
box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.2);
}
.button-header {
display: block;
margin: 0 0 0 10px;
}
.button-outline {
background-color: transparent;
}
.button-fill {
border-color: transparent;
}
.button-blue,
a.button-blue {
background-color: #007aff;
color: #fff;
}
.button-blue:hover {
color: #fff;
}
.button-white,
a.button-white {
background-color: #fff;
color: #007aff;
}
.button-white:hover {
color: #007aff;
}
.button-black,
a.button-black {
background-color: #111;
color: #fff;
}
.button-black:hover {
color: #fff;
}
.button-large {
padding: 17px 39px 19px 39px;
font-weight: bold;
font-size: 18px;
line-height: 24px;
}
.button-standart {
padding: 7px 19px 9px 19px;
font-weight: bold;
font-size: 16px;
line-height: 30px;
}
.decor-label {
display: inline-block;
vertical-align: top;
position: relative;
font-weight: bold;
transition: transform 0.3s ease;
}
.decor-label::before {
box-sizing: border-box;
content: '';
display: block;
width: calc(100% + 4px);
height: 100%;
border-radius: 4px;
transform: rotate(1deg);
background-color: rgba(0, 122, 255, 0.15);
position: absolute;
top: 0;
left: -2px;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.decor-label:hover {
transform: translateY(-2px);
}
.decor-label:hover::before {
transform: rotate(0deg);
}
.decor-label > span {
position: relative;
color: #007aff;
}
.decor-label-skew-right::before {
transform: rotate(-1deg);
}
.decor-label-violet > span {
color: #5856d6;
}
.decor-label-violet::before {
background-color: #5856d6;
opacity: 0.15;
}
.cta-tutorial,
a.cta-tutorial {
/* display: inline-block; */
vertical-align: top;
font-size: 21px;
line-height: 28px;
color: #0070c9;
margin: 20px 0 0 0;
display: none;
text-decoration: underline;
}
.cta-tutorial > img {
display: inline-block;
vertical-align: top;
width: auto;
height: 22px;
margin: 3px 0 0 6px;
}
.soon-label {
display: inline-block;
padding: 4px 34px 2px 12px;
border-radius: 100px;
background-color: #111;
font-weight: 500;
font-size: 14px;
line-height: 20px;
color: #fff;
background-image: url('/img/ui/image-man-manager-1x.png');
-webkit-background-size: 18px 20px;
background-size: 18px 20px;
background-position: calc(100% - 12px) 100%;
background-repeat: no-repeat;
margin: 16px 0 0 0;
}
.soon-label-mobile {
display: none;
}

View File

@ -0,0 +1,269 @@
import $ from 'jquery';
$(document).ready(function() {
// Fixed header
$(window).on('scroll load', function() {
if ($(document).scrollTop() > 0) {
$('.main-header').addClass('fixed');
} else {
$('.main-header').removeClass('fixed');
}
});
// Share popup
function windowPopup(url, width, height) {
const left = screen.width / 2 - width / 2,
top = screen.height / 2 - height / 2;
window.open(
url,
'',
'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,width=' +
width +
',height=' +
height +
',top=' +
top +
',left=' +
left
);
}
// Share popup on click
$('.article-share-list > li > a').on('click', function(e) {
e.preventDefault();
windowPopup($(this).attr('href'), 500, 300);
});
// FAQ slider
function faqSlider() {
const topControls = $('.faq-top-controls-list > li'),
sliderList = $('.faq-sublists'),
sliderListItem = sliderList.children('li'),
questionPane = $('.faq-panes-list > li'),
questionPaneHeading = questionPane.find('.faq-panes-list-item-header'),
questionPaneAnswer = questionPane.find('.faq-panes-list-item-content'),
hash = location.hash.substr(2);
// Build
topControls.eq(0).addClass('active');
sliderListItem.eq(0).addClass('active');
sliderListItem.outerWidth(sliderList.parent().outerWidth());
// Scroll to hash in url
if (hash != '') {
const listIndex = hash.substring(0, hash.indexOf('-')) - 1,
questionItem = $('#' + hash);
topControls
.removeClass('active')
.eq(listIndex)
.addClass('active');
sliderListItem
.removeClass('active')
.eq(listIndex)
.addClass('active');
sliderList.css('transform', 'translateX(-' + listIndex * sliderListItem.outerWidth() + 'px)');
questionItem
.addClass('opened')
.find(questionPaneAnswer)
.slideDown(300);
$('html, body')
.delay(1300)
.animate({ scrollTop: questionItem.offset().top - $('.main-header').outerHeight() - 30 }, 600);
}
// Fixed topics on desktop
$(window).on('scroll', function() {
if ($(window).width() > 1239) {
if ($(window).scrollTop() > 70) {
$('.faq-top-controls-list').addClass('fixed');
} else {
$('.faq-top-controls-list').removeClass('fixed');
}
}
});
// Rebuild on resize
$(window).on('resize', function() {
sliderListItem.outerWidth(sliderList.parent().outerWidth());
});
// Top slider controls event
topControls.on('click', function() {
const thisIndex = $(this).index();
topControls
.removeClass('active')
.eq(thisIndex)
.addClass('active');
sliderListItem
.removeClass('active')
.eq(thisIndex)
.addClass('active');
sliderList.css('transform', 'translateX(-' + thisIndex * sliderListItem.outerWidth() + 'px)');
questionPane
.removeClass('opened')
.find(questionPaneAnswer)
.slideUp(1000);
if ($(window).scrollTop() > 0) {
$('html, body').animate({ scrollTop: 0 }, 1000);
}
});
// Uncollapse item
questionPaneHeading.on('click', function() {
window.location.hash =
'#q' +
$(this)
.parent('li')
.attr('id');
if (
$(this)
.parent('li')
.hasClass('opened')
) {
$(this)
.parent('li')
.removeClass('opened');
$(this)
.next(questionPaneAnswer)
.slideUp(300);
} else {
$(this)
.parent('li')
.addClass('opened');
$(this)
.next(questionPaneAnswer)
.slideDown(300);
}
});
// Toggle accordion
$('.accordeon-header').on('click', function() {
const contentEl = $(this).next('.accordeon-content');
if ($(this).hasClass('visible')) {
contentEl.slideUp(300);
} else {
contentEl.slideDown(300);
}
$(this).toggleClass('visible');
});
}
// Init slider
if ($('.faq-container-right')) faqSlider();
// Pricing FAQ list
$('.section-page-pricing-faq-list > li')
.eq(0)
.children('h4')
.addClass('active')
.next('.section-page-pricing-faq-list-item-content')
.slideDown(600);
$('.section-page-pricing-faq-list > li > h4').on('click', function() {
if ($(this).hasClass('active')) {
$(this).removeClass('active');
$(this)
.next('.section-page-pricing-faq-list-item-content')
.slideUp(600);
} else {
$(this).addClass('active');
$(this)
.next('.section-page-pricing-faq-list-item-content')
.slideDown(600);
}
});
// Mobile menu
$('.mobile-menu-btn').on('click', function() {
if ($(this).hasClass('active')) {
$(this).removeClass('active');
$('.mobile-menu').removeClass('active');
$('body').removeClass('overflow-hidden');
} else {
$(this).addClass('active');
$('.mobile-menu').addClass('active');
$('body').addClass('overflow-hidden');
}
});
// Pricing switcher
$('#switcher').on('click', function() {
const priceEl = $('#price');
const switcherEl = $(this);
const price = switcherEl.hasClass('active') ? priceEl.data('priceAnnually') : priceEl.data('priceMonthly');
switcherEl.toggleClass('active');
priceEl.html(price);
});
// Cookies functions
function setCookie(name, value, days) {
let expires = '';
if (days) {
var date = new Date();
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
expires = '; expires=' + date.toUTCString();
}
document.cookie = name + '=' + (value || '') + expires + '; path=/';
}
function getCookie(name) {
const nameEQ = name + '=';
let ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
// Article links with images no underline
if ($('.section-article-text')) {
$('.section-article-text a').each(function() {
$(this)
.has('img')
.addClass('no-underline');
});
}
// Change language
$('.lang-chooser').on('click', function() {
const destinationLang = $(this).data('lang');
setCookie('lang', destinationLang, 7);
});
// Accept cookie
const termsAccepted = getCookie('terms_accept');
if (!termsAccepted) {
$('#cookie-message').addClass('visible');
$('#close-cookie').on('click', function() {
setCookie('terms_accept', 'true', 365);
if ($(window).width() > 767) {
$('#cookie-message').css({
transform: 'translateY(100px)',
opacity: 0,
});
} else {
$('#cookie-message').css({
transform: 'translateY(-100px)',
opacity: 0,
});
}
setTimeout(function() {
$('#cookie-message').remove();
}, 400);
});
} else {
$('#cookie-message').remove();
}
});

3
src/i18n/i18n.ts Normal file
View File

@ -0,0 +1,3 @@
export const LOCALES = ['en', 'uk', 'ru', 'es', 'pt', 'th'] as const;
export type LocaleType = typeof LOCALES[number];
export const DEFAULT_LOCALE = 'en';

4
src/i18n/navigation.ts Normal file
View File

@ -0,0 +1,4 @@
import { createNavigation } from 'next-intl/navigation';
import { routing } from './routing';
export const { Link, redirect, usePathname, useRouter, getPathname } = createNavigation(routing);

15
src/i18n/request.ts Normal file
View File

@ -0,0 +1,15 @@
import { getRequestConfig } from 'next-intl/server';
import { hasLocale } from 'next-intl';
import { routing } from './routing';
export default getRequestConfig(async ({ requestLocale }) => {
const requested = await requestLocale;
const locale = hasLocale(routing.locales, requested)
? requested
: routing.defaultLocale;
return {
locale,
messages: (await import(`../../messages/${locale}.json`)).default
};
});

8
src/i18n/routing.ts Normal file
View File

@ -0,0 +1,8 @@
import { defineRouting } from 'next-intl/routing';
import { DEFAULT_LOCALE, LOCALES } from './i18n';
export const routing = defineRouting({
locales: LOCALES,
defaultLocale: DEFAULT_LOCALE,
localePrefix: 'as-needed',
});

24
src/lax.d.ts vendored Normal file
View File

@ -0,0 +1,24 @@
declare module 'lax.js' {
interface LaxAnimationValue {
[key: string]: [string[], number[]];
}
interface LaxElementConfig {
scrollY?: LaxAnimationValue;
[key: string]: LaxAnimationValue | undefined;
}
interface Lax {
init: () => void;
addDriver: (name: string, callback: () => number) => void;
addElement: (selector: string, config: LaxElementConfig) => void;
addElements: (selector: string, config: LaxElementConfig) => void;
removeElement: (selector: string) => void;
removeElements: (selector: string) => void;
updateElements: () => void;
destroy: () => void;
}
const lax: Lax;
export default lax;
}

5
src/lib/fontawesome.ts Normal file
View File

@ -0,0 +1,5 @@
import { config } from '@fortawesome/fontawesome-svg-core'
import '@fortawesome/fontawesome-svg-core/styles.css'
// Tell Font Awesome to skip adding the CSS automatically since it's being imported above
config.autoAddCss = false

11
src/middleware.ts Normal file
View File

@ -0,0 +1,11 @@
import createMiddleware from 'next-intl/middleware';
import { routing } from './i18n/routing';
export default createMiddleware(routing);
export const config = {
// Match all pathnames except for
// - … if they start with `/api`, `/trpc`, `/_next` or `/_vercel`
// - … the ones containing a dot (e.g. `favicon.ico`)
matcher: '/((?!api|trpc|_next|_vercel|.*\\..*).*)'
};