Initial commit — Aspekter VA email builder

Full project: Svelte 5 frontend, Vite 7 backend API,
Pug email templates (email-gen), Docker deployment.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sergey Zotov
2026-04-13 01:20:24 +05:00
commit c090bfcf47
61 changed files with 18907 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
# email-gen overrides
This folder stores local overrides mounted into `email-gen-api` container.
Scope now:
- `reaspekt-master` only
- mounted files:
- `blocks/_factory.pug`
- `blocks/buttons.pug`
- `blocks/texts.pug`
- `blocks/texts-ext.pug`
- `blocks/other-ext.pug`
Why:
- keep customizations outside `email-gen` repo
- `git pull` in `email-gen` does not remove these local overrides

View File

@@ -0,0 +1,323 @@
// Reaspekt master shared factory mixins
mixin ctaButtonSection(opts = {})
- const width = opts.width || 560
- const text = opts.text || '#ТЕКСТ#'
- const href = opts.href || '#ССЫЛКА#'
- const buttonBg = opts.buttonBg || '#ffffff'
- const buttonText = opts.buttonText || '#130F33'
- const iconSrc = opts.iconSrc || 'https://574922.selcdn.ru/email.static/reaspekt/2024_newsletters/2024_09_29/icon-watch-white.png'
if width === 560
tr
td.padding-wrapper
+buttonRounded(text, href, 560, 60, buttonBg, 16, buttonText, 0, '', iconSrc, 20, 17, 1, 'right').textVerdana
else if width === 270
tr
td.padding-wrapper
+defaultTable('560')
tr
td(width='270')
+buttonRounded(text, href, 270, 60, buttonBg, 16, buttonText, 0, '', iconSrc, 20, 17, 1, 'right').textVerdana
+tdFixed(20)
td(width='270')
+buttonRounded(text, href, 270, 60, buttonBg, 16, buttonText, 0, '', iconSrc, 20, 17, 1, 'right').textVerdana
else if width === 173
tr
td.padding-wrapper
+defaultTable('560')
tr
td(width='173')
+buttonRounded(text, href, 173, 60, buttonBg, 16, buttonText, 0, '', iconSrc, 20, 17, 1, 'right').textVerdana
+tdFixed(21)
td(width='173')
+buttonRounded(text, href, 173, 60, buttonBg, 16, buttonText, 0, '', iconSrc, 20, 17, 1, 'right').textVerdana
+tdFixed(20)
td(width='173')
+buttonRounded(text, href, 173, 60, buttonBg, 16, buttonText, 0, '', iconSrc, 20, 17, 1, 'right').textVerdana
mixin ctaLinkSection(opts = {})
- const width = opts.width || 560
- const href = opts.href || ''
- const linkText = opts.linkText || (width === 173 ? 'Любой текст' : 'Как не терять наши письма?')
- const colorClass = opts.colorClass || 'color__blue'
- const linkClass = opts.linkClass || 'text__link-blue'
- const linkColorClass = opts.linkColorClass || textClass
- const tableWidth = opts.tableWidth || '560'
if width === 560
tr
td(align='center').padding-wrapper
a(href=href target='_blank').textVerdana(class=`${colorClass} text__link ${linkClass}`)= linkText
else if width === 270
tr
td.padding-wrapper
+defaultTable(tableWidth)
tr
td(width='270' align='center')
a(href=href target='_blank').textVerdana(class=`${colorClass} text__link ${linkClass}`)= linkText
+tdFixed(20)
td(width='270' align='center')
a(href=href target='_blank').textVerdana(class=`${colorClass} text__link ${linkClass}`)= linkText
else if width === 173
tr
td.padding-wrapper
+defaultTable(tableWidth)
tr
td(width='173' align='center')
a(href=href target='_blank').textVerdana(class=`${colorClass} text__link ${linkClass}`)= linkText
+tdFixed(21)
td(width='173' align='center')
a(href=href target='_blank').textVerdana(class=`${colorClass} text__link ${linkClass}`)= linkText
+tdFixed(20)
td(width='173' align='center')
a(href=href target='_blank').textVerdana(class=`${colorClass} text__link ${linkClass}`)= linkText
mixin contentCardInner(opts = {})
- const width = opts.width || 560
- const titleClass = opts.titleClass || 'color__blue'
- const textClass = opts.textClass || 'color__blue'
- const titleSizeClass = opts.titleSizeClass || 'header__h1'
- const title = opts.title || 'Контекстная реклама для увеличения продаж'
- const text = opts.text || 'Наша команда стала активнее участвовать в образовательных мероприятиях, на которых мы делимся тонкостями своей работы и рассказываем о практическом опыте. Решили поделиться с вами записями прошедших вебинаров. Вот сводка тем:'
- const buttonBg = opts.buttonBg || '#ffffff'
- const buttonText = opts.buttonText || '#130F33'
- const withImage = !!opts.withImage
- const imageSrc = opts.imageSrc || 'https://574922.selcdn.ru/email.static/reaspekt/master-tamplate/banners/banner-50-percent.jpg'
+defaultTable(`${width}`)
if withImage
tr
td
+backgroundImageBlock(imageSrc, width, 180, '#ffffff', 'left', 'top')
+spacerLine(20)
tr
td
span.textVerdana(class=`${titleSizeClass} ${titleClass}`)= title
+spacerLine(20)
if opts.firstColumnExtraGap
+spacerLine(20)
tr
td
span.textVerdana.text__normal(class=textClass)= text
+spacerLine(20)
tr
td
+buttonRounded('#ТЕКСТ#', '#ССЫЛКА#', width, 60, buttonBg, 16, buttonText, 0, '').textVerdana
mixin textSection560(opts = {})
tr
td.padding-wrapper(class=opts.bgClass || 'background__white')
+defaultTable('560')
+spacerLine(40)
tr
td
span.textVerdana.header__h1(class=opts.titleClass || 'color__blue') Мы продолжаем делать вебинары для вас, а чтобы следить за актуальными темами, подписывайтесь на наше сообщество ВКонтакте
+spacerLine(20)
tr
td
span.textVerdana.text__normal(class=opts.textClass || 'color__blue') Наша команда стала активнее участвовать в образовательных мероприятиях, на которых мы делимся тонкостями своей работы и рассказываем о практическом опыте. Решили поделиться с вами записями прошедших вебинаров. Вот сводка тем:
+spacerLine(20)
tr
td
+buttonRounded('#ТЕКСТ#', '#ССЫЛКА#', 560, 60, opts.buttonBg || '#ffffff', 16, opts.buttonText || '#130F33', 0, '').textVerdana
+spacerLine(40)
mixin textSection270(opts = {})
tr
td.padding-wrapper(class=opts.bgClass || 'background__white')
+defaultTable('560')
+spacerLine(40, 3)
tr
td(valign='top')
+contentCardInner({
width: 270,
withImage: true,
titleClass: opts.titleClass,
textClass: opts.textClass,
buttonBg: opts.buttonBg,
buttonText: opts.buttonText
})
+tdFixed(20)
td(valign='top')
+contentCardInner({
width: 270,
withImage: true,
titleClass: opts.titleClass,
textClass: opts.textClass,
buttonBg: opts.buttonBg,
buttonText: opts.buttonText
})
+spacerLine(40, 3)
mixin textSection173(opts = {})
tr
td.padding-wrapper(class=opts.bgClass || 'background__white')
+defaultTable('560')
+spacerLine(40, 5)
mixin textImageSection560(opts = {})
- const title = opts.title || 'Мы продолжаем делать вебинары для вас, а чтобы следить за актуальными темами, подписывайтесь на наше сообщество ВКонтакте'
- const text = opts.text || 'Наша команда стала активнее участвовать в образовательных мероприятиях, на которых мы делимся тонкостями своей работы и рассказываем о практическом опыте. Решили поделиться с вами записями прошедших вебинаров. Вот сводка тем:'
- const imageSrc = opts.imageSrc || 'https://574922.selcdn.ru/email.static/reaspekt/master-tamplate/banners/image.jpg'
- const bgClass = opts.bgClass || 'background__white'
- const titleClass = opts.titleClass || 'color__blue'
- const textClass = opts.textClass || 'color__blue'
- const buttonBg = opts.buttonBg || '#ffffff'
- const buttonText = opts.buttonText || '#130F33'
- const showTitle = opts.showTitle !== false
- const showText = opts.showText !== false
- const showButton = !!opts.showButton
- const textBeforeImage = !!opts.textBeforeImage
- const center = !!opts.center
- const linkMode = !!opts.linkMode
- const linkHref = opts.linkHref || ''
- const linkText = opts.linkText || 'Как не терять наши письма?'
- const linkClass = opts.linkClass || 'text__link-blue'
tr
td.padding-wrapper(class=bgClass)
+defaultTable('560')
+spacerLine(40)
if showTitle && !textBeforeImage
tr
td(class=center ? 'text__center' : '')
span.textVerdana.header__h1(class=titleClass)= title
+spacerLine(20)
if showText && textBeforeImage
tr
td(class=center ? 'text__center' : '')
span.textVerdana.text__normal(class=textClass)= text
+spacerLine(20)
tr
td
+backgroundImageBlock(imageSrc, 560, 266, '#ffffff', 'left', 'top')
if showText && !textBeforeImage
+spacerLine(20)
tr
td(class=center ? 'text__center' : '')
span.textVerdana.text__normal(class=textClass)= text
if showButton
+spacerLine(20)
tr
td
if linkMode
a(href=linkHref target='_blank' style='width: 100%;').textVerdana(class=`${linkColorClass} text__link ${linkClass}`)= linkText
else
+buttonRounded('#ТЕКСТ#', '#ССЫЛКА#', 560, 60, buttonBg, 16, buttonText, 0, '').textVerdana
+spacerLine(40)
mixin contentCardImage270(opts = {})
- const title = opts.title || 'Контекстная реклама для увеличения продаж'
- const text = opts.text || 'Наша команда стала активнее участвовать в образовательных мероприятиях, на которых мы делимся тонкостями своей работы и рассказываем о практическом опыте. Решили поделиться с вами записями прошедших вебинаров. Вот сводка тем:'
- const imageSrc = opts.imageSrc || 'https://574922.selcdn.ru/email.static/reaspekt/master-tamplate/banners/image.jpg'
- const titleClass = opts.titleClass || 'color__blue'
- const textClass = opts.textClass || 'color__blue'
- const buttonBg = opts.buttonBg || '#ffffff'
- const buttonText = opts.buttonText || '#130F33'
- const showButton = !!opts.showButton
- const linkMode = !!opts.linkMode
- const linkHref = opts.linkHref || ''
- const linkText = opts.linkText || 'Как не терять наши письма?'
- const linkClass = opts.linkClass || 'text__link-blue'
- const linkColorClass = opts.linkColorClass || textClass
+defaultTable('270')
tr
td
+backgroundImageBlock(imageSrc, 270, 270, '#ffffff', 'left', 'top')
+spacerLine(20)
tr
td
span.textVerdana.header__h2(class=titleClass)= title
+spacerLine(20)
tr
td
span.textVerdana.text__normal(class=textClass)= text
if showButton
+spacerLine(20)
tr
td
if linkMode
a(href=linkHref target='_blank' style='width: 100%;').textVerdana(class=`${linkColorClass} text__link ${linkClass}`)= linkText
else
+buttonRounded('#ТЕКСТ#', '#ССЫЛКА#', 270, 60, buttonBg, 16, buttonText, 0, '').textVerdana
mixin textImageSection270(opts = {})
- const bgClass = opts.bgClass || 'background__white'
tr
td.padding-wrapper(class=bgClass)
+defaultTable('560')
+spacerLine(40, 3)
tr
td(valign='top')
+contentCardImage270(opts)
+tdFixed(20)
td(valign='top')
+contentCardImage270(opts)
+spacerLine(40, 3)
tr
td(valign='top')
+contentCardInner({
width: 173,
withImage: false,
titleSizeClass: 'header__h2',
titleClass: opts.titleClass,
textClass: opts.textClass,
buttonBg: opts.buttonBg,
buttonText: opts.buttonText,
firstColumnExtraGap: !!opts.firstColumnExtraGap
})
+tdFixed(20)
td(valign='top')
+contentCardInner({
width: 173,
withImage: false,
titleSizeClass: 'header__h2',
titleClass: opts.titleClass,
textClass: opts.textClass,
buttonBg: opts.buttonBg,
buttonText: opts.buttonText
})
+tdFixed(21)
td(valign='top')
+contentCardInner({
width: 173,
withImage: false,
titleSizeClass: 'header__h2',
titleClass: opts.titleClass,
textClass: opts.textClass,
buttonBg: opts.buttonBg,
buttonText: opts.buttonText
})
+spacerLine(40, 5)
mixin sideImageTextSection(opts = {})
- const bgClass = opts.bgClass || 'background__blue'
- const textClass = opts.textClass || 'color__white'
- const imageSrc = opts.imageSrc || 'https://574922.selcdn.ru/email.static/reaspekt/master-tamplate/banners/icons-box-blue.png'
- const imageBg = opts.imageBg || '#130F33'
- const text1 = opts.text1 || 'Искусственный интеллект может ускорить работу SEO-специалистов и&nbsp;оптимизировать затраты. Заменяет&nbsp;ли&nbsp;chatGPT копирайтера? Всем&nbsp;ли&nbsp;поможет такой подход? Об&nbsp;этом и&nbsp;не&nbsp;только узнайте по&nbsp;ссылке.'
- const text2 = opts.text2 || 'Наша команда стала активнее участвовать в&nbsp;образовательных мероприятиях, на&nbsp;которых мы&nbsp;делимся тонкостями своей работы....'
- const showSecondText = opts.showSecondText !== false
tr
td(class=bgClass)
+defaultTable('100%')
tr
td.paddingWrapper
+defaultTable('100%')
+spacerLine(40)
tr
td
span.textVerdana.text__normal(class=textClass)!= text1
if showSecondText
tr
td
span.textVerdana.text__normal(class=textClass)!= text2
+spacerLine(40)
td(valign='bottom')
+defaultTable('')
+trtd
+backgroundImageBlock(imageSrc, 145, 270, imageBg, 'center', 'top', 'contain')

View File

@@ -0,0 +1,77 @@
include ./_factory
+spacerLine(20)
//Кнопка Синяя 100% ширины
+ctaButtonSection({
width: 560,
buttonBg: '#ffffff',
buttonText: '#130F33',
iconSrc: 'https://574922.selcdn.ru/email.static/reaspekt/2024_newsletters/2024_09_29/icon-watch-white.png'
})
+spacerLine(20)
//Кнопка Синяя 50% ширины
+ctaButtonSection({
width: 270,
buttonBg: '#ffffff',
buttonText: '#130F33',
iconSrc: 'https://574922.selcdn.ru/email.static/reaspekt/2024_newsletters/2024_09_29/icon-watch-white.png'
})
+spacerLine(20)
//Кнопка Синяя 33% ширины
+ctaButtonSection({
width: 173,
buttonBg: '#ffffff',
buttonText: '#130F33',
iconSrc: 'https://574922.selcdn.ru/email.static/reaspekt/2024_newsletters/2024_09_29/icon-watch-white.png'
})
+spacerLine(20)
+spacerLine(20)
//Кнопка Зеленая 100% ширины
+ctaButtonSection({
width: 560,
buttonBg: '#130F33',
buttonText: '#AAC8C8',
iconSrc: 'https://574922.selcdn.ru/email.static/reaspekt/2024_newsletters/2024_09_29/icon-watch-blue.png'
})
+spacerLine(20)
//Кнопка Зеленая 50% ширины
+ctaButtonSection({
width: 270,
buttonBg: '#130F33',
buttonText: '#AAC8C8',
iconSrc: 'https://574922.selcdn.ru/email.static/reaspekt/2024_newsletters/2024_09_29/icon-watch-blue.png'
})
+spacerLine(20)
//Кнопка Зеленая 33% ширины
+ctaButtonSection({
width: 173,
buttonBg: '#130F33',
buttonText: '#AAC8C8',
iconSrc: 'https://574922.selcdn.ru/email.static/reaspekt/2024_newsletters/2024_09_29/icon-watch-blue.png'
})
+spacerLine(20)
//Сcылка синяя 100% ширины
+ctaLinkSection({ width: 560, colorClass: 'color__blue', linkClass: 'text__link-blue' })
+spacerLine(20)
//Сcылка синяя 50% ширины
+ctaLinkSection({ width: 270, colorClass: 'color__blue', linkClass: 'text__link-blue' })
+spacerLine(20)
//Сcылка синяя 33% ширины
+ctaLinkSection({ width: 173, colorClass: 'color__blue', linkClass: 'text__link-blue' })
+spacerLine(20)
tr
td.background__blue
+defaultTable('560')
+spacerLine(20)
//Сcылка белая 100% ширины
+ctaLinkSection({ width: 560, colorClass: 'color__white', linkClass: 'text__link-white' })
+spacerLine(20)
//Сcылка белая 50% ширины
+ctaLinkSection({ width: 270, colorClass: 'color__white', linkClass: 'text__link-white', tableWidth: '100%' })
+spacerLine(20)
//Сcылка белая 33% ширины
+ctaLinkSection({ width: 173, colorClass: 'color__white', linkClass: 'text__link-white', tableWidth: '100%' })
+spacerLine(20)

View File

@@ -0,0 +1,29 @@
include ./_factory
// Extended
// 1
// Текст с изображением справа Синий Фон
+sideImageTextSection({
bgClass: 'background__blue',
textClass: 'color__white',
imageSrc: 'https://574922.selcdn.ru/email.static/reaspekt/master-tamplate/banners/icons-box-blue.png',
imageBg: '#130F33'
})
// Текст с изображением справа Белый Фон
+sideImageTextSection({
bgClass: 'background__white',
textClass: 'color__blue',
imageSrc: 'https://574922.selcdn.ru/email.static/reaspekt/master-tamplate/banners/icons-box-white.png',
imageBg: '#ffffff'
})
// Текст с изображением справа Зеленый Фон
+sideImageTextSection({
bgClass: 'background__green',
textClass: 'color__blue',
imageSrc: 'https://574922.selcdn.ru/email.static/reaspekt/master-tamplate/banners/icons-box-green.png',
imageBg: '#AAC8C8'
})

View File

@@ -0,0 +1,222 @@
include ./_factory
//Перенести в texts.pug
//Текст 100% Ширины + Картинка Синий фон
+textImageSection560({
bgClass: 'background__blue',
titleClass: 'color__white',
textClass: 'color__white',
buttonBg: '#130F33',
buttonText: '#AAC8C8',
showTitle: true,
showText: true,
showButton: true
})
//Текст 100% Ширины + Картинка Белый фон
+textImageSection560({
bgClass: 'background__white',
titleClass: 'color__blue',
textClass: 'color__blue',
buttonBg: '#ffffff',
buttonText: '#130F33',
showTitle: true,
showText: true,
showButton: true
})
//Текст 100% Ширины + Картинка Зеленый фон
+textImageSection560({
bgClass: 'background__green',
titleClass: 'color__blue',
textClass: 'color__blue',
buttonBg: '#ffffff',
buttonText: '#130F33',
showTitle: true,
showText: true,
showButton: true
})
//Extended
//1
//Текст 100% Ширины + Картинка Синий фон
+textImageSection560({
bgClass: 'background__blue',
titleClass: 'color__white',
textClass: 'color__white',
showTitle: false,
showText: true,
textBeforeImage: true,
showButton: false
})
//Текст 100% Ширины + Картинка Белый фон
+textImageSection560({
bgClass: 'background__white',
titleClass: 'color__blue',
textClass: 'color__blue',
showTitle: false,
showText: true,
textBeforeImage: true,
showButton: false
})
//Текст 100% Ширины + Картинка Зеленый фон
+textImageSection560({
bgClass: 'background__green',
titleClass: 'color__blue',
textClass: 'color__blue',
showTitle: false,
showText: true,
textBeforeImage: true,
showButton: false
})
//2
//Текст 100% Ширины + Картинка Синий фон
+textImageSection560({
bgClass: 'background__blue',
titleClass: 'color__white',
textClass: 'color__white',
buttonBg: '#130F33',
buttonText: '#AAC8C8',
showTitle: false,
showText: true,
textBeforeImage: true,
showButton: true
})
//Текст 100% Ширины + Картинка Белый фон
+textImageSection560({
bgClass: 'background__white',
titleClass: 'color__blue',
textClass: 'color__blue',
buttonBg: '#ffffff',
buttonText: '#130F33',
showTitle: false,
showText: true,
textBeforeImage: true,
showButton: true
})
//Текст 100% Ширины + Картинка Зеленый фон
+textImageSection560({
bgClass: 'background__green',
titleClass: 'color__blue',
textClass: 'color__blue',
buttonBg: '#ffffff',
buttonText: '#130F33',
showTitle: false,
showText: true,
textBeforeImage: true,
showButton: true
})
//3
//Текст 100% Ширины + Картинка Синий фон
+textImageSection560({
bgClass: 'background__blue',
titleClass: 'color__white',
textClass: 'color__white',
title: 'Контекстная реклама для увеличения продаж',
center: true,
showTitle: true,
showText: true,
showButton: false
})
//Текст 100% Ширины + Картинка Белый фон
+textImageSection560({
bgClass: 'background__white',
titleClass: 'color__blue',
textClass: 'color__blue',
title: 'Контекстная реклама для увеличения продаж',
center: true,
showTitle: true,
showText: true,
showButton: false
})
//Текст 100% Ширины + Картинка Зеленый фон
+textImageSection560({
bgClass: 'background__green',
titleClass: 'color__blue',
textClass: 'color__blue',
title: 'Контекстная реклама для увеличения продаж',
center: true,
showTitle: true,
showText: true,
showButton: false
})
//4
//Текст 50% Ширины + Картинка Синий фон
+textImageSection270({
bgClass: 'background__blue',
titleClass: 'color__white',
textClass: 'color__white',
buttonBg: '#130F33',
buttonText: '#AAC8C8',
showButton: true
})
//Текст 50% Ширины + Картинка Белый фон
+textImageSection270({
bgClass: 'background__white',
titleClass: 'color__blue',
textClass: 'color__blue',
buttonBg: '#ffffff',
buttonText: '#130F33',
showButton: true
})
//Текст 50% Ширины + Картинка Зеленый фон
+textImageSection270({
bgClass: 'background__green',
titleClass: 'color__blue',
textClass: 'color__blue',
buttonBg: '#ffffff',
buttonText: '#130F33',
showButton: true
})
//5
//Текст 50% Ширины + Картинка Синий фон
+textImageSection270({
bgClass: 'background__blue',
titleClass: 'color__white',
textClass: 'color__white',
showButton: true,
linkMode: true,
linkColorClass: 'color__green',
linkClass: 'text__link-green'
})
//Текст 50% Ширины + Картинка Белый фон
+textImageSection270({
bgClass: 'background__white',
titleClass: 'color__blue',
textClass: 'color__blue',
showButton: true,
linkMode: true,
linkColorClass: 'color__green',
linkClass: 'text__link-green'
})
//Текст 50% Ширины + Картинка Зеленый фон
+textImageSection270({
bgClass: 'background__green',
titleClass: 'color__blue',
textClass: 'color__blue',
showButton: true,
linkMode: true,
linkColorClass: 'color__blue',
linkClass: 'text__link-blue'
})

View File

@@ -0,0 +1,83 @@
include ./_factory
//Текст 100% Ширины Синий фон
+textSection560({
bgClass: 'background__blue',
titleClass: 'color__white',
textClass: 'color__white',
buttonBg: '#130F33',
buttonText: '#AAC8C8'
})
//Текст 100% Ширины Белый фон
+textSection560({
bgClass: 'background__white',
titleClass: 'color__blue',
textClass: 'color__blue',
buttonBg: '#ffffff',
buttonText: '#130F33'
})
//Текст 100% Ширины Зеленый фон
+textSection560({
bgClass: 'background__green',
titleClass: 'color__blue',
textClass: 'color__blue',
buttonBg: '#ffffff',
buttonText: '#130F33'
})
//Текст 50% Ширины Синий фон
+textSection270({
bgClass: 'background__blue',
titleClass: 'color__white',
textClass: 'color__white',
buttonBg: '#130F33',
buttonText: '#AAC8C8'
})
//Текст 50% Ширины Белый фон
+textSection270({
bgClass: 'background__white',
titleClass: 'color__blue',
textClass: 'color__blue',
buttonBg: '#ffffff',
buttonText: '#130F33'
})
//Текст 50% Ширины Зеленый фон
+textSection270({
bgClass: 'background__green',
titleClass: 'color__blue',
textClass: 'color__blue',
buttonBg: '#ffffff',
buttonText: '#130F33'
})
//Текст 33% Ширины Синий фон
+textSection173({
bgClass: 'background__blue',
titleClass: 'color__white',
textClass: 'color__white',
buttonBg: '#130F33',
buttonText: '#AAC8C8'
})
//Текст 33% Ширины Белый фон
+textSection173({
bgClass: 'background__white',
titleClass: 'color__blue',
textClass: 'color__blue',
buttonBg: '#ffffff',
buttonText: '#130F33',
firstColumnExtraGap: true
})
//Текст 33% Ширины Зеленый фон
+textSection173({
bgClass: 'background__green',
titleClass: 'color__blue',
textClass: 'color__blue',
buttonBg: '#ffffff',
buttonText: '#130F33'
})