diff --git a/.gitignore b/.gitignore index 8219ebd..e253328 100644 --- a/.gitignore +++ b/.gitignore @@ -118,3 +118,13 @@ yandex_*.html # !/wp-content/plugins/мой-кастомный-плагин/** .ssh_key_for_web .ssh_key_for_web.pub +opencode.json +AGENTS.md +.opencode/ +wp-content/backups-dup-lite/ +wp-content/upgrade-temp-backup/ + +# === Agent/Test files — dev-мусор (не в git) === +data/ +llms.txt +test.php diff --git a/AGENTS.md b/AGENTS.md index db77e4e..4a29e69 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,29 +1,24 @@ -# Глобальные инструкции проекта +# Site1 — WordPress project -## Язык общения -- ВСЕГДА отвечай на русском языке. -- Код, комментарии, коммиты, техническая документация — на английском (стандарт). -- Объяснения, архитектурные решения, анализ, рекомендации — на русском. -- Если пользователь пишет на другом языке — отвечай на том же языке. +## Primary agent +- @site1 — dedicated WordPress agent (auto-activated, see `.opencode/AGENTS.md`) -## Оптимизация DeepSeek v4 Flash -- Модель: `opencode/deepseek-v4-flash-free` -- DeepSeek v4 Flash оптимизирован для быстрых инференсов с большим контекстом. -- Для сложных задач используй декомпозицию: разбивай на подзадачи, выполняй последовательно. -- Для работы с файлами: предпочитай пакетные операции (множественные чтения/записи) вместо последовательных вызовов. -- Для поиска по коду: используй glob/grep с точными паттернами, избегай избыточного сканирования. -- При работе с большими проектами — используй подзадачи (Task/Explore) для параллельного исследования. -- tool_output лимиты увеличены для работы с большими результатами (max_lines: 300, max_bytes: 10240). -- compaction включён, tail_turns: 20 — удержание контекста в длинных сессиях. -- MCP таймаут: 60s (для работы с медленными внешними сервисами). +## Quick rules +- PHP: PSR-12, type declarations, Composer +- JS: TypeScript strict, ESM, async/await +- Commits: conventional commits (`feat:`, `fix:`, `chore:`, etc.) -## Профиль разработчика -- WP-Architect — WordPress full-stack architect. -- Специализация: теминг, SEO, производительность, маркетинг. -- Доступно >80 скиллов: SEO/AEO, CRO, UI/UX, CI/CD, аналитика, безопасность. +## Security +- NEVER modify wp-config.php without explicit confirmation +- NEVER delete files in uploads/ or wp-content/ without confirmation +- ALWAYS ask before destructive actions (rm, overwrite, DB write, git push) -## Принципы работы -- Используй скиллы при каждой возможности (даже 1% совпадения). -- Caveman-режим активируется пользователем (/caveman). -- Коммиты и PR — на нормальном английском. -- Сообщай о проблемах безопасности сразу, без caveman. +## Commands +- PHP test: `vendor/bin/phpunit` +- PHP lint: `vendor/bin/phpstan analyse` +- JS build: `npm run build` +- JS test: `npm test` +- JS lint: `npm run lint` + +## All details +See `.opencode/AGENTS.md` for full architecture, skills, agents list, and directory structure. diff --git a/opencode.json b/opencode.json deleted file mode 100644 index 83b145e..0000000 --- a/opencode.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "$schema": "https://opencode.ai/config.json", - "model": "opencode/deepseek-v4-flash-free", - - "instructions": ["AGENTS.md"], - - "default_agent": "wp-architect", - - "plugin": [ - "file:///home/letoline/.config/opencode/plugins/caveman/plugin.js", - "file:///home/letoline/.config/opencode/plugins/claude-mem.js", - "@zenobius/opencode-skillful" - ], - - "command": { - "wp-audit": { "template": "short" }, - "wp-seo": { "template": "short" }, - "wp-content": { "template": "short" }, - "wp-speed": { "template": "short" }, - "design-persona": { "template": "short" }, - "design-research": { "template": "short" }, - "critique": { "template": "short" }, - "gsd": { "template": "short" }, - "caveman": { "template": "short" }, - "caveman-commit": { "template": "short" }, - "caveman-review": { "template": "short" }, - "design-screen": { "template": "short" }, - "design-system": { "template": "short" }, - "ux-audit": { "template": "short" }, - "prototype": { "template": "short" }, - "school": { "template": "short" } - } -} diff --git a/wp-content/mu-plugins/acf-loader.php b/wp-content/mu-plugins/acf-loader.php old mode 100755 new mode 100644 diff --git a/wp-content/themes/dekart/assets/css/front-page.css b/wp-content/themes/dekart/assets/css/front-page.css new file mode 100644 index 0000000..03ac7c1 --- /dev/null +++ b/wp-content/themes/dekart/assets/css/front-page.css @@ -0,0 +1,56 @@ +/* ═══════════════════════════════════════════════════ + front-page.css — стили для шаблона front-page.php + Извлечены из inline style="..." для соответствия + стандартам и оптимизации скорости загрузки + ═══════════════════════════════════════════════════ */ + +/* ---- Блок "Наши услуги" (блоки-карточки) ---- */ +.advantages__block-item { + border-width: 2px; + border-style: solid; +} +.advantages__block-item--school { border-color: #A05A95; } +.advantages__block-item--preschool { border-color: #F682A5; } +.advantages__block-item--afterschool { border-color: #FEDF6F; } +.advantages__block-item--exam { border-color: #F9A474; } +.advantages__block-item--camp { border-color: #C9DA8F; } +.advantages__block-item--clubs { border-color: #B8CEDC; } + +/* ---- Информационный блок ---- */ +.info__block--compact { + padding-bottom: 0; + margin-top: 40px; +} +.info__block-content_text--full { + max-width: 100%; +} + +/* ---- CTA-блок (бесплатная экскурсия) ---- */ +.cta-block { + background: linear-gradient(90deg, #fdf6ff 0%, #f5e8f5 100%); + padding: 60px 0; + border-top: 2px solid #A05A95; + border-bottom: 2px solid #A05A95; + margin: 40px 0; + text-align: center; +} +.cta-wrapper { + max-width: 900px; + margin: 0 auto; +} +.cta-wrapper .page_h2 { + margin-bottom: 20px; + line-height: 1.3; +} +.cta-wrapper p { + font-size: 1.2rem; + color: #444; + margin-bottom: 30px; +} +.cta-wrapper .btn-page { + margin: 0 auto; + display: block; + padding: 18px 45px; + font-size: 1.3rem; + box-shadow: 0 4px 15px rgba(160, 90, 149, .3); +} diff --git a/wp-content/themes/dekart/assets/css/main.css b/wp-content/themes/dekart/assets/css/main.css index 475a19e..d9d72bb 100644 --- a/wp-content/themes/dekart/assets/css/main.css +++ b/wp-content/themes/dekart/assets/css/main.css @@ -4490,11 +4490,12 @@ footer a:hover, .btn-close-resume-form, .btn-close-request-form { position: absolute; - top: -10px; - right: -10px; + top: 12px; + right: 12px; background: #fff0; border: none; - z-index: 10; + z-index: 99999; + cursor: pointer; } .btn-close-resume-form img, @@ -7001,7 +7002,8 @@ footer a:hover, } .container { - max-width: 101.25vw; + max-width: 100%; + padding: 0 20px; } .footer-wrapper { @@ -9623,3 +9625,653 @@ footer a:hover, } /* end mobile= */ + +/* ═══════════════════════════════════════════════════ + 🎯 REDESIGN 2026 — Bento Grid + Mobile-First CRO + ═══════════════════════════════════════════════════ */ + +/* ── 1. Новая цветовая палитра ── */ +:root { + --accent: #7C3AED; + --accent-hover: #6D28D9; + --accent-light: #F5F3FF; + --accent-50: #F5F3FF; + --accent-100: #EDE9FE; + --accent-200: #DDD6FE; + --accent-500: #8B5CF6; + --accent-700: #5B21B6; + + --green-cta: #059669; + --green-hover: #047857; + --green-light: #D1FAE5; + + --bg-primary: #FFFFFF; + --bg-soft: #F8FAFC; + --bg-card: #FFFFFF; + --bg-bento-alt: #F1F5F9; + + --text-primary: #0F172A; + --text-secondary: #475569; + --text-tertiary: #94A3B8; + + --shadow-sm: 0 1px 3px rgba(0,0,0,0.06); + --shadow-md: 0 4px 12px rgba(0,0,0,0.08); + --shadow-lg: 0 10px 30px rgba(0,0,0,0.1); + --shadow-xl: 0 20px 50px rgba(0,0,0,0.15); + + --radius-sm: 8px; + --radius-md: 12px; + --radius-lg: 16px; + --radius-xl: 20px; + --radius-pill: 28px; +} + +/* ── 2. Bento Grid System ── */ +.bento { + display: grid; + gap: 16px; + padding: 16px; + max-width: 1280px; + margin: 0 auto; +} + +@media (min-width: 640px) { + .bento { + grid-template-columns: repeat(6, 1fr); + gap: 16px; + } +} + +@media (min-width: 1024px) { + .bento { + grid-template-columns: repeat(12, 1fr); + gap: 20px; + padding: 24px; + } +} + +.bento__hero { grid-column: 1 / -1; grid-row: auto; } +.bento__stat { grid-column: 1 / -1; } +.bento__half { grid-column: 1 / -1; } +.bento__third { grid-column: 1 / -1; } +.bento__full { grid-column: 1 / -1; } +.bento__wide { grid-column: 1 / -1; } + +@media (min-width: 640px) { + .bento__hero { grid-column: span 4; grid-row: span 2; } + .bento__stat { grid-column: span 2; } + .bento__half { grid-column: span 3; } + .bento__third { grid-column: span 2; } + .bento__wide { grid-column: span 4; } +} + +@media (min-width: 1024px) { + .bento__hero { grid-column: span 6; grid-row: span 2; } + .bento__stat { grid-column: span 3; } + .bento__half { grid-column: span 6; } + .bento__third { grid-column: span 4; } + .bento__wide { grid-column: span 8; } +} + +.bento-card { + background: var(--bg-card); + border-radius: var(--radius-lg); + padding: 24px; + box-shadow: var(--shadow-sm); + transition: box-shadow .2s, transform .2s; +} + +.bento-card:hover { + box-shadow: var(--shadow-md); + transform: translateY(-2px); +} + +.bento-card--highlight { + background: var(--accent); + color: white; +} + +.bento-card--soft { + background: var(--bg-soft); +} + +.bento-card--green { + background: var(--green-light); +} + +/* ── 3. Social Counters ── */ +.social-counters { + display: flex; + flex-wrap: wrap; + gap: 12px; + margin-top: 16px; + justify-content: center; +} + +@media (min-width: 640px) { + .social-counters { + justify-content: flex-start; + } +} + +.social-counter { + display: flex; + align-items: center; + gap: 8px; + padding: 10px 16px; + background: var(--bg-soft); + border-radius: var(--radius-sm); + font-size: 14px; + color: var(--text-secondary); + flex: 1; + min-width: 140px; +} + +.social-counter__icon { + font-size: 20px; + flex-shrink: 0; +} + +.social-counter__number { + font-weight: 700; + color: var(--accent); + font-size: 18px; + white-space: nowrap; +} + +.social-counter__label { + color: var(--text-tertiary); + font-size: 12px; + line-height: 1.2; +} + +/* ── 4. Sticky CTA Mobile ── */ +.sticky-cta-mobile { + display: none; + position: fixed; + bottom: 0; + left: 0; + right: 0; + z-index: 1000; + padding: 8px 16px max(12px, env(safe-area-inset-bottom)); + background: linear-gradient(to top, rgba(255,255,255,0.98) 60%, transparent); + pointer-events: none; + backdrop-filter: blur(8px); + -webkit-backdrop-filter: blur(8px); +} + +@media (max-width: 639px) { + .sticky-cta-mobile { + display: block; + } + body { + padding-bottom: 80px; + } +} + +.sticky-cta-btn { + pointer-events: auto; + width: 100%; + height: 56px; + border: none; + border-radius: var(--radius-pill); + background: linear-gradient(135deg, var(--accent), var(--accent-500)); + color: white; + font-size: 18px; + font-weight: 700; + font-family: 'Roboto', sans-serif; + cursor: pointer; + box-shadow: var(--shadow-lg); + transition: transform .15s, box-shadow .15s; + display: flex; + align-items: center; + justify-content: center; + gap: 8px; +} + +.sticky-cta-btn:active { + transform: scale(0.97); + box-shadow: var(--shadow-md); +} + +/* ── 5. Guarantee Block ── */ +.guarantee-block { + background: linear-gradient(135deg, var(--accent-light), #FEF3C7); + border-radius: var(--radius-xl); + padding: 32px 24px; + text-align: center; + border: 2px solid var(--accent-200); + position: relative; + overflow: hidden; +} + +.guarantee-block::before { + content: '🛡️'; + position: absolute; + top: -10px; + right: -10px; + font-size: 80px; + opacity: 0.15; + transform: rotate(15deg); +} + +.guarantee-block__text { + font-size: 16px; + line-height: 1.6; + color: var(--text-secondary); + max-width: 560px; + margin: 0 auto; +} + +.guarantee-block__badge { + display: inline-block; + margin-top: 16px; + padding: 6px 20px; + background: var(--accent); + color: white; + border-radius: var(--radius-pill); + font-size: 14px; + font-weight: 600; +} + +@media (min-width: 640px) { + .guarantee-block { + padding: 40px 32px; + } +} + +/* ── 6. Hero Risk Reversal Badge ── */ +.hero-risk-reversal { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 4px 14px; + background: var(--green-light); + color: #065F46; + border-radius: var(--radius-pill); + font-size: 13px; + font-weight: 600; + margin-top: 8px; +} + +/* ── 7. Transformation Case ── */ +.transformation-case { + display: grid; + grid-template-columns: 1fr; + gap: 16px; + padding: 24px; + background: var(--bg-soft); + border-radius: var(--radius-xl); + position: relative; +} + +@media (min-width: 640px) { + .transformation-case { + grid-template-columns: 1fr auto 1fr; + align-items: center; + } +} + +.transformation-step { + text-align: center; + padding: 16px; + border-radius: var(--radius-md); +} + +.transformation-step--before { + background: #FEF2F2; + border-left: 4px solid #EF4444; +} + +.transformation-step--process { + background: var(--accent-light); +} + +.transformation-step--after { + background: var(--green-light); + border-right: 4px solid var(--green-cta); +} + +.transformation-step__label { + font-size: 12px; + text-transform: uppercase; + letter-spacing: 0.05em; + color: var(--text-tertiary); + font-weight: 600; + margin-bottom: 8px; +} + +.transformation-step__title { + font-size: 18px; + font-weight: 700; + color: var(--text-primary); + margin-bottom: 4px; +} + +.transformation-step__desc { + font-size: 14px; + color: var(--text-secondary); + line-height: 1.4; +} + +.transformation-arrow { + display: none; + font-size: 28px; + color: var(--accent); + text-align: center; +} + +@media (min-width: 640px) { + .transformation-arrow { + display: block; + } +} + +/* ── 8. Outcome Card ── */ +.outcome-card { + display: flex; + flex-direction: column; + gap: 24px; + padding: 32px 24px; + background: linear-gradient(135deg, #EEF2FF, #F5F3FF); + border-radius: var(--radius-xl); +} + +@media (min-width: 640px) { + .outcome-card { + flex-direction: row; + align-items: center; + padding: 40px 32px; + } +} + +.outcome-card__metrics { + display: flex; + flex-wrap: wrap; + gap: 20px; + flex: 1; +} + +.outcome-metric { + flex: 1; + min-width: 120px; +} + +.outcome-metric__value { + font-family: 'Oswald', sans-serif; + font-size: 36px; + font-weight: 700; + color: var(--accent); + line-height: 1; +} + +.outcome-metric__label { + font-size: 14px; + color: var(--text-secondary); + margin-top: 4px; +} + +.outcome-card__cta { + flex-shrink: 0; +} + +/* ── 9. Final CTA Section ── */ +.cta-final { + background: linear-gradient(135deg, var(--accent), #5B21B6); + color: white; + border-radius: var(--radius-xl); + padding: 48px 24px; + text-align: center; +} + +.cta-final__title { + font-family: 'Oswald', sans-serif; + font-size: 28px; + font-weight: 600; + margin-bottom: 12px; + line-height: 1.2; +} + +.cta-final__subtitle { + font-size: 16px; + opacity: 0.9; + margin-bottom: 24px; + line-height: 1.5; +} + +.cta-final .btn { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 16px 40px; + background: white; + color: var(--accent); + border: none; + border-radius: var(--radius-pill); + font-size: 18px; + font-weight: 700; + font-family: 'Roboto', sans-serif; + cursor: pointer; + box-shadow: var(--shadow-lg); + transition: transform .15s; +} + +.cta-final .btn:active { + transform: scale(0.97); +} + +@media (min-width: 640px) { + .cta-final { + padding: 64px 48px; + } + .cta-final__title { + font-size: 36px; + } +} + +/* ── 10. Button System — Unified ── */ +.btn-primary { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 8px; + padding: 14px 32px; + background: linear-gradient(135deg, var(--accent), var(--accent-500)); + color: white; + border: none; + border-radius: var(--radius-pill); + font-size: 16px; + font-weight: 600; + font-family: 'Roboto', sans-serif; + cursor: pointer; + transition: transform .15s, box-shadow .15s; + box-shadow: var(--shadow-sm); + text-decoration: none; + min-height: 48px; +} + +.btn-primary:hover, +.btn-primary:focus-visible { + transform: translateY(-1px); + box-shadow: var(--shadow-md); +} + +.btn-primary:active { + transform: translateY(0); +} + +.btn-secondary { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 8px; + padding: 12px 28px; + background: transparent; + color: var(--accent); + border: 2px solid var(--accent-200); + border-radius: var(--radius-pill); + font-size: 15px; + font-weight: 600; + font-family: 'Roboto', sans-serif; + cursor: pointer; + transition: background .15s, border-color .15s; + text-decoration: none; + min-height: 44px; +} + +.btn-secondary:hover, +.btn-secondary:focus-visible { + background: var(--accent-light); + border-color: var(--accent); +} + +/* ── 11. Mobile: hide old "Оставить заявку" text ── */ +.btn-banner .btn-free-lesson-header { + /* Keeping existing class but text updated */ +} + +/* ── 12. Banner enhancement — Risk Reversal Tag ── */ +.banner__content .risk-reversal-tag { + display: inline-block; + margin-top: 8px; + padding: 4px 16px; + background: rgba(255,255,255,0.15); + border-radius: var(--radius-pill); + font-size: 14px; + color: #FFD43E; + font-weight: 500; + backdrop-filter: blur(4px); +} + +/* ── 13. Section spacers for Bento sections ── */ +.pksh-section { + padding: 40px 16px; +} + +@media (min-width: 640px) { + .pksh-section { + padding: 60px 24px; + } +} + +@media (min-width: 1024px) { + .pksh-section { + padding: 80px 32px; + } +} + +.pksh-section--alt { + background: var(--bg-soft); +} + +/* ── 14. Mobile CTA — full width tap target ── */ +@media (max-width: 639px) { + .btn-write.btn-primary.mobile, + .btn-page.btn-write { + width: calc(100% - 32px); + margin: 8px auto; + height: 52px; + font-size: 17px !important; + border-radius: var(--radius-pill); + } +} + +/* ── 15. Price/Bento Cards refinement ── */ +.pksh-price-card { + border-radius: var(--radius-xl); + padding: 28px 20px; + background: var(--bg-card); + box-shadow: var(--shadow-sm); + border: 1px solid #E2E8F0; + transition: box-shadow .2s, border-color .2s; +} + +.pksh-price-card:hover { + box-shadow: var(--shadow-md); + border-color: var(--accent-200); +} + +.pksh-price-card--featured { + border-color: var(--accent); + box-shadow: 0 0 0 2px var(--accent), var(--shadow-md); +} + +.pksh-price-card__title { + font-family: 'Oswald', sans-serif; + font-size: 22px; + font-weight: 600; + color: var(--text-primary); + margin-bottom: 8px; +} + +.pksh-price-card__price { + font-size: 32px; + font-weight: 700; + color: var(--accent); + margin-bottom: 16px; +} + +.pksh-price-card__features { + list-style: none; + padding: 0; + margin: 0 0 20px; + display: flex; + flex-direction: column; + gap: 10px; +} + +.pksh-price-card__features li { + font-size: 14px; + color: var(--text-secondary); + display: flex; + align-items: center; + gap: 8px; +} + +/* ── 16. Animations ── */ +@keyframes fadeInUp { + from { opacity: 0; transform: translateY(20px); } + to { opacity: 1; transform: translateY(0); } +} + +.bento-card { + animation: fadeInUp 0.4s ease-out both; +} + +.bento-card:nth-child(1) { animation-delay: 0.05s; } +.bento-card:nth-child(2) { animation-delay: 0.1s; } +.bento-card:nth-child(3) { animation-delay: 0.15s; } +.bento-card:nth-child(4) { animation-delay: 0.2s; } +.bento-card:nth-child(5) { animation-delay: 0.25s; } + +.bento-card--static { + animation: none; +} + +/* ── Reduced Motion ── */ +@media (prefers-reduced-motion: reduce) { + .bento-card { + animation: none; + } + .sticky-cta-btn { + transition: none; + } + .btn-primary, + .btn-secondary { + transition: none; + } +} + +/* ── 17. Modal Form Enhancement ── */ +.modal-request-form { + z-index: 9999; +} + +/* ── 18. Section Spacing Fix for main ── */ +main { + gap: 0; +} + +main > .pksh-section:first-child { + padding-top: 0; +} diff --git a/wp-content/themes/dekart/assets/css/podgotovka-k-shkole.css b/wp-content/themes/dekart/assets/css/podgotovka-k-shkole.css new file mode 100644 index 0000000..8db736d --- /dev/null +++ b/wp-content/themes/dekart/assets/css/podgotovka-k-shkole.css @@ -0,0 +1,2988 @@ +/* ============================================================ + podgotovka-k-shkole.css — v4.0 (Hero Photo-led Redesign 2026) + Page-specific styles for "Подготовка к школе" + Loaded only via page-podgotovka-k-shkole.php template + ============================================================ */ + +/* ============================================================ + 1. DESIGN TOKENS (page-pksh scoped) + ============================================================ */ +.page-pksh { + --bg-deep: #0F172A; + --bg-soft-2026: #F8FAFC; + --bg-warm: #F8F4F0; /* warm cream — primary warm section bg */ + --bg-warm-alt: #F5F0E8; /* warm stone — secondary warm section bg */ + --navy: #0F172A; + --slate-600: #475569; + --slate-400: #94A3B8; + --radius-2026: 24px; + +} + +/* Unified purple design system (was orange in v1). + --accent defined in main.css :root (#7C3AED). */ + +/* ============================================================ + 2. BANNER — address & scarcity + ============================================================ */ +.banner__address { + font-family: 'Roboto', sans-serif; + font-size: 16px; + color: #fff; + text-align: center; + margin-bottom: 8px; + letter-spacing: 0.02em; +} + +.banner__scarcity { + font-family: 'Roboto', sans-serif; + font-size: 14px; + font-weight: 700; + color: #fff; + text-align: center; + margin: 0 0 10px; + padding: 6px 18px; +background: rgba(124, 58, 237, 0.2); + border-radius: 100px; + backdrop-filter: blur(4px); + display: inline-block; + max-width: fit-content; +} + +.banner__scarcity strong { + color: #C084FC; +} + +.btn-banner--main { + font-size: 16px; + padding: 14px 32px; +} + +@media (max-width: 860px) { + .banner__address { + font-size: 14px; + } + .banner__scarcity { + font-size: 12px; + padding: 4px 14px; + } + .btn-banner--main { + font-size: 14px; + padding: 12px 24px; + width: 100%; + max-width: 320px; + } +} + +/* ============================================================ + 3. BENTO LABELS & HEADINGS + ============================================================ */ +.bento-label { + display: inline-block; + font-size: 0.8125rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.08em; + color: var(--accent, #7C3AED); + margin-bottom: 8px; +} + +.bento-label--light { + color: rgba(255,255,255,0.8); +} + +.bento-h2 { + font-size: 1.625rem; + font-weight: 700; + line-height: 1.25; + color: var(--navy); + margin: 0 0 12px; +} + +.bento-h2--light { + color: #fff; +} + +.bento-p { + font-size: 1rem; + line-height: 1.6; + color: var(--slate-600); + margin: 0 0 20px; +} + +@media (min-width: 640px) { + .bento-h2 { + font-size: 1.875rem; + } +} + +/* ============================================================ + 4. STEPS-3 — How classes work + ============================================================ */ +.steps-3 { + display: flex; + flex-direction: column; + gap: 16px; + margin-top: 16px; +} + +.step { + display: flex; + align-items: flex-start; + gap: 14px; +} + +.step__num { + flex-shrink: 0; + width: 40px; + height: 40px; + border-radius: 50%; + background: linear-gradient(135deg, #7C3AED, #8B5CF6); + color: #fff; + display: flex; + align-items: center; + justify-content: center; + font-weight: 800; + font-size: 1rem; + box-shadow: 0 3px 10px rgba(124, 58, 237, 0.25); +} + +.step strong { + display: block; + font-size: 0.9375rem; + color: var(--navy); + margin-bottom: 2px; +} + +.step span:not(.step__num) { + display: block; + font-size: 0.875rem; + color: var(--slate-600); + line-height: 1.4; +} + +/* ============================================================ + 5. OBJECTIONS — Why us cards + ============================================================ */ +/* WHITE cards on warm #F8F4F0 section = bright, contrast resolved. + Warm border + generous shadow replaces lost figure/ground. */ +.bento-card--objections { + background: #FFFFFF; + border: 1.5px solid #EDE8DF; + box-shadow: 0 6px 24px rgba(0, 0, 0, 0.07); +} +.bento-card--objections:hover { + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); +} + +.objection-list { + display: flex; + flex-direction: column; + gap: 16px; +} + +.objection-item { + display: flex; + gap: 12px; + align-items: flex-start; +} + +.objection-item__icon { + flex-shrink: 0; + width: 32px; + height: 32px; + color: var(--accent, #7C3AED); + margin-top: 2px; + filter: drop-shadow(0 1px 3px rgba(124, 58, 237, 0.2)); +} + +.objection-item strong { + display: block; + font-size: 0.9375rem; + color: var(--navy); + margin-bottom: 2px; +} + +.objection-item p { + font-size: 0.875rem; + color: var(--slate-600); + line-height: 1.45; + margin: 0; +} + +/* ============================================================ + 6. RESULTS GRID — Highlight section + ============================================================ */ +.bento-card--highlight-results { + background: var(--bg-deep); + border-radius: var(--radius-2026); + padding: 32px 24px; +} + +@media (min-width: 640px) { + .bento-card--highlight-results { + padding: 40px 32px; + } +} + +.results-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 20px; + margin-top: 8px; +} + +@media (min-width: 640px) { + .results-grid { + grid-template-columns: repeat(4, 1fr); + gap: 24px; + } +} + +.result-item { + text-align: center; +} + +.result-item__value { + display: block; + font-size: 2.25rem; + font-weight: 800; + color: var(--accent, #7C3AED); + line-height: 1; + margin-bottom: 6px; +} + +@media (min-width: 640px) { + .result-item__value { + font-size: 2.75rem; + } +} + +.result-item__desc { + display: block; + font-size: 0.8125rem; + color: var(--slate-400); + line-height: 1.35; +} + +/* ============================================================ + 7. GUARANTEE Bento Card + ============================================================ */ +/* .bento-card--guarantee moved to .guarantee-block--centered */ + +/* ============================================================ + 8. (removed — FAQ moved to section 44) + ============================================================ */ + +/* ============================================================ + 9. PROGRAMS GRID + ============================================================ */ +.programs-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 24px; + margin: 28px 0 20px; +} + +/* ── Card container ── */ +.program-card { + display: flex; + flex-direction: column; + border-radius: 20px; + overflow: hidden; + background: #fff; + box-shadow: 0 4px 24px rgba(0,0,0,0.07); + transition: transform 0.25s ease, box-shadow 0.25s ease; +} + +.program-card:hover { + transform: translateY(-6px); + box-shadow: 0 16px 40px rgba(0,0,0,0.12); +} + +/* ── Header ── */ +.program-card__header { + padding: 20px 24px; + background: linear-gradient(135deg, var(--accent, #7C3AED), #A855F7); + color: #fff; + display: flex; + align-items: center; + gap: 12px; +} + +.program-card__icon { + font-size: 1.6rem; + flex-shrink: 0; + width: 44px; + height: 44px; + display: flex; + align-items: center; + justify-content: center; + background: rgba(255,255,255,0.18); + border-radius: 12px; +} + +.program-card__title { + margin: 0; + font-size: 1.1rem; + font-weight: 700; + color: #fff; + line-height: 1.25; +} + +/* ── Body ── */ +.program-card__body { + padding: 24px; + flex-grow: 1; + display: flex; + flex-direction: column; + gap: 18px; +} + +/* ── Shared label ── */ +.program-card__label { + display: block; + font-size: 0.8rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.04em; + color: #64748B; + margin-bottom: 4px; +} + +/* ── Intensity ── */ +.program-card__intensity { + font-size: 0.95rem; + color: #334155; + background: #F8FAFC; + padding: 10px 14px; + border-radius: 10px; + border-left: 3px solid var(--accent, #7C3AED); +} + +/* ── Schedule ── */ +.program-card__schedule ul { + list-style: none; + padding: 0; + margin: 0; +} + +.program-card__schedule li { + position: relative; + padding-left: 18px; + margin-bottom: 4px; + font-size: 0.9rem; + color: #475569; + line-height: 1.5; +} + +.program-card__schedule li::before { + content: "•"; + position: absolute; + left: 4px; + color: var(--accent, #7C3AED); + font-weight: 700; +} + +/* ── Lesson structure timeline ── */ +.program-card__structure .program-card__label { + margin-bottom: 8px; +} + +.program-card__timeline { + list-style: none; + padding: 0; + margin: 0; + display: flex; + flex-direction: column; + gap: 6px; +} + +.program-card__timeline-item { + display: flex; + align-items: center; + gap: 10px; + padding: 6px 10px; + background: #F8FAFC; + border-radius: 8px; +} + +.program-card__timeline-badge { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 60px; + padding: 2px 8px; + font-size: 0.72rem; + font-weight: 700; + color: #fff; + background: var(--accent, #7C3AED); + border-radius: 6px; + white-space: nowrap; +} + +.program-card__timeline-name { + font-size: 0.88rem; + color: #334155; + line-height: 1.35; +} + +/* ── Includes (✅ list) ── */ +.program-card__includes ul { + list-style: none; + padding: 0; + margin: 0; +} + +.program-card__includes li { + position: relative; + padding-left: 20px; + margin-bottom: 4px; + font-size: 0.88rem; + color: #475569; + line-height: 1.5; +} + +.program-card__includes li::before { + content: "✅"; + position: absolute; + left: 0; + font-size: 0.7rem; +} + +/* ── Pricing block ── */ +.program-card__pricing { + margin-top: auto; + padding-top: 14px; + border-top: 1px solid #E9EDF4; + display: flex; + flex-direction: column; + gap: 4px; +} + +.program-card__price-main { + display: flex; + align-items: baseline; + gap: 8px; +} + +.program-card__price-value { + font-size: 1.5rem; + font-weight: 800; + color: #0F172A; + line-height: 1.1; +} + +.program-card__price-period { + font-size: 0.8rem; + color: #64748B; +} + +.program-card__price-single { + font-size: 0.8rem; + color: #94A3B8; +} + +/* ── CTA button ── */ +.program-card__btn { + display: block; + width: 100%; + padding: 12px; + border: none; + border-radius: 12px; + font-family: inherit; + font-size: 1rem; + font-weight: 700; + color: #fff; + cursor: pointer; + background: var(--accent, #7C3AED); + text-align: center; + text-decoration: none; + transition: opacity 0.15s, transform 0.15s, box-shadow 0.15s; +} + +.program-card__btn:hover { + opacity: 0.9; + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(124, 58, 237, 0.3); +} + +/* ── Programs grid responsive ── */ +@media (max-width: 860px) { + .programs-grid { + grid-template-columns: repeat(2, 1fr); + } +} +@media (max-width: 639px) { + .programs-grid { + grid-template-columns: 1fr; + } +} + +.programs-note { + text-align: center; + padding: 16px 0 0; + font-size: 0.925rem; + color: var(--slate-600); +} + +.programs-note__link { + color: var(--accent, #7C3AED); + font-weight: 700; + text-decoration: underline; + text-underline-offset: 2px; +} + +@media (max-width: 639px) { + .programs-grid { + grid-template-columns: 1fr; + gap: 16px; + } + .program-card__header { + padding: 14px 16px; + } + .program-card__title { + font-size: 0.95rem; + } + .program-card__body { + padding: 16px; + } +} + +/* ============================================================ + 10. FINAL CTA + ============================================================ */ +.final-cta { + text-align: center; + padding: 24px 0; +} + +.final-cta__text { + font-size: 1rem; + color: var(--slate-600); + line-height: 1.6; + max-width: 540px; + margin: 0 auto 24px; +} + +.final-cta__footnote { + font-size: 0.8125rem; + color: var(--accent, #7C3AED); + font-weight: 600; + margin: 16px 0 0; +} + +.btn-primary--large { + padding: 18px 40px; + font-size: 1.125rem; + min-height: 56px; + border-radius: 32px; +} + +/* ============================================================ + 11. MOBILE OVERRIDES + ============================================================ */ +@media (max-width: 639px) { + .bento-card { + padding: 20px 16px; + border-radius: 20px; + } + + .bento-h2 { + font-size: 1.375rem; + } + + .result-item__value { + font-size: 1.75rem; + } +} + +/* ============================================================ + 11b. MOBILE — Fixed header compensation + Header is 76px fixed at top. Banner must not hide behind it. + ============================================================ */ +@media (max-width: 860px) { + .page-pksh .banner { + padding-top: 76px; + margin-top: -76px; /* fixed header compensation */ + } + .page-pksh .banner__content.mobile { + margin-top: 0; /* ensure no double gap */ + } +} + +/* ============================================================ + 11c. MOBILE — Banner scarcity on mobile wraps nicely + ============================================================ */ +@media (max-width: 639px) { + .banner__scarcity { + font-size: 12px; + padding: 4px 14px; + margin: 8px auto 0; + } + .btn-banner--main { + font-size: 14px; + padding: 12px 24px; + width: 100%; + max-width: 320px; + } +} + +/* ============================================================ + 12. ANCHOR NAVIGATION + ============================================================ */ +/* ═══════════════════════════════════════════════════════════════ + ANCHOR NAV — redesigned for desktop 2026-05 + + Problem: links were too small (8×18px padding, 14px font), + nav was 1280px wide (no alignment with 900px content axis of + sections 2-4), vertical rhythm was 12px vs section 80px. + + Solution: + • Container → 900px (aligns with Social/Micro/Guarantee axis) + • Flex-wrap 2 rows × 3 pills, centered + • Pills → 14×28px padding, 16px font (body-text scale) + • Purple hover with translateY(-2px) + glow shadow + • Vertical padding 48/56px (matches section rhythm) + ═══════════════════════════════════════════════════════════ */ +.pksh-anchor-nav { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 10px; + max-width: 900px; + margin: 0 auto; + padding: 48px 16px 56px; + overflow: visible; +} + +.pksh-anchor-link { + flex-shrink: 0; + padding: 14px 28px; + border-radius: 100px; + background: #FFFFFF; + color: #475569; + font-size: 1rem; + font-weight: 600; + text-decoration: none; + border: 1.5px solid #E2E8F0; + transition: all 0.2s ease; + white-space: nowrap; +} + +.pksh-anchor-link:hover, +.pksh-anchor-link:focus-visible { + background: #F5F3FF; + color: #7C3AED; + border-color: #7C3AED; + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(124, 58, 237, 0.15); +} + +.pksh-anchor-link--cta { + background: linear-gradient(135deg, #7C3AED, #8B5CF6); + color: #fff; + border-color: transparent; +} + +.pksh-anchor-link--cta:hover, +.pksh-anchor-link--cta:focus-visible { + background: linear-gradient(135deg, #6D28D9, #7C3AED); + color: #fff; + border-color: transparent; + box-shadow: 0 4px 12px rgba(124, 58, 237, 0.3); +} + +@media (max-width: 639px) { + .pksh-anchor-nav { + padding: 32px 16px 40px; + gap: 8px; + justify-content: center; + } + .pksh-anchor-link { + padding: 10px 18px; + font-size: 0.875rem; + min-height: 44px; + display: inline-flex; + align-items: center; + } +} + +/* ============================================================ + 13. FOMO SCARCITY BADGE + ============================================================ */ +.pksh-fomo { + display: flex; + align-items: center; + justify-content: center; + gap: 10px; + margin: 16px auto 0; + padding: 10px 24px; + background: linear-gradient(135deg, #F5F0FF, #EDE4FF); + border-radius: 100px; + max-width: fit-content; + border: 1px solid #D4C4F0; +} + +.pksh-fomo__dot { + width: 10px; + height: 10px; + border-radius: 50%; + background: var(--accent, #7C3AED); + flex-shrink: 0; + animation: pksh-pulse 2s infinite; +} + +@keyframes pksh-pulse { + 0%, 100% { opacity: 1; transform: scale(1); } + 50% { opacity: 0.6; transform: scale(1.3); } +} + +.pksh-fomo__text { + font-size: 0.875rem; + font-weight: 600; + color: #9A3412; +} + +/* ============================================================ + 14. OVERRIDE: fix CTA gap 640–860px + Sticky CTA appears at 860px to match when banner CTA hides + ============================================================ */ +@media (max-width: 860px) { + .sticky-cta-mobile { + display: block; + } + body { + padding-bottom: 80px; + } +} + +/* ============================================================ + 16. OVERRIDE: Teachers section — constrain on mobile + Swiper overflows viewport at <640px + ============================================================ */ +@media (max-width: 639px) { + .page-pksh .our-teachers .container { + padding-left: 16px !important; + padding-right: 16px !important; + } + .page-pksh .teachers-owl-wrapper { + padding: 0 !important; + } +} + +/* ============================================================ + 18. (removed — program-card__btn moved to base styles) + ============================================================ */ + +/* ============================================================ + 19. OVERRIDE: Header btn-lilac — use accent + Legacy header button should match brand + ============================================================ */ +.page-pksh .btn-lilac { + background: linear-gradient(135deg, var(--accent, #7C3AED), var(--accent-500, #8B5CF6)) !important; + font-family: 'Roboto', sans-serif !important; + font-weight: 700 !important; + text-transform: none !important; + border-radius: var(--radius-pill, 28px) !important; + border: none !important; +} + +.page-pksh .btn-lilac:hover { + background: linear-gradient(135deg, var(--accent-hover, #6D28D9), var(--accent-700, #5B21B6)) !important; +} + +/* ============================================================ + 15. OVERRIDE: Banner CTA accent + Use accent (purple) for banner CTA to match brand + ============================================================ */ +.page-pksh .btn-banner--main { + background: linear-gradient(135deg, var(--accent, #7C3AED), var(--accent-500, #8B5CF6)); + border: none; + color: #fff; + font-family: 'Roboto', sans-serif; + font-weight: 700; + text-transform: none; + letter-spacing: 0; +} +.page-pksh .btn-banner--main:hover { + background: linear-gradient(135deg, var(--accent-hover, #6D28D9), var(--accent-700, #5B21B6)); +} + +/* ============================================================ + 21. DESKTOP LAYOUT — ширину.всё. + Force ALL bento sections to fill max-width (1280px). + Fix: inline-block-like collapse when content narrower. + ============================================================ */ +.page-pksh .bento { + width: 100%; +} + +/* Inner grid items fill their cells (CSS Grid default is stretch) */ +.page-pksh .bento__full, +.page-pksh .bento__half, +.page-pksh .bento__wide { + min-width: 0; /* prevent grid overflow from long words */ + box-sizing: border-box; +} + +/* ── 21b. Social Counters — center content ── */ +.page-pksh .social-counters { + width: 100%; + display: flex; + justify-content: space-evenly; + align-items: center; + flex-wrap: wrap; + gap: 24px; +} + +.page-pksh .social-counter { + flex: 1 1 180px; + max-width: 280px; + display: flex; + align-items: center; + gap: 14px; +} + +/* ── 21c. Programs grid — fill bento width ── */ +.page-pksh .programs-grid { + width: 100%; +} + +/* ── 21d. Final CTA — full width + centered content ── */ +.page-pksh #final-cta .bento__full { + width: 100%; + max-width: 700px; + margin: 0 auto; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; +} + +/* ── 21f. Consistent section vertical spacing ── */ +.page-pksh .pksh-section + .pksh-section { + /* Sections already have padding: 80px 0; no extra margin needed */ +} +.page-pksh .pksh-section + .pksh-anchor-nav, +.page-pksh .pksh-anchor-nav + .pksh-section { + margin-top: 0; +} +.page-pksh .pksh-section + :not(.pksh-section):not(.pksh-anchor-nav) { + /* map, etc. — no extra spacing */ +} + +/* ── 21g. Guarantee card ── fill height ── */ +/* (removed — guarantee uses .guarantee-block--centered now) */ + +/* ============================================================ + 22. DESKTOP — program cards keep 3-col (base grid handles it) + Override removed — base .programs-grid already uses 3 columns. + ============================================================ */ + +/* ============================================================ + 23. DESKTOP — teacher cards in bento ── constrain within grid + Teachers.php uses .container with padding:20px 90px which + overflows when bento is 1280px. Reduce padding to grid padding. + ============================================================ */ +.page-pksh #teachers .our-teachers .container { + max-width: 100%; + width: 100%; + padding: 20px 24px 40px; +} + +/* Teacher slides — fix fixed width on desktop */ +.page-pksh .teachers-owl .swiper-slide { + width: auto !important; + flex: 0 0 236px; +} + +/* ============================================================ + 23b. Price section (legacy) — prevent narrow collapse + The price section uses .container with padding, outside bento grid + ============================================================ */ +.page-pksh .price .container { + max-width: 1280px; + padding-left: 32px; + padding-right: 32px; +} + +/* ============================================================ + 25. BANNER GUARANTEE MICRO + ============================================================ */ +.banner__guarantee { + font-family: 'Roboto', sans-serif; + font-size: 13px; + font-weight: 600; + color: #FFD43E; + text-align: center; + margin: 10px 0 0; + padding: 8px 18px; + background: rgba(15, 23, 42, 0.6); + border: 1px solid rgba(255, 212, 62, 0.3); + border-radius: 100px; + display: inline-block; + max-width: fit-content; + backdrop-filter: blur(4px); +} + +.banner__guarantee strong { + color: #fff; +} + +@media (max-width: 860px) { + .banner__guarantee { + font-size: 11px; + padding: 6px 14px; + } +} + +/* ============================================================ + 26. GUARANTEE HERO BLOCK (Risk Reversal showcase) + Unified to purple design system: warm neutral card × + purple border/accents. Orange → purple migration. + ============================================================ */ +.guarantee-hero { + display: flex; + align-items: center; + gap: 32px; + max-width: 900px; + margin: 0 auto; + padding: 32px 24px; + background: linear-gradient(135deg, #F8F4F0 0%, #F0EBE5 50%, #F8F4F0 100%); + border: 2px solid #7C3AED; + border-radius: var(--radius-2026, 24px); +} + +.guarantee-hero__shield { + flex-shrink: 0; + font-size: 4rem; + line-height: 1; +} + +.guarantee-hero__content { + flex: 1; +} + +.guarantee-hero__text { + font-size: 1rem; + line-height: 1.6; + color: var(--slate-600, #475569); + margin: 0 0 18px; +} + +.guarantee-hero__text strong { + color: #6D28D9; +} + +.guarantee-hero__btn { + padding: 14px 32px; + font-size: 1rem; +} + +.guarantee-hero__badges { + display: flex; + flex-direction: column; + align-items: center; + gap: 12px; + flex-shrink: 0; +} + +@media (max-width: 639px) { + .guarantee-hero { + flex-direction: column; + text-align: center; + gap: 16px; + padding: 24px 20px; + } + .guarantee-hero__badges { + flex-direction: row; + gap: 16px; + } + .guarantee-hero__shield { + font-size: 3rem; + } +} + +/* ============================================================ + 26b. GUARANTEE HERO — section background + spacing override + Base .pksh-section--alt gives cool #F8FAFC — clashes with + warm palette. White keeps the visual rhythm consistent: + gradient → white → warm stone → white → nav + Padding reduced from 80px → 32/48 for 80px gap rhythm. + ============================================================ */ +.page-pksh .bento[aria-label="Гарантия"] { + background: #FFFFFF; + padding: 32px 32px 48px; +} + +@media (max-width: 860px) { + .page-pksh .bento[aria-label="Гарантия"] { + padding: 24px 16px 32px; + } +} + +/* ============================================================ + 27. MICRO-COMMITMENT (checklist download) + ============================================================ */ +.micro-commit { + display: flex; + align-items: center; + gap: 40px; + max-width: 900px; + margin: 0 auto; + padding: 32px 24px; + background: #fff; + border-radius: var(--radius-2026, 24px); + box-shadow: 0 8px 32px rgba(0,0,0,0.06); +} + +.micro-commit__content { + flex: 1; +} + +.micro-commit__visual { + flex-shrink: 0; + width: 120px; + height: 120px; + background: #F5F0FF; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; +} + +.micro-commit__btn { + padding: 14px 32px; + font-size: 1rem; + margin-top: 8px; +} + +.micro-commit__disclaimer { + font-size: 0.75rem; + color: #94A3B8; + margin: 8px 0 0; +} + +@media (max-width: 639px) { + .micro-commit { + flex-direction: column; + text-align: center; + gap: 20px; + padding: 24px 20px; + } + .micro-commit__visual { + width: 80px; + height: 80px; + } +} + +/* ============================================================ + 28. DESKTOP STICKY CTA + ============================================================ */ +.sticky-cta-desktop { + display: none; + position: fixed; + bottom: 0; + left: 0; + right: 0; + z-index: 999; + background: rgba(255,255,255,0.95); + backdrop-filter: blur(12px); + border-top: 1px solid #E2E8F0; + padding: 12px 32px; + box-shadow: 0 -4px 20px rgba(0,0,0,0.06); + animation: stickyFadeIn 0.3s ease; +} + +@keyframes stickyFadeIn { + from { opacity: 0; transform: translateY(16px); } + to { opacity: 1; transform: translateY(0); } +} + +.sticky-cta-desktop__inner { + max-width: 1280px; + margin: 0 auto; + display: flex; + align-items: center; + justify-content: space-between; + gap: 24px; +} + +.sticky-cta-desktop__info { + display: flex; + align-items: center; + gap: 16px; +} + +.sticky-cta-desktop__badge { + display: inline-block; + padding: 4px 14px; + background: var(--accent, #7C3AED); + color: #fff; + font-size: 0.8125rem; + font-weight: 700; + border-radius: 100px; +} + +.sticky-cta-desktop__text { + font-size: 0.9375rem; + color: var(--navy, #0F172A); + font-weight: 500; +} + +.sticky-cta-desktop__text strong { + color: var(--accent, #7C3AED); +} + +.sticky-cta-desktop__btn { + padding: 14px 32px; + font-size: 1rem; + font-weight: 700; + border: none; + border-radius: 32px; + background: linear-gradient(135deg, var(--accent, #7C3AED), var(--accent-500, #8B5CF6)); + color: #fff; + cursor: pointer; + font-family: 'Roboto', sans-serif; + transition: opacity 0.15s, transform 0.15s; + white-space: nowrap; +} + +.sticky-cta-desktop__btn:hover { + opacity: 0.95; + transform: translateY(-1px); +} + +/* Desktop sticky — show after scrolling past header (~200px) via IntersectionObserver + but default to hidden. Will be shown by JS. */ +@media (min-width: 861px) { + .sticky-cta-desktop { + display: block; + transform: translateY(100%); + transition: transform 0.3s ease; + } + .sticky-cta-desktop.visible { + transform: translateY(0); + } + body { + padding-bottom: 0; + } +} + +/* ============================================================ + 29. TAP TARGET SIZE FIX (Mobile 48px minimum) + ============================================================ */ +@media (max-width: 639px) { + .page-pksh .btn-primary, + .page-pksh .btn-banner--main, + .page-pksh .program-card__btn, + .page-pksh .sticky-cta-btn, + .page-pksh .guarantee-hero__btn, + .page-pksh .micro-commit__btn { + min-height: 48px; + padding-top: 14px; + padding-bottom: 14px; + font-size: 1rem; + } + + /* (FAQ trigger removed — FAQ uses box__accordion now) */ + + /* Social counters — make entire card tappable */ + .page-pksh .social-counter { + min-height: 48px; + } + + /* Final CTA footnote — ensure sufficient height */ + .page-pksh .final-cta__footnote { + padding: 8px 0; + } +} + +/* ============================================================ + 30. SCARCITY ANIMATION & VISUAL WEIGHT + ============================================================ */ +.banner__scarcity { + animation: scarcityPulse 2s ease-in-out infinite; +} + +@keyframes scarcityPulse { + 0%, 100% { transform: scale(1); background: rgba(249, 115, 22, 0.25); } + 50% { transform: scale(1.03); background: rgba(249, 115, 22, 0.35); } +} + +/* Hover on scarcity increases urgency */ +.banner__scarcity:hover { + animation-play-state: paused; + background: rgba(249, 115, 22, 0.4); +} + +/* ============================================================ + 31. BANNER ADDRESS — visual enhancement + ============================================================ */ +.banner__address { + display: flex; + align-items: center; + justify-content: center; + gap: 6px; + opacity: 0.9; +} + +/* ============================================================ + 32. FOMO SCARCITY — make more urgent + Replace pulsing dot with stronger indicator + ============================================================ */ +.pksh-fomo { + cursor: pointer; + transition: transform 0.2s, box-shadow 0.2s; +} + +.pksh-fomo:hover { + transform: scale(1.02); + box-shadow: 0 4px 16px rgba(234, 88, 12, 0.15); +} + +/* ============================================================ + 33. TEACHERS — show experience/credentials + Teacher direction already shows. Style enhancement. + ============================================================ */ +.page-pksh .ourteacher_title { + font-size: 0.8125rem; + min-height: 36px; + display: flex; + align-items: center; + justify-content: center; + text-align: center; + padding: 0 4px; +} + +/* ============================================================ + 34. (removed — 2-col override conflicting with base 3-col grid) + ============================================================ */ + +/* ============================================================ + 36. SCROLL PROGRESS INDICATOR (optional enhancement) + ============================================================ */ +.page-pksh .pksh-scroll-progress { + position: fixed; + top: 0; + left: 0; + height: 3px; + background: linear-gradient(90deg, var(--accent, #7C3AED), #A855F7); + z-index: 10000; + width: 0%; + transition: width 0.1s linear; +} + +/* ============================================================ + 37. MOBILE BANNER OVERRIDE — show CTA inside banner__content + Main.css hides .banner__content .btn-write on mobile. + We moved button INSIDE .banner__content.mobile — unhide. + ============================================================ */ +@media (max-width: 860px) { + .page-pksh .banner__content.mobile .btn-write { + display: block !important; + width: 100%; + max-width: 320px; + margin: 10px auto 0; + padding: 14px 24px; + font-size: 16px; + border-radius: 32px; + background: linear-gradient(135deg, var(--accent, #7C3AED), var(--accent-500, #8B5CF6)); + border: none; + color: #fff; + font-weight: 700; + font-family: 'Roboto', sans-serif; + cursor: pointer; + transition: opacity 0.15s; + } + .page-pksh .banner__content.mobile .btn-write:hover { + opacity: 0.95; + } + + .page-pksh .banner__content.mobile .banner__scarcity { + display: block; + margin: 8px auto 0; + font-size: 12px; + } + + .page-pksh .banner__content.mobile .banner__guarantee { + display: inline-block; + margin: 8px auto 0; + font-size: 11px; + } + + .page-pksh .banner__content.mobile .banner__address { + font-size: 13px; + margin-bottom: 6px; + opacity: 0.85; + } + + /* Mobile banner content — ensure proper spacing for stacked elements */ + .page-pksh .banner__content.mobile { + padding: 16px 20px; + display: flex; + flex-direction: column; + align-items: center; + gap: 2px; + } + + .page-pksh .banner__content.mobile .page_title { + font-size: 22px; + line-height: 1.2; + margin: 4px 0; + } + + .page-pksh .banner__content.mobile .banner_text { + font-size: 15px; + margin: 4px 0; + } +} + +/* ============================================================ + 38. PKSH ANCHOR NAV — scroll offset for fixed header + ============================================================ */ +.page-pksh #how-it-works, +.page-pksh #results, +.page-pksh #programs, +.page-pksh #teachers, +.page-pksh #results, +.page-pksh #programs, +.page-pksh #teachers, +.page-pksh #faq, +.page-pksh #final-cta { + scroll-margin-top: 100px; +} + +/* ═══════════════════════════════════════════════════════════ +/* ═══════════════════════════════════════════════════════════ + 39. HERO — PHOTO-LED REDESIGN v4.0 (May 2026) + Psychology: + - Photo of children → oxytocin (caregiver bond, trust) + - Warm golden gradient → safety, happiness, optimism + - Floating badges like ribbons → achievement, social proof + - Decorative frame → premium feel, anchors the photo + - Sparkles → delight, childhood magic + - Bold purple CTA with glow → urgency, premium action + ═══════════════════════════════════════════════════════ */ + +/* ── Hero container ── */ +.page-pksh .hero-pksh { + position: relative; + min-height: 600px; + display: flex; + flex-direction: column; + overflow: hidden; + background: linear-gradient(165deg, + #FFFAF0 0%, + #FFF1E0 20%, + #FFE4C8 40%, + #F3E8FF 70%, + #FEF7E6 100% + ); +} + +/* ── Background layer ── */ +.hero-pksh__bg { + position: absolute; + inset: 0; + z-index: 0; + pointer-events: none; +} + +/* ── Blobs — warmer, more visible, more organic motion ── */ +.hero-pksh__blob { + position: absolute; + border-radius: 50%; + filter: blur(120px); + will-change: transform; +} + +.hero-pksh__blob--1 { + width: 700px; height: 700px; + background: #FFB088; + top: -280px; right: -100px; + opacity: 0.20; + animation: heroBlob1 12s ease-in-out infinite alternate; +} + +.hero-pksh__blob--2 { + width: 520px; height: 520px; + background: #FFC857; + bottom: -200px; left: -120px; + opacity: 0.16; + animation: heroBlob2 14s ease-in-out infinite alternate; +} + +.hero-pksh__blob--3 { + width: 400px; height: 400px; + background: #D4A0E8; + top: 25%; left: 35%; + opacity: 0.13; + animation: heroBlob3 10s ease-in-out infinite alternate; +} + +.hero-pksh__blob--4 { + width: 240px; height: 240px; + background: #FEC8D8; + bottom: 10%; right: 15%; + opacity: 0.12; + animation: heroBlob4 8s ease-in-out infinite alternate; +} + +@keyframes heroBlob1 { + 0% { transform: translate(0, 0) scale(1); } + 100% { transform: translate(-60px, 50px) scale(1.12); } +} +@keyframes heroBlob2 { + 0% { transform: translate(0, 0) scale(1); } + 100% { transform: translate(50px, -40px) scale(1.08); } +} +@keyframes heroBlob3 { + 0% { transform: translate(0, 0) scale(1); opacity: 0.13; } + 100% { transform: translate(30px, 20px) scale(1.2); opacity: 0.20; } +} +@keyframes heroBlob4 { + 0% { transform: translate(0, 0) scale(1); opacity: 0.12; } + 100% { transform: translate(-20px, -15px) scale(1.1); opacity: 0.18; } +} + +/* ── Sparkle particles ── */ +.hero-pksh__sparkle { + position: absolute; + width: 5px; + height: 5px; + border-radius: 50%; + background: #FFD700; + box-shadow: 0 0 6px rgba(255, 215, 0, 0.4); + animation: sparkleFloat 4s ease-in-out infinite; + pointer-events: none; +} + +.hero-pksh__sparkle:nth-child(1) { top: 15%; left: 10%; width: 4px; height: 4px; animation-delay: 0s; background: #D4A0E8; box-shadow: 0 0 8px rgba(212, 160, 232, 0.4); } +.hero-pksh__sparkle:nth-child(2) { top: 30%; right: 18%; width: 6px; height: 6px; animation-delay: 1.2s; } +.hero-pksh__sparkle:nth-child(3) { bottom: 35%; left: 5%; width: 3px; height: 3px; animation-delay: 2s; } +.hero-pksh__sparkle:nth-child(4) { top: 55%; right: 8%; width: 5px; height: 5px; animation-delay: 0.8s; } +.hero-pksh__sparkle:nth-child(5) { bottom: 12%; left: 20%; width: 4px; height: 4px; animation-delay: 3s; } + +@keyframes sparkleFloat { + 0%, 100% { transform: translateY(0) scale(1); opacity: 0.4; } + 50% { transform: translateY(-20px) scale(1.4); opacity: 0.9; } +} + +/* ── Dot pattern ── */ +.hero-pksh__pattern { + position: absolute; + inset: 0; + background-image: radial-gradient(rgba(255, 154, 118, 0.05) 1px, transparent 1px); + background-size: 32px 32px; +} + +/* ── Breadcrumbs ── */ +.hero-pksh__breadcrumbs { + position: relative; + z-index: 2; + padding-top: 24px; +} + +@media (max-width: 860px) { + .hero-pksh__breadcrumbs { + padding-top: 96px; + } +} + +.hero-pksh__breadcrumbs .breadcrumbs a, +.hero-pksh__breadcrumbs .breadcrumbs span { + color: #A0AEC0; + font-weight: 500; +} + +.hero-pksh__breadcrumbs .breadcrumbs a:hover { + color: #7C3AED; +} + +/* ── Main layout grid ── */ +.hero-pksh__layout { + position: relative; + z-index: 1; + flex: 1; + display: grid; + grid-template-columns: 1fr 1fr; + gap: 48px; + max-width: 1280px; + margin: 0 auto; + padding: 28px 32px 48px; + width: 100%; + align-items: center; +} + +/* ── Left column ── */ +.hero-pksh__content { + display: flex; + flex-direction: column; + gap: 16px; +} + +/* ── Address pill ── */ +.hero-pksh__address { + display: inline-flex; + align-items: center; + gap: 8px; + font-family: 'Roboto', sans-serif; + font-size: 14px; + font-weight: 500; + color: #6B7280; + background: rgba(124, 58, 237, 0.06); + backdrop-filter: blur(8px); + -webkit-backdrop-filter: blur(8px); + padding: 8px 18px; + border-radius: 100px; + max-width: fit-content; + border: 1px solid rgba(124, 58, 237, 0.10); + transition: all 0.2s; +} + +.hero-pksh__address:hover { + background: rgba(124, 58, 237, 0.10); + border-color: rgba(124, 58, 237, 0.20); +} + +.hero-pksh__address svg { + width: 16px; height: 16px; + flex-shrink: 0; + color: #7C3AED; +} + +/* ── Headline — solid dark for readability, purple for emotion ── */ +.hero-pksh__title { + font-family: 'Oswald', sans-serif; + font-size: 52px; + font-weight: 700; + line-height: 1.06; + color: #1E293B; + margin: 2px 0; + max-width: 600px; +} + +/* ── Subtitle ── */ +.hero-pksh__subtitle { + font-family: 'Roboto', sans-serif; + font-size: 20px; + font-weight: 400; + line-height: 1.55; + color: #475569; + margin: 0; + max-width: 520px; +} + +/* ── Actions ── */ +.hero-pksh__actions { + display: flex; + flex-direction: column; + gap: 12px; + margin-top: 10px; +} + +/* ── CTA — bold purple with glow ── */ +.hero-pksh__cta { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 10px; + padding: 20px 44px; + font-family: 'Roboto', sans-serif; + font-size: 18px; + font-weight: 700; + color: #fff; + background: linear-gradient(135deg, #7C3AED 0%, #9F6EF0 50%, #B794F4 100%); + border: none; + border-radius: 100px; + cursor: pointer; + transition: transform 0.25s ease, box-shadow 0.25s ease; + box-shadow: 0 8px 32px rgba(124, 58, 237, 0.30), 0 2px 8px rgba(124, 58, 237, 0.15); + max-width: fit-content; + text-transform: none; + letter-spacing: 0.01em; + position: relative; + overflow: hidden; + animation: ctaGlow 3s ease-in-out infinite; +} + +@keyframes ctaGlow { + 0%, 100% { box-shadow: 0 8px 32px rgba(124, 58, 237, 0.30), 0 2px 8px rgba(124, 58, 237, 0.15); } + 50% { box-shadow: 0 12px 48px rgba(124, 58, 237, 0.45), 0 4px 16px rgba(124, 58, 237, 0.25); } +} + +.hero-pksh__cta::after { + content: ''; + position: absolute; + inset: -2px; + border-radius: 102px; + background: linear-gradient(135deg, rgba(255,255,255,0.15), transparent 50%); + pointer-events: none; +} + +.hero-pksh__cta:hover { + transform: translateY(-3px); + box-shadow: 0 14px 40px rgba(124, 58, 237, 0.40), 0 4px 12px rgba(124, 58, 237, 0.20); +} + +.hero-pksh__cta:active { + transform: translateY(-1px); + box-shadow: 0 6px 20px rgba(124, 58, 237, 0.25); +} + +.hero-pksh__cta-arrow { + display: inline-block; + transition: transform 0.2s; + font-size: 20px; + line-height: 1; +} + +.hero-pksh__cta:hover .hero-pksh__cta-arrow { + transform: translateX(4px); +} + +/* ── Scarcity badge ── */ +.hero-pksh__scarcity { + font-family: 'Roboto', sans-serif; + font-size: 14px; + font-weight: 600; + color: #9A3412; + background: #FFF7ED; + padding: 10px 22px; + border-radius: 100px; + max-width: fit-content; + border: 1.5px solid rgba(249, 115, 22, 0.15); + animation: heroScarcityPulse 3s ease-in-out infinite; +} + +.hero-pksh__scarcity strong { + color: #C2410C; + font-weight: 800; +} + +@keyframes heroScarcityPulse { + 0%, 100% { transform: scale(1); background: #FFF7ED; } + 50% { transform: scale(1.02); background: #FFEDD5; } +} + +/* ── Trust bar ── */ +.hero-pksh__trust { + display: flex; + flex-wrap: wrap; + gap: 20px; + margin-top: 8px; +} + +.hero-pksh__trust-item { + display: inline-flex; + align-items: center; + gap: 8px; + font-family: 'Roboto', sans-serif; + font-size: 14px; + color: #64748B; + background: rgba(255,255,255,0.7); + padding: 6px 14px; + border-radius: 100px; + border: 1px solid rgba(0,0,0,0.04); +} + +.hero-pksh__trust-icon { + font-size: 16px; + line-height: 1; +} + +.hero-pksh__trust-label strong { + color: #1E293B; + font-weight: 700; +} + +/* ═══════════════════════════════════════════════════════════ + RIGHT COLUMN: Photo of children + floating badges + Photo is the emotional anchor — triggers oxytocin. + Floating badges provide social proof + curiosity. + Decorative frame makes the photo feel premium. + ═══════════════════════════════════════════════════════ */ + +/* ── Visual column container ── */ +.hero-pksh__visual { + position: relative; + display: flex; + align-items: center; + justify-content: center; + min-height: 480px; +} + +/* ── Purple glow backdrop ── */ +.hero-pksh__visual-glow { + position: absolute; + width: 420px; + height: 420px; + border-radius: 50%; + background: radial-gradient(circle, rgba(124,58,237,0.08) 0%, rgba(168,85,247,0.05) 30%, transparent 65%); + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + pointer-events: none; +} + +/* ── Photo wrapper — contains frame and ring ── */ +.hero-pksh__photo-wrap { + position: relative; + z-index: 2; + display: flex; + align-items: center; + justify-content: center; +} + +/* ── Decorative photo frame ── */ +.hero-pksh__photo-frame { + position: relative; + width: 380px; + height: 380px; + border-radius: 50%; + overflow: hidden; + box-shadow: + 0 20px 60px rgba(124, 58, 237, 0.15), + 0 8px 24px rgba(0, 0, 0, 0.08), + inset 0 0 0 4px rgba(255, 255, 255, 0.6); + border: 6px solid rgba(255, 255, 255, 0.8); + animation: photoFloat 6s ease-in-out infinite; +} + +.hero-pksh__photo { + width: 100%; + height: 100%; + object-fit: cover; + display: block; +} + +@keyframes photoFloat { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-8px); } +} + +/* ── Photo accent ring ── */ +.hero-pksh__photo-ring { + position: absolute; + width: 420px; + height: 420px; + border-radius: 50%; + border: 2px solid rgba(124, 58, 237, 0.08); + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + pointer-events: none; + animation: ringPulse 4s ease-in-out infinite; +} + +@keyframes ringPulse { + 0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 1; } + 50% { transform: translate(-50%, -50%) scale(1.04); opacity: 0.6; } +} + +/* ── Floating badges — ribbon/sticky-note style ── */ +.hero-pksh__float { + position: absolute; + display: flex; + align-items: center; + gap: 8px; + padding: 10px 20px; + border-radius: 100px; + font-family: 'Roboto', sans-serif; + font-size: 13px; + font-weight: 600; + white-space: nowrap; + animation: heroFloat 5s ease-in-out infinite; + z-index: 3; +} + +.hero-pksh__float--1 { + top: 4%; + right: -8px; + animation-delay: 0s; + background: linear-gradient(135deg, rgba(124,58,237,0.12), rgba(168,85,247,0.08)); + color: #6D28D9; + border: 1px solid rgba(124,58,237,0.12); + backdrop-filter: blur(8px); +} + +.hero-pksh__float--2 { + bottom: 22%; + left: -24px; + animation-delay: 1.2s; + background: linear-gradient(135deg, rgba(255,183,77,0.18), rgba(255,154,118,0.10)); + color: #92400E; + border: 1px solid rgba(255,183,77,0.15); + backdrop-filter: blur(8px); +} + +.hero-pksh__float--3 { + bottom: 4%; + right: 6%; + animation-delay: 2.4s; + background: linear-gradient(135deg, rgba(72,187,120,0.15), rgba(104,211,145,0.08)); + color: #276749; + border: 1px solid rgba(72,187,120,0.12); + backdrop-filter: blur(8px); +} + +.hero-pksh__float--4 { + top: 48%; + left: -28px; + animation-delay: 3.5s; + background: linear-gradient(135deg, rgba(255,215,0,0.20), rgba(255,183,77,0.12)); + color: #92400E; + border: 1px solid rgba(255,215,0,0.15); + backdrop-filter: blur(8px); + font-size: 12px; + padding: 8px 16px; +} + +.hero-pksh__float--4 strong { + color: #7C3AED; +} + +.hero-pksh__float-icon { + font-size: 18px; + line-height: 1; +} + +@keyframes heroFloat { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-10px); } +} + +/* ── Decorative shapes ── */ +.hero-pksh__deco { + position: absolute; + border-radius: 50%; + pointer-events: none; + z-index: 1; +} + +.hero-pksh__deco--1 { + width: 40px; height: 40px; + background: rgba(255, 183, 77, 0.15); + top: 12%; + left: 2%; + animation: decoFloat 6s ease-in-out infinite; +} + +.hero-pksh__deco--2 { + width: 24px; height: 24px; + background: rgba(206, 147, 216, 0.18); + bottom: 40%; + right: -6px; + animation: decoFloat 8s ease-in-out infinite 1s; +} + +.hero-pksh__deco--3 { + width: 16px; height: 16px; + background: rgba(255, 154, 118, 0.20); + top: 48%; + left: -8px; + animation: decoFloat 7s ease-in-out infinite 2s; +} + +.hero-pksh__deco--4 { + width: 10px; height: 10px; + background: rgba(212, 160, 232, 0.25); + bottom: 15%; + right: -4px; + animation: decoFloat 5s ease-in-out infinite 3s; +} + +@keyframes decoFloat { + 0%, 100% { transform: translateY(0) scale(1); } + 50% { transform: translateY(-12px) scale(1.1); } +} + +/* ═══════════════════════════════════════════════════════════ + 39b. HERO — Responsive (Tablet) + ═══════════════════════════════════════════════════════ */ +@media (max-width: 1024px) { + .hero-pksh__layout { gap: 36px; padding: 20px 24px 40px; } + .hero-pksh__title { font-size: 40px; } + .hero-pksh__subtitle { font-size: 18px; } + .hero-pksh__photo-frame { width: 300px; height: 300px; } + .hero-pksh__photo-ring { width: 340px; height: 340px; } + .hero-pksh__float--1 { right: 0; } + .hero-pksh__float--2 { left: -16px; } +} + +/* ═══════════════════════════════════════════════════════════ + 39c. HERO — Responsive (Mobile < 860px) + ═══════════════════════════════════════════════════════ */ +@media (max-width: 860px) { + .page-pksh .hero-pksh { min-height: auto; } + .hero-pksh__layout { grid-template-columns: 1fr; gap: 28px; padding: 12px 16px 40px; } + .hero-pksh__content { gap: 14px; align-items: flex-start; } + .hero-pksh__title { font-size: 32px; max-width: 100%; } + .hero-pksh__subtitle { font-size: 17px; max-width: 100%; } + .hero-pksh__address { font-size: 13px; padding: 6px 14px; } + .hero-pksh__cta { width: 100%; max-width: 100%; font-size: 16px; padding: 16px 24px; min-height: 52px; justify-content: center; text-align: center; } + .hero-pksh__actions { width: 100%; } + .hero-pksh__scarcity { width: 100%; max-width: 100%; text-align: center; font-size: 13px; padding: 8px 16px; box-sizing: border-box; } + .hero-pksh__trust { gap: 10px; } + .hero-pksh__trust-item { font-size: 12px; padding: 4px 10px; gap: 6px; } + .hero-pksh__visual { min-height: auto; order: 1; padding: 20px 0 10px; } + .hero-pksh__photo-frame { width: 220px; height: 220px; border-width: 4px; } + .hero-pksh__photo-ring { width: 250px; height: 250px; } + .hero-pksh__float--1 { top: 4%; right: 4px; font-size: 12px; padding: 6px 14px; } + .hero-pksh__float--2 { display: none; } + .hero-pksh__float--3 { display: none; } + .hero-pksh__float--4 { display: none; } + .hero-pksh__deco--1 { display: none; } + .hero-pksh__deco--2 { display: none; } + .hero-pksh__deco--3 { display: none; } + .hero-pksh__deco--4 { display: none; } +} + +/* ═══════════════════════════════════════════════════════════ + 39d. HERO — Small mobile (< 480px) + ═══════════════════════════════════════════════════════ */ +@media (max-width: 480px) { + .hero-pksh__title { font-size: 26px; } + .hero-pksh__subtitle { font-size: 15px; } + .hero-pksh__trust { gap: 8px; } + .hero-pksh__trust-item { font-size: 11px; gap: 4px; } + .hero-pksh__photo-frame { width: 180px; height: 180px; border-width: 3px; } + .hero-pksh__photo-ring { width: 210px; height: 210px; } +} + +/* ═══════════════════════════════════════════════════════════ + 39e. HERO — hide old mobile banner (safety net) + ═══════════════════════════════════════════════════════ */ +.page-pksh .banner__content.mobile { + display: none !important; +} + +/* ═══════════════════════════════════════════════════════════ + 39f. Reduced motion — respect user preference + ═══════════════════════════════════════════════════════ */ +@media (prefers-reduced-motion: reduce) { + .hero-pksh__blob, + .hero-pksh__sparkle, + .hero-pksh__float, + .hero-pksh__deco, + .hero-pksh__photo-frame, + .hero-pksh__photo-ring, + .hero-pksh__scarcity { animation: none !important; } + .hero-pksh__cta, + .hero-pksh__cta-arrow { transition: none !important; } +} +/* ═══════════════════════════════════════════════════════════ + 40. SOCIAL PROOF — Premium counters redesign v4.0 + Psychology: + - White cards with colored tops = achievement ribbons + - Subtle background pattern = premium texture + - Gradient numbers = premium, celebratory + - Hover lift = tactile, encourages engagement + - Warm coordinating colors: purple, gold, green, coral + ═══════════════════════════════════════════════════════ */ + +/* ── Section container warm background ── */ +.page-pksh .bento[aria-label="Социальное доказательство"] { + background: var(--bg-warm, #F8F4F0); + padding: 40px 32px 48px; + position: relative; +} + +/* Subtle background pattern for depth */ +.page-pksh .bento[aria-label="Социальное доказательство"]::before { + content: ''; + position: absolute; + inset: 0; + background-image: radial-gradient(rgba(124, 58, 237, 0.03) 1px, transparent 1px); + background-size: 24px 24px; + pointer-events: none; +} + +@media (max-width: 860px) { + .page-pksh .bento[aria-label="Социальное доказательство"] { + padding: 28px 16px 36px; + } +} + +/* ── Grid: 4 columns desktop, 2 tablet, 1 mobile ── */ +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counters { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 20px; + max-width: 1000px; + margin: 0 auto; + width: 100%; + position: relative; + z-index: 1; +} + +@media (max-width: 860px) { + .page-pksh .bento[aria-label="Социальное доказательство"] .social-counters { + grid-template-columns: repeat(2, 1fr); + gap: 14px; + max-width: 500px; + } +} + +@media (max-width: 480px) { + .page-pksh .bento[aria-label="Социальное доказательство"] .social-counters { + grid-template-columns: 1fr; + gap: 12px; + } +} + +/* ── Counter card ── */ +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counter { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + gap: 0; + padding: 0; + background: #FFFFFF; + border: none; + border-radius: 20px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05); + overflow: hidden; + transition: box-shadow 0.3s ease, transform 0.3s ease; +} + +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counter:hover { + box-shadow: 0 16px 40px rgba(0, 0, 0, 0.10); + transform: translateY(-4px); +} + +/* ── Card colored top bar ── */ +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counter__top { + width: 100%; + height: 5px; + flex-shrink: 0; +} + +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counter:nth-child(1) .social-counter__top { + background: linear-gradient(90deg, #7C3AED, #A855F7); +} +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counter:nth-child(2) .social-counter__top { + background: linear-gradient(90deg, #F59E0B, #F97316); +} +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counter:nth-child(3) .social-counter__top { + background: linear-gradient(90deg, #10B981, #34D399); +} +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counter:nth-child(4) .social-counter__top { + background: linear-gradient(90deg, #EC4899, #F472B6); +} + +/* ── Card body ── */ +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counter__body { + padding: 24px 16px 26px; + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; + width: 100%; +} + +/* ── Icon ── */ +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counter__icon { + font-size: 30px; + flex-shrink: 0; + width: 56px; + height: 56px; + display: flex; + align-items: center; + justify-content: center; + background: linear-gradient(135deg, rgba(124,58,237,0.08), rgba(168,85,247,0.05)); + border-radius: 16px; + margin-bottom: 2px; + transition: transform 0.3s ease, box-shadow 0.3s ease; +} + +.social-counter:hover .social-counter__icon { + transform: scale(1.08); +} + +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counter:nth-child(2) .social-counter__icon { + background: linear-gradient(135deg, rgba(245,158,11,0.12), rgba(249,115,22,0.08)); +} +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counter:nth-child(3) .social-counter__icon { + background: linear-gradient(135deg, rgba(16,185,129,0.10), rgba(52,211,153,0.06)); +} +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counter:nth-child(4) .social-counter__icon { + background: linear-gradient(135deg, rgba(236,72,153,0.10), rgba(244,114,182,0.06)); +} + +/* ── Number ── */ +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counter__number { + font-family: 'Oswald', sans-serif; + font-size: 34px; + font-weight: 700; + color: #1E293B; + line-height: 1; +} + +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counter:nth-child(1) .social-counter__number { + color: #7C3AED; +} +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counter:nth-child(2) .social-counter__number { + color: #D97706; +} +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counter:nth-child(3) .social-counter__number { + color: #059669; +} +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counter:nth-child(4) .social-counter__number { + color: #DB2777; +} + +/* ── Label ── */ +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counter__label { + font-family: 'Roboto', sans-serif; + font-size: 14px; + color: #64748B; + line-height: 1.35; +} + +@media (max-width: 860px) { + .page-pksh .bento[aria-label="Социальное доказательство"] .social-counter__icon { + width: 48px; + height: 48px; + font-size: 24px; + } + .page-pksh .bento[aria-label="Социальное доказательство"] .social-counter__number { + font-size: 28px; + } + .page-pksh .bento[aria-label="Социальное доказательство"] .social-counter__body { + padding: 18px 12px 22px; + } + .page-pksh .bento[aria-label="Социальное доказательство"] .social-counter__label { + font-size: 13px; + } +} + 41. MICRO-COMMITMENT — warm section, white card, animated SVG + Unlike social counters (white bg × cream cards), + this section alternates: warm bg × white card. + Creates vertical rhythm and visual distinction. + SVG ring: slow rotation = calm, not flashy. + ============================================================ */ + +/* NARROW section — constrained 900px content. White bg */ +.page-pksh .bento[aria-label="Скачать чек-лист"] { + background: #FFFFFF; + padding: 40px 32px 48px; +} + +@media (max-width: 860px) { + .page-pksh .bento[aria-label="Скачать чек-лист"] { + padding: 32px 16px 40px; + } +} + +/* ── Full-width sections: warm #F8F4F0 alternation ── */ +.page-pksh .bento[aria-label="Как проходят занятия"], +.page-pksh .bento#teachers { + background: #F8F4F0; +} + +/* ── Section 6 cards: white on warm, with definition ── */ +.page-pksh #how-it-works .bento-card--soft { + background: #FFFFFF; + border: 1.5px solid #EDE8DF; + box-shadow: 0 6px 24px rgba(0, 0, 0, 0.07); +} +.page-pksh #how-it-works .bento-card--soft:hover { + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); +} + +/* ── Card — white bg with warm border + shadow for depth ── */ +.page-pksh .bento[aria-label="Скачать чек-лист"] .micro-commit { + display: flex; + align-items: center; + gap: 40px; + max-width: 900px; + margin: 0 auto; + padding: 36px 32px; + background: #FFFFFF; + border: 1.5px solid #DED3C0; + border-radius: 24px; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.06); +} + +@media (max-width: 860px) { + .page-pksh .bento[aria-label="Скачать чек-лист"] .micro-commit { + flex-direction: column; + text-align: center; + padding: 28px 20px; + gap: 24px; + border-width: 1px; + } +} + +/* ── Visual — document preview placeholder (replaces circle+ring) ── */ +.page-pksh .bento[aria-label="Скачать чек-лист"] .micro-commit__visual { + flex-shrink: 0; + width: 130px; + height: 170px; + position: relative; + display: flex; + align-items: center; + justify-content: center; + background: #FFFFFF; + border: 1.5px solid #DED3C0; + border-radius: 12px; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.04); +} + +@media (max-width: 860px) { + .page-pksh .bento[aria-label="Скачать чек-лист"] .micro-commit__visual { + width: 96px; + height: 126px; + } +} + +/* ── Checklist illustration SVG fills the visual container ── */ +.page-pksh .micro-commit__svg { + width: 100%; + height: 100%; + display: block; +} + +/* ── Content ── */ +.page-pksh .bento[aria-label="Скачать чек-лист"] .micro-commit__content { + flex: 1; +} + +/* ── Tag "Бесплатно" — purple accent (was orange) ── */ +.page-pksh .bento[aria-label="Скачать чек-лист"] .bento-label { + color: #7C3AED; +} + +/* ── H2 heading — slightly larger for conviction ── */ +.page-pksh .bento[aria-label="Скачать чек-лист"] .bento-h2 { + font-size: 1.75rem; + color: #1E293B; +} + +@media (max-width: 860px) { + .page-pksh .bento[aria-label="Скачать чек-лист"] .bento-h2 { + font-size: 1.375rem; + } +} + +/* ── Description text ── */ +.page-pksh .bento[aria-label="Скачать чек-лист"] .bento-p { + font-size: 1rem; + color: #475569; + line-height: 1.6; +} + +/* ── CTA button — accent gradient, enhanced sizing ── */ +.page-pksh .bento[aria-label="Скачать чек-лист"] .micro-commit__btn { + margin-top: 8px; + padding: 16px 36px; + font-size: 1rem; + border-radius: 100px; + box-shadow: 0 4px 16px rgba(124, 58, 237, 0.20); + transition: transform 0.2s ease, box-shadow 0.2s ease; +} + +.page-pksh .bento[aria-label="Скачать чек-лист"] .micro-commit__btn:hover { + transform: translateY(-2px); + box-shadow: 0 8px 24px rgba(124, 58, 237, 0.30); +} + +/* ── Disclaimer — subtle on warm card bg ── */ +.page-pksh .bento[aria-label="Скачать чек-лист"] .micro-commit__disclaimer { + font-size: 0.75rem; + color: #94A3B8; + margin: 8px 0 0; +} + +/* ============================================================ + 42. REVIEWS — standalone section (camp-style) + lw-card rendering from Carbon Fields complex field. + Same pattern as .camp-reviews on camp page. + ============================================================ */ + +/* ── Section full-width background ── */ +.page-pksh .pksh-reviews { + position: relative; + padding: 80px 32px; + max-width: 1280px; + margin: 0 auto; +} + +/* ── Layout utilities (scoped) ── */ +.page-pksh .pksh-reviews .lw-scroll-x { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + padding-bottom: 8px; +} +.page-pksh .pksh-reviews .lw-scroll-x::-webkit-scrollbar { + height: 6px; +} +.page-pksh .pksh-reviews .lw-scroll-x::-webkit-scrollbar-thumb { + background: #ccc; + border-radius: 8px; +} + +.page-pksh .pksh-reviews .lw-grid { + display: grid; +} +.page-pksh .pksh-reviews .lw-grid--3 { + grid-template-columns: repeat(3, 1fr); +} +.page-pksh .pksh-reviews .lw-gap-20 { + gap: 20px; +} + +.page-pksh .pksh-reviews .lw-flex { + display: flex; +} +.page-pksh .pksh-reviews .lw-flex--row { + flex-direction: row; +} +.page-pksh .pksh-reviews .lw-flex--col { + flex-direction: column; +} +.page-pksh .pksh-reviews .lw-gap-12 { + gap: 12px; +} +.page-pksh .pksh-reviews .lw-items-center { + align-items: center; +} + +/* ── Card ── */ +.page-pksh .pksh-reviews .lw-card { + background: #FFFFFF; + border-radius: 20px; + padding: 20px; + display: flex; + flex-direction: column; + transition: box-shadow 0.3s ease, transform 0.3s ease; +} + +/* ── Avatar ── */ +.page-pksh .pksh-reviews .lw-avatar { + border-radius: 50%; + overflow: hidden; + flex-shrink: 0; + background: rgba(124, 58, 237, 0.08); + display: flex; + align-items: center; + justify-content: center; +} +.page-pksh .pksh-reviews .lw-avatar--48 { + width: 48px; + height: 48px; +} +.page-pksh .pksh-reviews .lw-avatar__img { + width: 100%; + height: 100%; + object-fit: cover; + display: block; +} + +/* ── Typography ── */ +.page-pksh .pksh-reviews .lw-text-dark { + color: #1c2b2d; +} +.page-pksh .pksh-reviews .lw-font-semibold { + font-weight: 600; +} + +/* ── Spacing ── */ +.page-pksh .pksh-reviews .lw-mt-8 { + margin-top: 8px; +} + +/* ── Badge ── */ +.page-pksh .pksh-reviews .lw-badge { + display: inline-flex; + align-items: center; + padding: 4px 10px; + border-radius: 50px; + font-size: 11px; + font-weight: 600; + line-height: 1.2; + white-space: nowrap; + margin-left: auto; + flex-shrink: 0; +} +.page-pksh .pksh-reviews .lw-badge--verified { + background: rgba(124, 58, 237, 0.08); + color: #7C3AED; +} + +/* ── Stars ── */ +.page-pksh .pksh-reviews .lw-stars { + display: flex; + gap: 2px; + align-items: center; +} +.page-pksh .pksh-reviews .lw-star { + color: #D1D5DB; + flex-shrink: 0; +} +.page-pksh .pksh-reviews .lw-star--filled { + color: #FFD43E; +} + +/* ── Card text ── */ +.page-pksh .pksh-reviews .lw-card__text { + font-size: 14px; + line-height: 1.55; + color: #475569; + word-break: break-word; +} + +/* ── Desktop: flex-wrap centered grid ── */ +.page-pksh .pksh-reviews .lw-scroll-x { + overflow: visible; + padding: 0; +} +.page-pksh .pksh-reviews .lw-grid--3 { + display: flex; + flex-wrap: wrap; + gap: 30px; + justify-content: center; +} +.page-pksh .pksh-reviews .lw-grid--3 .lw-card { + width: calc(25% - 23px); + min-width: 280px; + padding: 24px; + box-shadow: 0 2px 16px rgba(0,0,0,0.06); +} +.page-pksh .pksh-reviews .lw-grid--3 .lw-card:hover { + box-shadow: 0 8px 32px rgba(0,0,0,0.1); + transform: translateY(-4px); +} + +@media (max-width: 1200px) { + .page-pksh .pksh-reviews .lw-grid--3 .lw-card { + width: calc(50% - 15px); + min-width: 280px; + } +} + +@media (max-width: 768px) { + .page-pksh .pksh-reviews { + padding: 40px 0; + } + .page-pksh .pksh-reviews .lw-scroll-x { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + padding: 0 0 8px 16px; + margin: 0; + } + .page-pksh .pksh-reviews .lw-grid--3 { + display: flex; + gap: 12px; + overflow-x: auto; + scroll-snap-type: x mandatory; + flex-wrap: nowrap; + justify-content: flex-start; + padding: 0 0 4px 0; + margin: 0; + -webkit-overflow-scrolling: touch; + } + .page-pksh .pksh-reviews .lw-grid--3 .lw-card { + flex: 0 0 280px; + width: auto; + min-width: 0; + scroll-snap-align: start; + } + /* Mobile: all cards visible regardless of pagination state */ + .page-pksh .pksh-reviews .lw-card { + display: flex !important; + } + .page-pksh .pksh-reviews__actions { + display: none !important; + } +} + +@media (max-width: 480px) { + .page-pksh .pksh-reviews .lw-grid--3 .lw-card { + flex: 0 0 250px; + } +} + +/* ============================================================ + 43. REVIEWS — pagination / load more + ============================================================ */ +/* Default collapsed: show 2 rows per breakpoint */ +.page-pksh .pksh-reviews [data-pksh-collapsed] .lw-card:nth-child(n+9) { + display: none; +} +@media (max-width: 1200px) { + .page-pksh .pksh-reviews [data-pksh-collapsed] .lw-card:nth-child(n+5) { + display: none; + } +} +/* Expanded: override nth-child, show all */ +.page-pksh .pksh-reviews [data-pksh-expanded] .lw-card { + display: flex; +} +.page-pksh .pksh-reviews__actions { + display: flex; + justify-content: center; + margin-top: 32px; +} +.page-pksh .pksh-reviews__toggle { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 12px 32px; + font-size: 15px; + font-weight: 600; + font-family: inherit; + color: #7C3AED; + background: rgba(124, 58, 237, 0.08); + border: 1.5px solid rgba(124, 58, 237, 0.2); + border-radius: 100px; + cursor: pointer; + transition: background 0.2s, border-color 0.2s, transform 0.15s; +} +.page-pksh .pksh-reviews__toggle:hover { + background: rgba(124, 58, 237, 0.15); + border-color: rgba(124, 58, 237, 0.35); + transform: translateY(-1px); +} +.page-pksh .pksh-reviews__toggle:active { + transform: translateY(0); +} + +/* ============================================================ + 44. CONTACTS — как на странице лагеря + ============================================================ */ +.page-pksh .pksh-contact { + padding: 0; + background: transparent; + box-shadow: none; +} +.page-pksh .pksh-contact__wrapper { + display: flex; + gap: 30px; + align-items: stretch; +} +.page-pksh .pksh-contact__info { + width: 35%; + display: flex; + flex-direction: column; + gap: 8px; + padding: 32px 0; +} +.page-pksh .pksh-contact__subtitle { + font-size: 15px; + font-weight: 700; + line-height: 1.3; + color: var(--slate-500, #64748B); + text-transform: uppercase; + letter-spacing: 0.06em; + margin-top: 12px; +} +.page-pksh .pksh-contact__subtitle:first-child { + margin-top: 0; +} +.page-pksh .pksh-contact__value { + font-size: clamp(17px, 2vw, 22px); + font-weight: 600; + line-height: 1.3; + color: var(--accent, #7C3AED); + text-decoration: none; +} +.page-pksh .pksh-contact__value:hover { + text-decoration: underline; +} +.page-pksh .pksh-contact__social { + display: flex; + flex-wrap: wrap; + gap: 12px; +} +.page-pksh .pksh-contact__social-link { + display: inline-flex; + align-items: center; + font-size: clamp(16px, 1.8vw, 20px); + font-weight: 600; + color: var(--accent, #7C3AED); + text-decoration: none; + transition: color 0.2s; + position: relative; +} +.page-pksh .pksh-contact__social-link:hover { + color: var(--accent-hover, #6D28D9); +} +.page-pksh .pksh-contact__social-link + .pksh-contact__social-link::before { + content: '·'; + margin-right: 12px; + color: var(--slate-400, #94A3B8); + font-weight: 400; +} +.page-pksh .pksh-contact__map { + flex: 1; + border-radius: 24px; + overflow: hidden; + min-height: 400px; + box-shadow: 0 4px 20px rgba(0,0,0,0.08); +} + +@media (max-width: 768px) { + .page-pksh .pksh-contact__wrapper { + flex-direction: column-reverse; + } + .page-pksh .pksh-contact__info { + width: 100%; + padding: 0; + } + .page-pksh .pksh-contact__map { + min-height: 280px; + margin: 0 -20px; + border-radius: 0; + box-shadow: none; + } +} + +/* ============================================================ + 45. FAQ — как на странице лагеря (pksh-faq) + ============================================================ */ +.page-pksh .pksh-faq { + padding: 0; + background: transparent; + box-shadow: none; +} +.page-pksh .pksh-faq__wrapper { + display: flex; + gap: 30px; +} +.page-pksh .pksh-faq__col { + width: 50%; + display: flex; + flex-direction: column; + gap: 0; + border-top: 1px solid var(--slate-200, #E2E8F0); +} +.page-pksh .pksh-faq .box__accordion { + position: relative; + cursor: pointer; + border-bottom: 1px solid var(--slate-200, #E2E8F0); + border-radius: 0; +} +.page-pksh .pksh-faq .box__accordion_label { + position: relative; + padding: 20px 0; + cursor: pointer; + display: flex; + align-items: center; + gap: 20px; + justify-content: space-between; + padding-left: 0; +} +.page-pksh .pksh-faq .box__accordion_label span { + font-size: clamp(17px, 2vw, 21px); + line-height: 1.3; + font-weight: 600; + color: var(--navy, #1c2b2d); +} +.page-pksh .pksh-faq .box__accordion_label svg { + width: 36px; + height: 36px; + padding: 8px; + border-radius: 50%; + background: var(--accent, #7C3AED); + stroke: #fff; + transition: background 0.2s; + flex-shrink: 0; +} +.page-pksh .pksh-faq .box__accordion_label svg g { + stroke: #fff; +} +.page-pksh .pksh-faq .active .box__accordion_label svg { + rotate: 45deg; + background: var(--accent-hover, #6D28D9); +} +.page-pksh .pksh-faq .box__accordion_content { + display: flex; + position: relative; + overflow: hidden; + max-height: 0; + transition: max-height 0.3s; + gap: 20px; + align-items: center; +} +.page-pksh .pksh-faq .box__accordion_content-text { + display: flex; + flex-direction: column; + gap: 10px; + font-size: 16px; + line-height: 1.6; + color: var(--slate-600, #475569); + padding-bottom: 20px; +} + +@media (max-width: 768px) { + .page-pksh .pksh-faq__wrapper { + flex-direction: column; + gap: 0; + } + .page-pksh .pksh-faq__col { + width: 100%; + border-top: none; + } + .page-pksh .pksh-faq__col:first-child { + border-top: 1px solid var(--slate-200, #E2E8F0); + } +} + +/* ============================================================ + 46. TEACHERS — camp-style cards + ============================================================ */ +.page-pksh .pksh-section--teachers { + background: var(--bg-soft-2026, #F8FAFC); + padding-top: 60px; + padding-bottom: 60px; +} + +.page-pksh .pksh-section--teachers .bento-h2 { + text-align: center; +} + +.pksh-teachers__wrapper { + display: flex; + flex-wrap: wrap; + gap: 24px; + justify-content: center; +} + +.pksh-teachers__item { + width: calc(25% - 18px); + min-width: 240px; +} + +.pksh-teachers__card { + background: #fff; + border-radius: 20px; + overflow: hidden; + box-shadow: 0 2px 12px rgba(0,0,0,0.06); + transition: transform 0.25s ease, box-shadow 0.25s ease; + display: flex; + flex-direction: column; + height: 100%; +} + +.pksh-teachers__card:hover { + transform: translateY(-4px); + box-shadow: 0 8px 24px rgba(0,0,0,0.10); +} + +.pksh-teachers__card-top { + background: linear-gradient(135deg, rgba(124, 58, 237, 0.05), rgba(139, 92, 246, 0.08)); + display: flex; + justify-content: center; + padding: 28px 24px 18px; +} + +.pksh-teachers__photo { + width: 130px; + height: 130px; + border-radius: 50%; + object-fit: cover; + border: 4px solid #fff; + box-shadow: 0 4px 12px rgba(0,0,0,0.08); +} + +.pksh-teachers__card-body { + padding: 18px 24px 24px; + display: flex; + flex-direction: column; + gap: 8px; + flex: 1; +} + +.pksh-teachers__name { + font-size: 1.125rem; + font-weight: 700; + line-height: 1.3; + color: var(--navy, #0F172A); + text-align: center; + margin: 0; +} + +.pksh-teachers__subj { + font-size: 0.875rem; + line-height: 1.4; + color: var(--accent, #7C3AED); + text-align: center; + font-weight: 600; + margin: 0; +} + +.pksh-teachers__about { + font-size: 0.875rem; + line-height: 1.5; + color: var(--slate-600, #475569); + text-align: center; + margin: 0; +} + +@media (max-width: 768px) { + .page-pksh .pksh-section--teachers { + padding-top: 40px; + padding-bottom: 40px; + } + .pksh-teachers__item { + width: calc(50% - 12px); + min-width: 0; + } + .pksh-teachers__wrapper { + gap: 16px; + } + .pksh-teachers__card-top { + padding: 24px 16px 14px; + } + .pksh-teachers__photo { + width: 110px; + height: 110px; + } + .pksh-teachers__card-body { + padding: 14px 18px 20px; + gap: 6px; + } + .pksh-teachers__name { + font-size: 1rem; + } + .pksh-teachers__subj, + .pksh-teachers__about { + font-size: 0.8125rem; + } +} + +@media (max-width: 480px) { + .pksh-teachers__item { + width: 100%; + max-width: 320px; + } +} + +@supports (scrollbar-width: thin) { + .pksh-teachers__scroll-x { + scrollbar-width: thin; + scrollbar-color: #ccc transparent; + } +} +.pksh-teachers__scroll-x::-webkit-scrollbar { + height: 6px; +} +.pksh-teachers__scroll-x::-webkit-scrollbar-thumb { + background: #ccc; + border-radius: 8px; +} + +/* ═══════════════════════════════════════════════════════════ + 42. BACKGROUND SYSTEM v2.1 — Coherent warm palette + Unified background rhythm across all sections. + + PROBLEMS SOLVED: + • White cluster — 3+ white sections in a row + • Warm/cool undertone conflict — #F8F4F0 vs #F8FAFC + • Missing backgrounds — Programs etc had no explicit bg + • Inconsistent rhythm — no visual breathing between sections + + DESIGN: + • WARM (#F8F4F0) = rhythm sections — how-it-works, + programs, teachers, final CTA + • WARM-ALT (#F5F0E8) = variety — FAQ + • WHITE = clean backdrop for content cards — checklist, + guarantee hero, results, guarantee standalone + • NAVY = emphasis — results inner card (unchanged) + ═══════════════════════════════════════════════════════ */ + +/* ── 42a. Global --alt override: warm instead of cool ── */ +/* Main.css gives .pksh-section--alt: var(--bg-soft) = #F8FAFC (cool gray). + This overrides all --alt sections to warm palette. + NOTE: uses background shorthand (not background-color) because + these sections do NOT have decorative background-image patterns. */ +.page-pksh .pksh-section--alt { + background: var(--bg-warm, #F8F4F0); +} + +/* ── 42b. Section-by-section background color assignments ── */ +/* Uses background-color (not shorthand) to avoid resetting + background-image set in 42d. */ + +/* 🔵 WHITE (#FFFFFF) — Checklist (clean card presentation) */ +.page-pksh .bento[aria-label="Скачать чек-лист"] { + background-color: #FFFFFF; +} + +/* 🔵 WHITE — Guarantee hero (strong purple border card) */ +.page-pksh .bento[aria-label="Гарантия"] { + background-color: #FFFFFF; +} + +/* 🔵 WHITE — Results (navy inner card needs clean backdrop) */ +.page-pksh #results.bento.pksh-section--alt { + background-color: #FFFFFF; +} + +/* 🔵 WHITE — Guarantee standalone (clean) */ +.page-pksh #guarantee.bento.pksh-section--alt { + background-color: #FFFFFF; +} + +/* 🟤 WARM — Programs (was transparent, now rhythm warm) */ +.page-pksh #programs.bento.pksh-section { + background-color: var(--bg-warm, #F8F4F0); +} + +/* 🟤 WARM — Final CTA (was cool via --alt, now warm) */ +.page-pksh #final-cta.bento.pksh-section--alt { + background-color: var(--bg-warm, #F8F4F0); +} + +/* 🟠 WARM-ALT — FAQ (warm stone for variety) */ +.page-pksh #faq.bento.pksh-section--alt { + background-color: var(--bg-warm-alt, #F5F0E8); +} + +/* ── 42c. Contacts — transparent (let footer handle it) ── */ +.page-pksh #pksh-contact.bento.pksh-section { + background-color: transparent; +} + +/* ── 42d. Background decorative gradients ── */ +/* Adds subtle radial gradient overlays to warm sections + for subtle depth without visual noise. + Safely combines with background-color from 42b. */ +.page-pksh #programs.bento.pksh-section { + background-image: + radial-gradient(ellipse at 80% 20%, rgba(124, 58, 237, 0.018) 0%, transparent 55%), + radial-gradient(ellipse at 10% 80%, rgba(0, 0, 0, 0.012) 0%, transparent 50%); +} + +.page-pksh #final-cta.bento.pksh-section--alt { + background-image: + radial-gradient(ellipse at 50% 0%, rgba(124, 58, 237, 0.025) 0%, transparent 60%); +} + +.page-pksh #faq.bento.pksh-section--alt { + background-image: + radial-gradient(ellipse at 30% 90%, rgba(124, 58, 237, 0.015) 0%, transparent 50%), + radial-gradient(ellipse at 70% 10%, rgba(0, 0, 0, 0.01) 0%, transparent 50%); +} + +/* ── 42e. Section separators ── */ +/* Subtle light border-top on warm sections following white + to create intentional visual stratification. */ +.page-pksh #programs.bento.pksh-section, +.page-pksh #final-cta.bento.pksh-section--alt { + border-top: 1px solid rgba(0, 0, 0, 0.03); +} + +/* ── 42f. Mobile-responsive final CTA ── */ +@media (max-width: 860px) { + .page-pksh #final-cta.bento.pksh-section--alt { + background-color: var(--bg-warm, #F8F4F0); + background-image: + radial-gradient(ellipse at 50% 0%, rgba(124, 58, 237, 0.025) 0%, transparent 60%); + } +} diff --git a/wp-content/themes/dekart/assets/css/reviews-page.css b/wp-content/themes/dekart/assets/css/reviews-page.css index 74c12d3..d9ae6b4 100644 --- a/wp-content/themes/dekart/assets/css/reviews-page.css +++ b/wp-content/themes/dekart/assets/css/reviews-page.css @@ -23,6 +23,11 @@ --transition-fast: 0.2s ease; --transition-normal: 0.3s ease; --color-bg: #fff; + --color-bg-warm: #F8F4EF; + --color-bg-alt: #EEF3EE; + --bg-hero: var(--color-bg-warm); + --bg-white: var(--color-bg); + --bg-mint: var(--color-bg-alt); --accent: #7C3AED; --accent-hover: #6D28D9; --accent-light: #F5F3FF; @@ -771,8 +776,8 @@ gap: 20px; justify-content: space-between; } -.reviews-faq .box__accordion_label::after { - background-image: none !important; +.reviews-faq .accordion .box__accordion .box__accordion_label::after { + background-image: none; } .reviews-faq .box__accordion_label span { font-size: clamp(18px, 2.2vw, 22px); @@ -1198,10 +1203,9 @@ /* Сетка отзывов: мобильный скролл */ @media (max-width: 768px) { - /* ─── Hero: фото скрыто, текст на всю ширину с отступами ─── */ - .reviews-hero { - padding-left: 20px; - padding-right: 20px; + /* ─── Container: единый отступ для всех секций ─── */ + .page-reviews .container { + padding: 0 20px; } .reviews-hero__image { display: none; @@ -1210,7 +1214,7 @@ max-width: none; } .reviews-hero__metrics { - flex-wrap: nowrap; + flex-wrap: wrap; gap: 10px; } .reviews-intro__grid { @@ -1261,10 +1265,10 @@ display: block; } - /* ─── Бейдж в колонке имени: убираем inline-переопределения с мобилки ─── */ + /* ─── Бейдж в колонке имени ─── */ .reviews-cards .lw-card .lw-badge--verified { - margin-top: 6px !important; - margin-left: 0 !important; + margin-top: 6px; + margin-left: 0; } /* ─── Звёзды: абсолютно в правый верхний угол карточки ─── */ @@ -1877,6 +1881,23 @@ } } +/* ─── SECTION-BG (full-width background utilities) ─── */ +.section-bg { + position: relative; +} +.section-bg::before { + content: ''; + position: absolute; + top: 0; + bottom: 0; + left: calc(-50vw + 50%); + width: 100vw; + z-index: -1; +} +.section-bg[data-bg="hero"]::before { background: var(--bg-hero); } +.section-bg[data-bg="white"]::before { background: var(--bg-white); } +.section-bg[data-bg="mint"]::before { background: var(--color-bg-alt); } + /* ─── PREFERS-REDUCED-MOTION ─── */ @media (prefers-reduced-motion: reduce) { .reveal, @@ -1903,4 +1924,44 @@ } } +/* ─── САМЫЕ МАЛЕНЬКИЕ ЭКРАНЫ (≤375px) ─── */ +@media (max-width: 375px) { + .reviews-hero__h1 { + font-size: 22px; + } + .reviews-hero__metrics { + gap: 6px; + } + .reviews-hero__metric { + padding: 10px 6px; + } + .reviews-hero__metric-number { + font-size: 20px; + } + .reviews-hero__metric-label { + font-size: 10px; + } + .reviews-cards .lw-grid--3 { + grid-template-columns: 1fr; + } + .results__card { + flex: 0 0 50%; + max-width: 50%; + padding: 16px 8px; + } + .results__grid { + gap: 0; + } + .cross-links__grid { + grid-template-columns: 1fr; + } + .final-cta__title { + font-size: 22px; + } + .reviews-hero__cta-btn { + padding: 14px 20px; + font-size: 15px; + } +} + diff --git a/wp-content/themes/dekart/assets/js/add.js b/wp-content/themes/dekart/assets/js/add.js index bf58329..cf64ae1 100644 --- a/wp-content/themes/dekart/assets/js/add.js +++ b/wp-content/themes/dekart/assets/js/add.js @@ -52,12 +52,20 @@ document.addEventListener("click", function (event) { } if (target.classList.contains("btn-write")) { modalRequestForm.style=""; + document.querySelector('html').style = "overflow: hidden;"; return; } - if (target.classList.contains("btn-close-request-form-img")) { + if (target.classList.contains("btn-close-request-form") || target.classList.contains("btn-close-request-form-img")) { modalRequestForm.style="display: none;"; + document.querySelector('html').style = ""; return; - } + } + // Клик по фону (затемнению) — закрыть модалку + if (target === modalRequestForm) { + modalRequestForm.style="display: none;"; + document.querySelector('html').style = ""; + return; + } if(target.classList.contains("hover-effect")) { target.classList.remove("hover-effect"); @@ -230,4 +238,93 @@ setTimeout(() => { document.querySelectorAll('.header-menu').forEach(item => { item.classList.add('hover-effect'); -}) \ No newline at end of file +}) + +/* ── Scroll Progress Bar ── */ +(function() { + var progressBar = document.createElement('div'); + progressBar.className = 'pksh-scroll-progress'; + document.body.prepend(progressBar); + + function updateProgress() { + var scrollTop = window.pageYOffset || document.documentElement.scrollTop; + var docHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight; + var progress = (scrollTop / docHeight) * 100; + progressBar.style.width = progress + '%'; + } + + window.addEventListener('scroll', updateProgress, { passive: true }); + window.addEventListener('resize', updateProgress, { passive: true }); + updateProgress(); +})(); + +/* ── Desktop Sticky CTA — show after hero ── */ +(function() { + var sticky = document.querySelector('.sticky-cta-desktop'); + var hero = document.querySelector('.banner'); + if (!sticky || !hero) return; + + var observer = new IntersectionObserver(function(entries) { + entries.forEach(function(entry) { + // Show sticky CTA when hero is NOT visible (scrolled past) + sticky.classList.toggle('visible', !entry.isIntersecting); + }); + }, { threshold: 0 }); + + observer.observe(hero); +})(); + +/* ── Mobile banner padding: compensate for fixed header ── */ +(function() { + var banner = document.querySelector('.page-pksh .banner'); + var header = document.querySelector('.header'); + if (banner && header && window.innerWidth <= 860) { + var headerH = header.offsetHeight || 76; + banner.style.paddingTop = headerH + 'px'; + banner.style.marginTop = '-' + headerH + 'px'; + } +})(); + +/* ── .open-bitrix-form → opens modal form ── */ +document.querySelectorAll('.open-bitrix-form').forEach(btn => { + btn.addEventListener('click', function(e) { + const modal = document.querySelector('.modal-request-form'); + if (modal) { + modal.style = ""; + } + }); +}); + +// Закрытие модалки по Escape +document.addEventListener("keydown", function(e) { + if (e.key === "Escape") { + const modal = document.querySelector('.modal-request-form'); + if (modal && modal.style.display !== "none") { + modal.style.display = "none"; + document.querySelector('html').style = ""; + } + } +}); + +/* ── FAQ Accordion (mystyle-accordion) ── */ +document.querySelectorAll('.mystyle-accordion-trigger').forEach(trigger => { + trigger.addEventListener('click', function(e) { + const item = this.closest('.mystyle-accordion-item'); + if (!item) return; + const isOpen = item.classList.contains('active'); + // Закрываем все другие аккордеоны в том же контейнере + const parent = item.parentElement; + if (parent) { + parent.querySelectorAll('.mystyle-accordion-item.active').forEach(other => { + if (other !== item) { + other.classList.remove('active'); + } + }); + } + if (isOpen) { + item.classList.remove('active'); + } else { + item.classList.add('active'); + } + }); +}); \ No newline at end of file diff --git a/wp-content/themes/dekart/assets/js/front-page.js b/wp-content/themes/dekart/assets/js/front-page.js new file mode 100644 index 0000000..e90e1db --- /dev/null +++ b/wp-content/themes/dekart/assets/js/front-page.js @@ -0,0 +1,45 @@ +/** + * front-page.js — обработчики для шаблона front-page.php + * Извлечены из inline + + + + + + + \ No newline at end of file diff --git a/wp-content/themes/dekart/front-page.php b/wp-content/themes/dekart/front-page.php index ac5ef03..6259e64 100644 --- a/wp-content/themes/dekart/front-page.php +++ b/wp-content/themes/dekart/front-page.php @@ -5,6 +5,11 @@ Template Name: шаблон главной страницы get_header(); $post_id = get_the_ID(); + +// ─── ДАННЫЕ ФИЛИАЛА ─── +$branch_email = get_option( 'branch_email' ) ?: carbon_get_theme_option( 'site_mail' ) ?: ''; +$branch_phone = get_option( 'branch_phone' ) ?: carbon_get_theme_option( 'site_phone' ) ?: ''; +$branch_name = get_option( 'branch_name' ) ?: carbon_get_theme_option( 'site_name' ) ?: 'Декарт'; ?>
@@ -61,14 +66,14 @@ $post_id = get_the_ID();

Наши услуги

-
+
Начальная школа

Обучение ведётся по программе «Перспектива» и методике Занкова в соответствии с ФГОС, включая изучение английского языка с 1 класса.

-
+
Подготовка к школе

Программа для будущих первоклассников: развитие базовых навыков, логики и речи через игровые задания.

@@ -76,7 +81,7 @@ $post_id = get_the_ID(); Узнать подробнее >
-
+
Группы продлённого дня

Помощь с домашними заданиями, творческие и развивающие занятия.

@@ -85,21 +90,21 @@ $post_id = get_the_ID();
-
+
Подготовка к экзаменам ОГЭ, ЕГЭ и ВПР

Интенсивная подготовка к экзаменам ВПР, ОГЭ и ЕГЭ по всем предметам школьной программы.

-
+
Летний городской лагерь

Образование, творчество и наука в тематических сменах.

-
+
Кружки и секции

Творческие студии, спортивные секции и развивающие занятия для детей всех возрастов.

@@ -120,11 +125,11 @@ $post_id = get_the_ID(); $block_text_1 = '

В нашей частной школе в Щелково мы знаем каждого ученика по имени. Небольшие классы до 12 человек, педагоги с опытом от 10 лет и углублённый английский с 1 класса. Работаем по программе «Перспектива» и методике Занкова. Принимаем детей из Щелково, Фрязино и Ивантеевки. Лицензия Министерства образования Московской области.

'; } ?> -
+
-
+
@@ -132,12 +137,22 @@ $post_id = get_the_ID();
-
+
-
-

Запишитесь на бесплатную экскурсию по школе и познакомьтесь с нашей программой!

-

Получите персональную консультацию и узнайте стоимость обучения прямо сейчас.

- +
+

Запишитесь на бесплатную экскурсию по школе и познакомьтесь с нашей программой!

+

Получите персональную консультацию и узнайте стоимость обучения прямо сейчас.

+ +
+
+
+ + + @@ -207,8 +222,8 @@ $post_id = get_the_ID(); "sameAs": ["https://vk.com/shkola_dekart"], "contactPoint": { "@type": "ContactPoint", - "telephone": "+79303334151", - "email": "shelkovo@dekart-school.ru", + "telephone": "", + "email": "", "contactType": "customer service", "areaServed": "RU", "availableLanguage": "Russian" @@ -296,27 +311,7 @@ $post_id = get_the_ID(); } - - + diff --git a/wp-content/themes/dekart/functions.php b/wp-content/themes/dekart/functions.php index aadb289..08455ea 100644 --- a/wp-content/themes/dekart/functions.php +++ b/wp-content/themes/dekart/functions.php @@ -189,6 +189,9 @@ function add_carbon() { Field::make( 'text', 'site_map_link', 'Ссылка на карту:' ), Field::make( 'text', 'site_location', 'Координаты адреса (для яндекc карт):' ), Field::make( 'text', 'site_frame_reviews', 'Ссылка на страницу с отзывами:' ), + Field::make( 'text', 'site_lk_url', 'Ссылка на личный кабинет (ЛК):' ) + ->set_default_value( 'https://lk.dekart-school.ru/' ) + ->set_help_text( 'URL личного кабинета для учеников/родителей. По умолчанию: https://lk.dekart-school.ru/' ), Field::make( 'textarea', 'site_bitrix_script', 'script (формы) БИТРИКС24:' ), Field::make( 'textarea', 'site_bitrix_vacancies', 'script (для формы связаться с нами) БИТРИКС24:' ), Field::make( 'checkbox', 'check_banner', 'Отображать плашку со скидкой на формах "Запись на бесплатное пробное занятие"' ) @@ -247,6 +250,9 @@ function add_carbon() { Field::make( 'text', 'schema_legal_name', 'Юридическое название (legalName)' ) ->set_width( 50 ) ->set_help_text( 'Полное юр. название организации. Например: "ИП Иванов Иван Иванович"' ), + Field::make( 'textarea', 'schema_description', 'Описание организации (description)' ) + ->set_width( 100 ) + ->set_help_text( 'Короткое описание для Schema.org Organization → School. Появляется в сниппете поисковиков. Рекомендуется 1–2 предложения: тип школы, классы, местоположение. Пример: "Частная школа полного дня в Щёлково. Обучение с 1 по 11 класс, подготовка к ЕГЭ и ОГЭ, индивидуальный подход." Если пусто — собирается автоматически из названия и города.' ), Field::make( 'text', 'schema_postal_code', 'Почтовый индекс (postalCode)' ) ->set_width( 50 ) ->set_help_text( 'Индекс для address.postalCode в микроразметке.' ), @@ -292,6 +298,9 @@ function add_carbon() { ) ), Field::make( 'media_gallery', 'schema_photos', 'Фотографии филиала (image[])' ) ->set_help_text( 'Выберите фотографии интерьера/экстерьера для image[].' ), + Field::make( 'textarea', 'schema_area_served', 'Города присутствия (areaServed)' ) + ->set_width( 100 ) + ->set_help_text( 'Список городов через запятую, где работает школа. Первый город должен совпадать с городом филиала. Пример: Щёлково, Фрязино, Монино, Ивантеевка, Королёв. Влияет на локальный поиск Google и Яндекса — школа будет показываться по этим городам. Если пусто — используется только город филиала.' ), )); // (пусто — старые поля banner_img_desktop, banner_img_mobile, @@ -1023,8 +1032,12 @@ function add_carbon() { ->set_html( '

Секция: .reviews-intro — SEO-текст в начале страницы. Управляется из админки, чтобы можно было править текст без редактирования шаблона.

' ), Field::make( 'text', 'reviews_intro_price_text', 'Стоимость обучения (текст)' ) ->set_default_value( 'от 40 000 ₽ в месяц' ) - ->set_width( 100 ) + ->set_width( 50 ) ->set_help_text( 'Текст стоимости в блоке .reviews-intro__info. Пример: «от 40 000 ₽ в месяц» или «от 35 000 ₽/мес». Если поле пусто — строка не выводится.' ), + Field::make( 'text', 'reviews_intro_hours', 'Режим работы (текст)' ) + ->set_default_value( 'ежедневно с 8:00 до 19:00, кроме воскресенья' ) + ->set_width( 50 ) + ->set_help_text( 'Текст режима работы в блоке .reviews-intro__info. Отображается на странице отзывов под SEO-текстом. Пример: «ежедневно с 8:00 до 19:00, кроме воскресенья» или «Пн–Пт: 08:00–19:00, Сб: 09:00–14:00». Если пусто — строка не выводится.' ), Field::make( 'textarea', 'reviews_intro_lead', 'Лид-абзац (первый, крупный)' ) ->set_default_value( 'Частная школа Декарт в Щёлково — это образовательное пространство, где каждый ребёнок получает внимание, заботу и качественные знания. Мы работаем в Щёлковском городском округе с 2010 года и за это время помогли раскрыть потенциал сотням учеников. Отзывы родителей о школе Декарт — это реальные истории семей, которые доверили нам образование своих детей. Мы публикуем их, чтобы вы могли принять взвешенное решение.' ) ->set_help_text( 'Первый, самый заметный абзац. Отображается крупнее остальных, отделён линией. 150–180 символов — оптимально. Должен вовлекать и отвечать на главный вопрос посетителя.' ), @@ -1252,9 +1265,12 @@ function exclude_custom_taxonomy_posts($query) { function add_og_image() { $term = get_queried_object(); - if ($term->term_id) { - $snippet = carbon_get_term_meta( $term->term_id, 'snippet' ); - if ($snippet != '') echo '' . "\n"; + if ( ! is_a( $term, 'WP_Term' ) || empty( $term->term_id ) ) { + return; + } + $snippet = carbon_get_term_meta( $term->term_id, 'snippet' ); + if ( $snippet ) { + echo '' . "\n"; } } add_action( 'wp_head', 'add_og_image' ); @@ -1317,12 +1333,8 @@ function enqueue_template_specific_styles() { ); } if ( is_page_template('page-reviews.php') ) { - wp_enqueue_style( - 'phosphor-icons', - 'https://unpkg.com/@phosphor-icons/web@2.1.1/src/regular/style.css', - array(), - '2.1.1' - ); + // Phosphor Icons загружаются через preload+onload в wp_head (page-reviews.php:46) + // Не используем wp_enqueue_style — избегаем render-blocking wp_enqueue_style( 'reviews-page-style', get_template_directory_uri() . '/assets/css/reviews-page.css', @@ -1665,7 +1677,6 @@ function dekart_branch_register_settings() { register_setting( 'dekart_branch_group', 'branch_social' ); register_setting( 'dekart_branch_group', 'branch_messengers' ); register_setting( 'dekart_branch_group', 'branch_button_script', array( 'sanitize_callback' => 'dekart_sanitize_script_field' ) ); - register_setting( 'dekart_branch_group', 'branch_hours', array( 'sanitize_callback' => 'sanitize_text_field' ) ); register_setting( 'dekart_branch_group', 'branch_myreviews_widget', array( 'sanitize_callback' => 'sanitize_text_field' ) ); register_setting( 'dekart_branch_group', 'branch_ext_yandex', array( 'sanitize_callback' => 'esc_url_raw' ) ); register_setting( 'dekart_branch_group', 'branch_ext_google', array( 'sanitize_callback' => 'esc_url_raw' ) ); @@ -1673,6 +1684,12 @@ function dekart_branch_register_settings() { register_setting( 'dekart_branch_group', 'branch_ext_otzovik', array( 'sanitize_callback' => 'esc_url_raw' ) ); register_setting( 'dekart_branch_group', 'branch_ext_other_name', array( 'sanitize_callback' => 'sanitize_text_field' ) ); register_setting( 'dekart_branch_group', 'branch_ext_other_url', array( 'sanitize_callback' => 'esc_url_raw' ) ); + register_setting( 'dekart_branch_group', 'branch_og_site_name', array( 'sanitize_callback' => 'sanitize_text_field' ) ); + register_setting( 'dekart_branch_group', 'branch_ext_review_count', array( 'sanitize_callback' => 'absint' ) ); + register_setting( 'dekart_branch_group', 'branch_avg_rating', array( 'sanitize_callback' => 'sanitize_text_field' ) ); + register_setting( 'dekart_branch_group', 'branch_remaining_seats', array( 'sanitize_callback' => 'absint' ) ); + register_setting( 'dekart_branch_group', 'branch_schema_description', array( 'sanitize_callback' => 'sanitize_textarea_field' ) ); + register_setting( 'dekart_branch_group', 'branch_area_served', array( 'sanitize_callback' => 'sanitize_text_field' ) ); // Поля branch_map_url, branch_founded, branch_photos — удалены. // Они дублировали CF таб «SEO и микроразметка» (schema_*). // Чтение: inc/schema.php → dekart_schema_option() → CF → Settings API (backward compat). @@ -1844,26 +1861,40 @@ function dekart_branch_settings_page() {
+
+ + +

Значение тега og:site_name — отображается в сниппетах Яндекса и Google. Рекомендуется: «Частная школа Декарт в Щёлково». Если оставить пустым — будет использован заголовок сайта из настроек WordPress.

+

Для микроразметки. Например: "$", "$$", "$$$".

+
+ + +

Отображается в блоке метрик на странице отзывов. Пример: 4.9

+
+
+ + +

Отображается в финальном CTA на странице отзывов: «осталось N мест».

+

ID изображения из Медиафайлы. Для JSON-LD image.

-
-
- - @@ -1922,6 +1953,11 @@ function dekart_branch_settings_page() {
+
+ + +

Отображается в бейдже под метриками: «4.9 из 5 на основе N отзывов на внешних площадках».

+
diff --git a/wp-content/themes/dekart/header.php b/wp-content/themes/dekart/header.php index 2c16546..d185b46 100644 --- a/wp-content/themes/dekart/header.php +++ b/wp-content/themes/dekart/header.php @@ -104,7 +104,7 @@ if ( is_front_page() ) { src="/assets/images/phone-volume.svg" alt="Телефон" loading="lazy"> - -
@@ -158,14 +158,14 @@ if ( is_front_page() ) { 'theme_location' => 'top', ) ); ?> -
- + Личный кабинет diff --git a/wp-content/themes/dekart/inc/schema.php b/wp-content/themes/dekart/inc/schema.php new file mode 100644 index 0000000..3ac296b --- /dev/null +++ b/wp-content/themes/dekart/inc/schema.php @@ -0,0 +1,1245 @@ + 'https://schema.org', + '@graph' => $graph, + ), + JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES + ); + + if ( false === $json ) { + return; // тихий выход вместо WSOD + } + + echo '' . "\n"; +} + +/* ===================================================================== + Сущности @graph + ===================================================================== */ + +/** + * WebPage — текущая страница. + * @see https://schema.org/WebPage + */ +function dekart_schema_webpage(): ?array { + $url = home_url( '/podgotovka-k-shkole/' ); + + // _yoast_wpseo_title — Yoast SEO заголовок + $yoast_title = get_post_meta( 2, '_yoast_wpseo_title', true ); + $name = $yoast_title ?: wp_get_document_title(); + + // _yoast_wpseo_metadesc — Yoast SEO описание + $description = get_post_meta( 2, '_yoast_wpseo_metadesc', true ); + $description = $description ?: get_post_meta( 2, 'rank_math_description', true ); + $description = $description ?: carbon_get_post_meta( 2, 'banner_subtitle' ); + $description = $description ?: 'Подготовка к школе для детей 5–7 лет в Щёлково. Чтение, письмо, математика, логика.'; + + // has_post_thumbnail — изображение страницы (OG-совместимость) + $image_url = ''; + if ( has_post_thumbnail( 2 ) ) { + $image_url = get_the_post_thumbnail_url( 2, 'full' ); + } + + // pksh_level — уровень образования (about) + $about_text = carbon_get_post_meta( 2, 'pksh_level' ) ?: 'Подготовка к школе'; + + // branch_city — город для about и keywords + $city = dekart_branch_option( 'branch_city', 'Щёлково' ); + + $webpage = array( + '@type' => 'WebPage', + '@id' => $url . '#webpage', + 'url' => $url, + 'name' => wp_strip_all_tags( $name ), + 'description' => wp_strip_all_tags( $description ), + 'inLanguage' => str_replace( '_', '-', determine_locale() ?: 'ru' ), + 'isPartOf' => array( + '@id' => home_url( '/' ) . '#website', + ), + 'breadcrumb' => array( + '@id' => $url . '#breadcrumb', + ), + // mainEntity — основной курс на странице + 'mainEntity' => array( + '@id' => $url . '#course', + ), + // speakable — для голосовых помощников и AI-поиска + 'speakable' => array( + '@type' => 'SpeakableSpecification', + 'cssSelector' => array( + 'h1.hero-pksh__title', + '.hero-pksh__subtitle', + ), + ), + // about — тематика страницы (образовательная услуга) + 'about' => array( + '@type' => 'Thing', + 'name' => wp_strip_all_tags( sprintf( '%s в %s', $about_text, $city ) ), + ), + // keywords — метки для поиска + 'keywords' => wp_strip_all_tags( + 'подготовка к школе, дошкольное образование, обучение чтению, обучение письму, ' + . 'математика для дошкольников, развитие логики, курсы для детей 5-7 лет, ' + . $city + ), + ); + + if ( $image_url ) { + $webpage['image'] = esc_url( $image_url ); + } + + // datePublished / dateModified — даты публикации страницы + $post_obj = get_post( 2 ); + if ( $post_obj ) { + $webpage['datePublished'] = get_the_date( 'c', $post_obj ); + $webpage['dateModified'] = get_the_modified_date( 'c', $post_obj ); + } + + // hasPart — ссылка на FAQPage этой страницы + $faq_items = carbon_get_post_meta( 2, 'pksh_faq_items' ); + if ( ! empty( $faq_items ) && is_array( $faq_items ) ) { + $webpage['hasPart'] = array( + '@id' => $url . '#faq', + ); + } + + return $webpage; +} + +/** + * WebSite — главный сайт. + * name из branch_name (единый источник с лагерем), а не из site_name. + */ +function dekart_schema_website(): ?array { + $site_name = dekart_branch_option( 'branch_name', 'Детский центр «Декарт»' ); + $home_url = home_url( '/' ); + + return array( + '@type' => 'WebSite', + '@id' => $home_url . '#website', + 'url' => $home_url, + 'name' => wp_strip_all_tags( $site_name ), + 'potentialAction' => array( + '@type' => 'SearchAction', + 'target' => array( + '@type' => 'EntryPoint', + 'urlTemplate' => $home_url . '?s={search_term_string}', + ), + 'query-input' => 'required name=search_term_string', + ), + ); +} + +/** + * BreadcrumbList — хлебные крошки для страницы. + */ +function dekart_schema_breadcrumb(): ?array { + $page_url = home_url( '/podgotovka-k-shkole/' ); + $home_url = home_url( '/' ); + + return array( + '@type' => 'BreadcrumbList', + '@id' => $page_url . '#breadcrumb', + 'itemListElement' => array( + array( + '@type' => 'ListItem', + 'position' => 1, + 'name' => 'Главная', + 'item' => $home_url, + ), + array( + '@type' => 'ListItem', + 'position' => 2, + 'name' => 'Подготовка к школе', + 'item' => $page_url, + ), + ), + ); +} + +/** + * Helper: получить значение из Carbon Fields (schema_*) с fallback на Settings API (branch_*). + * Работает с любыми типами (включая массивы complex/media_gallery). + * Приоритет: carbon_get_theme_option('schema_*') → get_option('branch_*') → $default. + */ +function dekart_schema_option( string $schema_key, string $branch_key, $default = '' ) { + $val = carbon_get_theme_option( $schema_key ); + if ( ! empty( $val ) ) { + return $val; + } + $val = get_option( $branch_key ); + if ( ! empty( $val ) ) { + return $val; + } + return $default; +} + +/** + * Helper: получить значение из Настроек филиала (branch_*). + * Единый источник: get_option('branch_*'). + * Схема-поля (schema_*) читать через dekart_schema_option() — CF → Settings API. + */ +function dekart_branch_option( string $key, string $default = '' ): string { + $val = get_option( $key ); + if ( ! empty( $val ) && is_string( $val ) ) { + return trim( $val ); + } + return $default; +} + +/** + * Parent Organization — юридическое лицо (без адреса филиала). + * @id совпадает с лагерем — это одна организация. + */ +function dekart_schema_organization(): ?array { + $home_url = home_url( '/' ); + $site_name = dekart_branch_option( 'branch_name', 'Детский центр «Декарт»' ); + + // Логотип: единая цепочка с page-camp.php + $logo_url = dekart_resolve_logo(); + + $org = array( + '@type' => 'Organization', + '@id' => $home_url . '#organization', + 'name' => wp_strip_all_tags( $site_name ), + 'url' => $home_url, + 'logo' => esc_url( $logo_url ), + ); + + // legalName — юридическое наименование (CF schema_legal_name → Settings API branch_legal_name) + $legal_name = dekart_schema_option( 'schema_legal_name', 'branch_legal_name' ); + if ( ! empty( $legal_name ) && is_string( $legal_name ) ) { + $org['legalName'] = wp_strip_all_tags( trim( $legal_name ) ); + } + + // contactPoint — контактный телефон для связи + $cp_phone = dekart_branch_option( 'branch_phone', '' ); + if ( $cp_phone ) { + $org['contactPoint'] = array( + '@type' => 'ContactPoint', + 'telephone' => wp_strip_all_tags( $cp_phone ), + 'contactType' => 'customer service', + 'areaServed' => 'RU', + 'availableLanguage' => 'Russian', + ); + } + + return $org; +} + +/** + * Helper: цепочка разрешения логотипа (аналог page-camp.php:92-103). + * branch_logo (ACF) → banner_img (CF) → custom_logo (WP) → post_thumbnail → fallback SVG. + */ +function dekart_resolve_logo(): string { + // 1. branch_logo — ACF опция филиала + $branch_logo = get_option( 'branch_logo' ); + if ( ! empty( $branch_logo ) ) { + if ( is_array( $branch_logo ) && isset( $branch_logo['url'] ) ) { + return $branch_logo['url']; + } + $url = wp_get_attachment_url( $branch_logo ); + if ( $url ) { + return $url; + } + } + + // 2. banner_img — CF поле страницы + $banner_img = carbon_get_post_meta( 2, 'banner_img' ); + if ( ! empty( $banner_img ) ) { + if ( is_array( $banner_img ) && isset( $banner_img['url'] ) ) { + return $banner_img['url']; + } + $url = wp_get_attachment_url( $banner_img ); + if ( $url ) { + return $url; + } + } + + // 3. custom_logo — WP Customizer + $logo_id = get_theme_mod( 'custom_logo' ); + if ( $logo_id ) { + $url = wp_get_attachment_url( $logo_id ); + if ( $url ) { + return $url; + } + } + + // 4. post_thumbnail страницы + if ( has_post_thumbnail( 2 ) ) { + $url = get_the_post_thumbnail_url( 2, 'full' ); + if ( $url ) { + return $url; + } + } + + // 5. fallback — SVG из темы + return get_template_directory_uri() . '/assets/images/logo-svg.svg'; +} + +/** + * LocalBusiness — филиал/центр с адресом, телефоном. + * Данные из Настроек филиала (branch_*), единый источник с лагерем. + * @id на уровне страницы, parentOrganization → #organization. + * + * @see https://schema.org/LocalBusiness + * @see https://schema.org/EducationalOrganization + */ +function dekart_schema_local_business(): ?array { + $page_url = home_url( '/podgotovka-k-shkole/' ); + $home_url = home_url( '/' ); + + // branch_name — название филиала (get_option) + $site_name = dekart_branch_option( 'branch_name', 'Детский центр «Декарт»' ); + // branch_address — улица + $street = dekart_branch_option( 'branch_address', 'Комсомольская ул., 11' ); + // branch_city — город + $city = dekart_branch_option( 'branch_city', 'Щёлково' ); + // branch_region — регион/область + $region = dekart_branch_option( 'branch_region', 'Московская область' ); + // branch_phone — телефон + $phone = dekart_branch_option( 'branch_phone', '' ); + // branch_email — email + $email = dekart_branch_option( 'branch_email', '' ); + // branch_coords — координаты "lat, lng" из Настроек филиала (Settings API) + $coords = get_option( 'branch_coords' ); + $lat = ''; + $lng = ''; + if ( ! empty( $coords ) && is_string( $coords ) && false !== strpos( $coords, ',' ) ) { + $parts = explode( ',', $coords ); + if ( count( $parts ) >= 2 ) { + $lat = trim( $parts[0] ); + $lng = trim( $parts[1] ); + } + } + // branch_postal_code — почтовый индекс (CF schema_postal_code → Settings API) + $zip = dekart_schema_option( 'schema_postal_code', 'branch_postal_code' ); + // branch_price_range — диапазон цен (Settings API) + $price_range = get_option( 'branch_price_range' ); + // branch_founded — год основания (CF schema_founded → Settings API) + $founded = dekart_schema_option( 'schema_founded', 'branch_founded' ); + // branch_map_url — ссылка на карту для hasMap (CF schema_map_url → Settings API) + $map_url = dekart_schema_option( 'schema_map_url', 'branch_map_url' ); + // branch_hours — часы работы: CF complex (schema_hours) → textarea (branch_hours) + $hours_cf = carbon_get_theme_option( 'schema_hours' ); + + $lb = array( + '@type' => array( 'EducationalOrganization', 'LocalBusiness' ), + '@id' => $page_url . '#localbusiness', + 'name' => wp_strip_all_tags( $site_name ), + 'url' => $home_url, + 'address' => array( + '@type' => 'PostalAddress', + 'streetAddress' => wp_strip_all_tags( $street ), + 'addressLocality' => wp_strip_all_tags( $city ), + 'addressRegion' => wp_strip_all_tags( $region ), + 'addressCountry' => 'RU', + ), + 'parentOrganization' => array( + '@id' => $home_url . '#organization', + ), + ); + + // postalCode — почтовый индекс (условно) + if ( ! empty( $zip ) && is_string( $zip ) ) { + $lb['address']['postalCode'] = trim( $zip ); + } + + // telephone — телефон (условно) + if ( $phone ) { + $lb['telephone'] = wp_strip_all_tags( $phone ); + } + + // email — почта (условно) + if ( $email ) { + $lb['email'] = wp_strip_all_tags( $email ); + } + + // geo — GeoCoordinates (условно: обе координаты не пусты) + if ( ! empty( $lat ) && ! empty( $lng ) ) { + $lb['geo'] = array( + '@type' => 'GeoCoordinates', + 'latitude' => floatval( $lat ), + 'longitude' => floatval( $lng ), + ); + } + + // hasMap — ссылка на карту (условно) + if ( ! empty( $map_url ) && is_string( $map_url ) ) { + $lb['hasMap'] = esc_url( trim( $map_url ) ); + } + + // openingHoursSpecification — часы работы + // Формат 1 (CF complex, schema_hours): [['day_of_week' => 'Monday', 'opens' => '09:00', 'closes' => '20:00', 'day_off' => '']] + // Формат 2 (Settings API textarea, branch_hours): "Monday|09:00|20:00" + $hours_spec = array(); + if ( ! empty( $hours_cf ) && is_array( $hours_cf ) ) { + foreach ( $hours_cf as $entry ) { + $day = isset( $entry['day_of_week'] ) ? trim( $entry['day_of_week'] ) : ''; + if ( empty( $day ) ) { + continue; + } + $is_off = ! empty( $entry['day_off'] ); + if ( $is_off ) { + $hours_spec[] = array( + '@type' => 'OpeningHoursSpecification', + 'dayOfWeek' => $day, + 'opens' => '00:00', + 'closes' => '00:00', + ); + } else { + $from = isset( $entry['opens'] ) ? trim( $entry['opens'] ) : ''; + $to = isset( $entry['closes'] ) ? trim( $entry['closes'] ) : ''; + if ( $from && $to ) { + $hours_spec[] = array( + '@type' => 'OpeningHoursSpecification', + 'dayOfWeek' => $day, + 'opens' => $from, + 'closes' => $to, + ); + } + } + } + } else { + $hours_raw = get_option( 'branch_hours' ); + if ( ! empty( $hours_raw ) && is_string( $hours_raw ) ) { + $lines = explode( "\n", $hours_raw ); + foreach ( $lines as $line ) { + $line = trim( $line ); + if ( empty( $line ) ) { + continue; + } + $parts = explode( '|', $line ); + $day = isset( $parts[0] ) ? trim( $parts[0] ) : ''; + if ( empty( $day ) ) { + continue; + } + if ( isset( $parts[2] ) && 'closed' === strtolower( trim( $parts[2] ) ) ) { + $hours_spec[] = array( + '@type' => 'OpeningHoursSpecification', + 'dayOfWeek' => $day, + 'opens' => '00:00', + 'closes' => '00:00', + ); + continue; + } + $from = isset( $parts[1] ) ? trim( $parts[1] ) : ''; + $to = isset( $parts[2] ) ? trim( $parts[2] ) : ''; + if ( $day && $from && $to ) { + $hours_spec[] = array( + '@type' => 'OpeningHoursSpecification', + 'dayOfWeek' => $day, + 'opens' => $from, + 'closes' => $to, + ); + } + } + } + } + if ( ! empty( $hours_spec ) ) { + $lb['openingHoursSpecification'] = $hours_spec; + } + + // priceRange — строка диапазона цен (условно) + if ( ! empty( $price_range ) && is_string( $price_range ) ) { + $lb['priceRange'] = trim( $price_range ); + } + + // areaServed — город присутствия (условно) + $lb['areaServed'] = array( + '@type' => 'City', + 'name' => wp_strip_all_tags( $city ), + ); + + // foundingDate — год основания (условно) + if ( ! empty( $founded ) && is_string( $founded ) ) { + $lb['foundingDate'] = trim( $founded ); + } + + // sameAs — массив URL соцсетей + // Формат 1 (CF schema_social complex): [['platform' => 'VK', 'url' => 'https://...']] + // Формат 2 (Settings API branch_social): [['name' => 'VK', 'url' => 'https://...']] + $social_cf = carbon_get_theme_option( 'schema_social' ); + $same_as = array(); + if ( ! empty( $social_cf ) && is_array( $social_cf ) ) { + foreach ( $social_cf as $entry ) { + $url = isset( $entry['url'] ) ? trim( $entry['url'] ) : ''; + if ( $url && filter_var( $url, FILTER_VALIDATE_URL ) ) { + $same_as[] = esc_url( $url ); + } + } + } else { + $social_raw = get_option( 'branch_social' ); + if ( ! empty( $social_raw ) && is_array( $social_raw ) ) { + foreach ( $social_raw as $entry ) { + $url = isset( $entry['url'] ) ? trim( $entry['url'] ) : ''; + if ( $url && filter_var( $url, FILTER_VALIDATE_URL ) ) { + $same_as[] = esc_url( $url ); + } + } + } + } + if ( ! empty( $same_as ) ) { + $lb['sameAs'] = $same_as; + } + + // image — массив URL фотографий филиала + // Формат 1 (CF schema_photos media_gallery): [123, 456] + // Формат 2 (Settings API branch_photos): "123, 456" + $photos_cf = carbon_get_theme_option( 'schema_photos' ); + $images = array(); + if ( ! empty( $photos_cf ) && is_array( $photos_cf ) ) { + foreach ( $photos_cf as $id ) { + if ( ! is_numeric( $id ) || $id <= 0 ) { + continue; + } + $url = wp_get_attachment_url( (int) $id ); + if ( $url ) { + $images[] = esc_url( $url ); + } + } + } else { + $photos_raw = get_option( 'branch_photos' ); + if ( ! empty( $photos_raw ) && is_string( $photos_raw ) ) { + $ids = explode( ',', $photos_raw ); + foreach ( $ids as $id ) { + $id = trim( $id ); + if ( ! is_numeric( $id ) || $id <= 0 ) { + continue; + } + $url = wp_get_attachment_url( (int) $id ); + if ( $url ) { + $images[] = esc_url( $url ); + } + } + } + } + if ( ! empty( $images ) ) { + $lb['image'] = $images; + } + + // employee — преподаватели (Person), если есть + $teachers = carbon_get_post_meta( 2, 'pksh_teachers' ); + if ( ! empty( $teachers ) && is_array( $teachers ) ) { + $employee_ids = array(); + foreach ( $teachers as $i => $t ) { + $name = isset( $t['teacher_name'] ) ? trim( $t['teacher_name'] ) : ''; + if ( $name ) { + $employee_ids[] = array( + '@id' => $page_url . '#teacher-' . $i, + ); + } + } + if ( ! empty( $employee_ids ) ) { + $lb['employee'] = $employee_ids; + } + } + + return $lb; +} + +/** + * Course — основной курс «Подготовка к школе». + * Данные из Carbon Fields: banner_h1, banner_subtitle. + * + * @see https://schema.org/Course + * @see https://schema.org/CourseInstance + */ +function dekart_schema_course(): ?array { + $page_url = home_url( '/podgotovka-k-shkole/' ); + $home_url = home_url( '/' ); + + // banner_h1 — заголовок H1 (Course.name) + $name = carbon_get_post_meta( 2, 'banner_h1' ) ?: 'Подготовка к школе 5–7 лет в Щёлково'; + // pksh_description — полное описание курса для микроразметки (textarea) + // Если заполнено — приоритет над banner_subtitle + $pksh_description = carbon_get_post_meta( 2, 'pksh_description' ); + // banner_subtitle — подзаголовок (Course.description) + $description = ! empty( $pksh_description ) ? $pksh_description : ( carbon_get_post_meta( 2, 'banner_subtitle' ) ?: 'Научим читать, считать и писать до школы. Бесплатное пробное занятие.' ); + // Пробное занятие — есть ли в подзаголовке упоминание бесплатно + $has_trial = ! empty( $description ) && false !== mb_stripos( $description, 'бесплатно' ); + // pksh_level — уровень образования + $level = carbon_get_post_meta( 2, 'pksh_level' ); + // pksh_age — возраст + $age = carbon_get_post_meta( 2, 'pksh_age' ); + // pksh_audience — целевая аудитория + $audience = carbon_get_post_meta( 2, 'pksh_audience' ); + // pksh_course_mode — формат обучения (очная/ONLINE/OFFLINE) + $course_mode = carbon_get_post_meta( 2, 'pksh_course_mode' ); + // pksh_skills — список навыков + $skills = carbon_get_post_meta( 2, 'pksh_skills' ); + // banner_img — изображение курса + $course_img = carbon_get_post_meta( 2, 'banner_img' ); + // pksh_programs — программы (для timeRequired + CourseInstance) + $programs = carbon_get_post_meta( 2, 'pksh_programs' ); + + $course = array( + '@type' => 'Course', + '@id' => $page_url . '#course', + 'name' => wp_strip_all_tags( $name ), + 'description' => wp_strip_all_tags( $description ), + 'inLanguage' => str_replace( '_', '-', determine_locale() ?: 'ru' ), + 'provider' => array( + '@id' => $page_url . '#localbusiness', + ), + 'offers' => array_merge( + array( array( '@id' => $page_url . '#offer' ) ), + $has_trial ? array( array( '@id' => $page_url . '#offer-trial' ) ) : array() + ), + 'aggregateRating' => array( + '@id' => $page_url . '#rating', + ), + ); + + // educationalLevel — уровень образования (условно) + if ( ! empty( $level ) && is_string( $level ) ) { + $course['educationalLevel'] = wp_strip_all_tags( trim( $level ) ); + } + + // audience — EducationalAudience (условно) + if ( ! empty( $audience ) && is_string( $audience ) ) { + $course['audience'] = array( + '@type' => 'EducationalAudience', + 'name' => wp_strip_all_tags( trim( $audience ) ), + ); + } + + // teaches — массив навыков (условно, из pksh_skills complex) + if ( ! empty( $skills ) && is_array( $skills ) ) { + $teaches = array(); + foreach ( $skills as $skill ) { + $name = isset( $skill['skill'] ) ? trim( $skill['skill'] ) : ''; + if ( $name ) { + $teaches[] = array( + '@type' => 'Thing', + 'name' => wp_strip_all_tags( $name ), + ); + } + } + if ( ! empty( $teaches ) ) { + $course['teaches'] = $teaches; + } + } + + // timeRequired — длительность курса из первой программы, где заполнено + if ( ! empty( $programs ) && is_array( $programs ) ) { + foreach ( $programs as $prog ) { + if ( ! empty( $prog['program_time_required'] ) ) { + $course['timeRequired'] = wp_strip_all_tags( trim( $prog['program_time_required'] ) ); + break; + } + } + } + + // image — изображение курса (условно, из banner_img) + if ( ! empty( $course_img ) ) { + if ( is_array( $course_img ) && isset( $course_img['url'] ) ) { + $course['image'] = esc_url( $course_img['url'] ); + } else { + $url = wp_get_attachment_url( $course_img ); + if ( $url ) { + $course['image'] = esc_url( $url ); + } + } + } elseif ( has_post_thumbnail( 2 ) ) { + // fallback: post_thumbnail страницы + $url = get_the_post_thumbnail_url( 2, 'full' ); + if ( $url ) { + $course['image'] = esc_url( $url ); + } + } + + // hasCourseInstance — по одной CourseInstance на каждую программу с данными + $instances = array(); + if ( ! empty( $programs ) && is_array( $programs ) ) { + foreach ( $programs as $prog ) { + $prog_workload = isset( $prog['program_workload'] ) ? trim( $prog['program_workload'] ) : ''; + $prog_intensity = isset( $prog['program_intensity'] ) ? trim( $prog['program_intensity'] ) : ''; + $prog_start = isset( $prog['program_start_date'] ) ? trim( $prog['program_start_date'] ) : ''; + $prog_end = isset( $prog['program_end_date'] ) ? trim( $prog['program_end_date'] ) : ''; + + if ( empty( $prog_workload ) && empty( $prog_intensity ) && empty( $prog_start ) && empty( $prog_end ) ) { + continue; // нет данных для CourseInstance + } + + $instance = array( + '@type' => 'CourseInstance', + 'courseMode' => 'Onsite', + 'location' => array( + '@id' => $page_url . '#localbusiness', + ), + ); + + // courseMode — формат обучения (глобальный, единый для всех программ) + // Допустимые Schema.org: Onsite, Online, Blended + if ( ! empty( $course_mode ) && is_string( $course_mode ) ) { + $cm = strtolower( trim( $course_mode ) ); + // Нормализация legacy-значений + $mode_map = array( + 'offline' => 'Onsite', + 'online' => 'Online', + 'очная' => 'Onsite', + 'очно' => 'Onsite', + ); + $cm_normalized = isset( $mode_map[ $cm ] ) ? $mode_map[ $cm ] : ucfirst( $cm ); + $valid_modes = array( 'Onsite', 'Online', 'Blended' ); + if ( in_array( $cm_normalized, $valid_modes, true ) ) { + $instance['courseMode'] = $cm_normalized; + } + } + + // courseSchedule — расписание (Schedule) + if ( $prog_workload || $prog_intensity || $prog_start || $prog_end ) { + $schedule = array( '@type' => 'Schedule' ); + // repeatFrequency — ISO 8601 из program_repeat_frequency (новое поле) + $repeat_freq = isset( $prog['program_repeat_frequency'] ) ? trim( $prog['program_repeat_frequency'] ) : ''; + if ( $repeat_freq ) { + $schedule['repeatFrequency'] = wp_strip_all_tags( $repeat_freq ); + } elseif ( $prog_intensity ) { + // fallback: program_intensity — только если нет ISO-поля + $schedule['repeatFrequency'] = wp_strip_all_tags( $prog_intensity ); + } + if ( $prog_start ) { + $schedule['startDate'] = $prog_start; + } + if ( $prog_end ) { + $schedule['endDate'] = $prog_end; + } + $instance['courseSchedule'] = $schedule; + } + + // courseWorkload — учебная нагрузка + if ( $prog_workload ) { + $instance['courseWorkload'] = wp_strip_all_tags( $prog_workload ); + } + + $instances[] = $instance; + } + } + + // fallback: если нет программ с данными, но есть courseMode — одна общая CourseInstance + if ( empty( $instances ) && ! empty( $course_mode ) && is_string( $course_mode ) ) { + $cm = strtolower( trim( $course_mode ) ); + $mode_map = array( + 'offline' => 'Onsite', + 'online' => 'Online', + 'очная' => 'Onsite', + 'очно' => 'Onsite', + ); + $cm_normalized = isset( $mode_map[ $cm ] ) ? $mode_map[ $cm ] : ucfirst( $cm ); + $valid_modes = array( 'Onsite', 'Online', 'Blended' ); + $instances[] = array( + '@type' => 'CourseInstance', + 'courseMode' => ( in_array( $cm_normalized, $valid_modes, true ) ) ? $cm_normalized : 'Onsite', + 'location' => array( + '@id' => $page_url . '#localbusiness', + ), + ); + } + + if ( ! empty( $instances ) ) { + $course['hasCourseInstance'] = $instances; + } + + return $course; +} + +/** + * AggregateOffer — цены программ + бесплатное пробное. + * Извлекает числовые значения из program_price_subscription / program_price_single. + * Если программ нет — возвращает Offer на бесплатное пробное. + * Если есть программы — возвращает AggregateOffer + отдельный Offer для free trial. + * + * @see https://schema.org/AggregateOffer + * @see https://schema.org/Offer + */ +function dekart_schema_offer(): ?array { + $page_url = home_url( '/podgotovka-k-shkole/' ); + $programs = carbon_get_post_meta( 2, 'pksh_programs' ); + + // priceValidUntil — самая поздняя дата из всех программ + $price_valid = ''; + if ( ! empty( $programs ) && is_array( $programs ) ) { + foreach ( $programs as $prog ) { + if ( ! empty( $prog['program_price_valid'] ) ) { + $d = trim( $prog['program_price_valid'] ); + if ( $d > $price_valid ) { + $price_valid = $d; + } + } + } + } + + $prices = array(); + + if ( ! empty( $programs ) && is_array( $programs ) ) { + foreach ( $programs as $program ) { + // program_price_subscription — цена абонемента + if ( ! empty( $program['program_price_subscription'] ) ) { + $num = dekart_parse_price( $program['program_price_subscription'] ); + if ( $num > 0 ) { + $prices[] = $num; + } + } + // program_price_single — цена разового занятия + if ( ! empty( $program['program_price_single'] ) ) { + $num = dekart_parse_price( $program['program_price_single'] ); + if ( $num > 0 ) { + $prices[] = $num; + } + } + } + } + + if ( empty( $prices ) ) { + // Нет цен в программах — Offer на бесплатное пробное + $offer = array( + '@type' => 'Offer', + '@id' => $page_url . '#offer', + 'price' => '0', + 'priceCurrency' => 'RUB', + 'availability' => 'https://schema.org/LimitedAvailability', + 'description' => 'Бесплатное пробное занятие', + ); + + // priceValidUntil — дата действия (условно) + if ( ! empty( $price_valid ) ) { + $offer['priceValidUntil'] = trim( $price_valid ); + } + + return $offer; + } + + $low = min( $prices ); + $high = max( $prices ); + + $aggregate = array( + '@type' => 'AggregateOffer', + '@id' => $page_url . '#offer', + 'priceCurrency' => 'RUB', + 'lowPrice' => (string) $low, + 'highPrice' => (string) $high, + 'offerCount' => (string) count( $prices ), + 'availability' => 'https://schema.org/InStock', + // category — категория услуги + 'category' => 'Образовательные услуги', + // offeredBy — кто предоставляет + 'offeredBy' => array( + '@id' => $page_url . '#localbusiness', + ), + ); + + // priceValidUntil — дата действия цен (условно) + if ( ! empty( $price_valid ) ) { + $aggregate['priceValidUntil'] = trim( $price_valid ); + } + + // Возвращаем массив: сначала AggregateOffer, потом (опционально) Offer на бесплатное пробное + $offers = array( $aggregate ); + + // banner_subtitle содержит фразу "бесплатное пробное" — создаём отдельный Offer + $subtitle = carbon_get_post_meta( 2, 'banner_subtitle' ); + if ( ! empty( $subtitle ) && false !== mb_stripos( $subtitle, 'бесплатно' ) ) { + $trial = array( + '@type' => 'Offer', + '@id' => $page_url . '#offer-trial', + 'price' => '0', + 'priceCurrency' => 'RUB', + 'availability' => 'https://schema.org/LimitedAvailability', + 'description' => wp_strip_all_tags( $subtitle ), + 'category' => 'Бесплатное пробное занятие', + 'offeredBy' => array( + '@id' => $page_url . '#localbusiness', + ), + ); + if ( ! empty( $price_valid ) ) { + $trial['priceValidUntil'] = trim( $price_valid ); + } + $offers[] = $trial; + } + + return $offers; +} + +/** + * AggregateRating — рейтинг из отзывов Carbon Fields. + * Вычисляется динамически из pksh_reviews_list. + * Если отзывов < 1 — блок не выводится. + */ +function dekart_schema_rating(): ?array { + $page_url = home_url( '/podgotovka-k-shkole/' ); + $reviews = carbon_get_post_meta( 2, 'pksh_reviews_list' ); + + if ( empty( $reviews ) || ! is_array( $reviews ) ) { + return null; + } + + $ratings = array(); + foreach ( $reviews as $review ) { + $rating = isset( $review['review_rating'] ) ? intval( $review['review_rating'] ) : 0; + if ( $rating >= 1 && $rating <= 5 ) { + $ratings[] = $rating; + } + } + + if ( count( $ratings ) < 1 ) { + return null; + } + + $average = round( array_sum( $ratings ) / count( $ratings ), 1 ); + + return array( + '@type' => 'AggregateRating', + '@id' => $page_url . '#rating', + 'ratingValue' => (string) $average, + 'bestRating' => '5', + 'worstRating' => '1', + 'ratingCount' => (string) count( $ratings ), + 'itemReviewed' => array( + '@id' => $page_url . '#course', + ), + ); +} + +/** + * FAQPage — вопросы и ответы из pksh_faq_items. + * Если вопросов нет — блок не выводится. + */ +function dekart_schema_faq(): ?array { + $page_url = home_url( '/podgotovka-k-shkole/' ); + $faq_items = carbon_get_post_meta( 2, 'pksh_faq_items' ); + + if ( empty( $faq_items ) || ! is_array( $faq_items ) ) { + return null; + } + + $main_entity = array(); + foreach ( $faq_items as $item ) { + $question = isset( $item['faq_question'] ) ? trim( $item['faq_question'] ) : ''; + $answer = isset( $item['faq_answer'] ) ? trim( $item['faq_answer'] ) : ''; + + if ( empty( $question ) || empty( $answer ) ) { + continue; + } + + $main_entity[] = array( + '@type' => 'Question', + 'name' => wp_strip_all_tags( $question ), + 'acceptedAnswer' => array( + '@type' => 'Answer', + 'text' => wp_strip_all_tags( $answer ), + ), + ); + } + + if ( empty( $main_entity ) ) { + return null; + } + + return array( + '@type' => 'FAQPage', + '@id' => $page_url . '#faq', + 'mainEntity' => $main_entity, + ); +} + +/** + * Review[] — поштучные отзывы из pksh_reviews_list. + * Каждый отзыв — отдельная сущность Review с автор-персоной и оценкой. + * itemReviewed → Course. Фильтр некорректных оценок (>5 или <1). + * + * @return array[] Массив Review-сущностей для @graph. + * @see https://schema.org/Review + */ +function dekart_schema_reviews(): array { + $page_url = home_url( '/podgotovka-k-shkole/' ); + // pksh_reviews_list — complex-поле отзывов + $reviews = carbon_get_post_meta( 2, 'pksh_reviews_list' ); + + if ( empty( $reviews ) || ! is_array( $reviews ) ) { + return array(); + } + + $result = array(); + $review_seq = 0; + foreach ( $reviews as $i => $review ) { + // review_author — имя автора (Person.name) + $author_name = isset( $review['review_author'] ) ? trim( $review['review_author'] ) : ''; + // review_text — текст отзыва + $body = isset( $review['review_text'] ) ? trim( $review['review_text'] ) : ''; + // review_rating — оценка 1-5 + $rating_val = isset( $review['review_rating'] ) ? intval( $review['review_rating'] ) : 0; + + // Пропускаем без автора или текста + if ( empty( $author_name ) || empty( $body ) ) { + continue; + } + + // Фильтруем оценки вне диапазона 1-5 + if ( $rating_val < 1 || $rating_val > 5 ) { + continue; + } + + $review_seq++; + + $entity = array( + '@type' => 'Review', + '@id' => $page_url . '#review-' . $review_seq, + 'author' => array( + '@type' => 'Person', + 'name' => wp_strip_all_tags( $author_name ), + ), + 'reviewBody' => wp_strip_all_tags( $body ), + 'itemReviewed' => array( + '@id' => $page_url . '#course', + ), + 'reviewRating' => array( + '@type' => 'Rating', + 'ratingValue' => (string) $rating_val, + 'bestRating' => '5', + 'worstRating' => '1', + ), + ); + + // datePublished — дата отзыва (условно, из review_date) + $review_date = isset( $review['review_date'] ) ? trim( $review['review_date'] ) : ''; + if ( $review_date ) { + $entity['datePublished'] = sanitize_text_field( $review_date ); + } + + $result[] = $entity; + } + + return $result; +} + +/** + * Person[] — преподаватели из pksh_teachers complex. + * Каждый преподаватель — отдельная сущность Person. + * Связаны с LocalBusiness через employee @id. + * + * @return array[] Массив Person-сущностей для @graph. + * @see https://schema.org/Person + */ +function dekart_schema_teachers(): array { + $page_url = home_url( '/podgotovka-k-shkole/' ); + // pksh_teachers — complex-поле преподавателей + $teachers = carbon_get_post_meta( 2, 'pksh_teachers' ); + + if ( empty( $teachers ) || ! is_array( $teachers ) ) { + return array(); + } + + $result = array(); + foreach ( $teachers as $i => $teacher ) { + // teacher_name — ФИО преподавателя + $name = isset( $teacher['teacher_name'] ) ? trim( $teacher['teacher_name'] ) : ''; + // teacher_subject — предмет / должность + $subject = isset( $teacher['teacher_subject'] ) ? trim( $teacher['teacher_subject'] ) : ''; + // teacher_about — описание / биография + $about = isset( $teacher['teacher_about'] ) ? trim( $teacher['teacher_about'] ) : ''; + // teacher_photo — фото (attachment ID или массив) + $photo = $teacher['teacher_photo'] ?? 0; + + if ( empty( $name ) ) { + continue; + } + + $person = array( + '@type' => 'Person', + '@id' => $page_url . '#teacher-' . $i, + 'name' => wp_strip_all_tags( $name ), + ); + + // jobTitle — должность (условно) + if ( ! empty( $subject ) ) { + $person['jobTitle'] = wp_strip_all_tags( $subject ); + } + + // description — о преподавателе (условно) + if ( ! empty( $about ) ) { + $person['description'] = wp_strip_all_tags( $about ); + } + + // image — фото преподавателя (условно) + if ( ! empty( $photo ) ) { + if ( is_array( $photo ) && isset( $photo['url'] ) ) { + $person['image'] = esc_url( $photo['url'] ); + } else { + $url = wp_get_attachment_url( $photo ); + if ( $url ) { + $person['image'] = esc_url( $url ); + } + } + } + + $result[] = $person; + } + + return $result; +} + +/* ===================================================================== + Вспомогательные функции + ===================================================================== */ + +/** + * Парсит цену из форматированной строки (например "7 500 ₽" → 7500). + * Поддерживает "1 234,56" (comma-decimal) и "1,234.56" (dot-decimal). + * + * @param string $raw Строка с ценой. + * @return float Числовое значение. + */ +function dekart_parse_price( string $raw ): float { + // Удаляем всё кроме цифр, точки, запятой + $clean = preg_replace( '/[^0-9.,]/', '', $raw ); + + // Определяем формат: если последний разделитель — запятая → comma-decimal + $last_comma = strrpos( $clean, ',' ); + $last_dot = strrpos( $clean, '.' ); + + if ( false !== $last_comma && ( false === $last_dot || $last_comma > $last_dot ) ) { + // Европейский формат: 1.234,56 → убираем точки, меняем запятую на точку + $clean = str_replace( '.', '', $clean ); + $clean = str_replace( ',', '.', $clean ); + } else { + // Стандартный/русский: убираем всё кроме последней точки + $clean = str_replace( ',', '', $clean ); + $clean = preg_replace( '/\.(?=.*\.)/', '', $clean ); + } + + return floatval( $clean ); +} diff --git a/wp-content/themes/dekart/page-podgotovka-k-shkole.php b/wp-content/themes/dekart/page-podgotovka-k-shkole.php new file mode 100644 index 0000000..0d569d8 --- /dev/null +++ b/wp-content/themes/dekart/page-podgotovka-k-shkole.php @@ -0,0 +1,712 @@ + + +
+ + + + + + + +
+
+ +
+
+ + + + +
+
+
+
+ Бесплатно +

Скачайте чек-лист готовности к школе

+

10 признаков, что ваш ребёнок готов к 1-му классу. Проверьте за 5 минут — и узнайте, на какие навыки обратить внимание.

+ +

Отправляя заявку, вы соглашаетесь на обработку персональных данных

+
+
+ +
+
+
+
+ + + + +
+
+
+
+
🛡️
+
+
+

Ваш ребёнок начнёт читать через 3 недели

+

Или мы вернём деньги и продолжим обучение бесплатно, пока не дойдём до результата. Мы — частная школа с гослицензией, а не кружок. Отвечаем за результат.

+ +
+
+
+
+ + + + +
+ + + + +
+
+ Как проходит занятие +

30 минут игры = 1 шаг к школе

+

Никаких скучных прописей. Каждое занятие построено так, что ребёнок сам хочет вернуться.

+
+
+ 1 +
+ Вход в тему + Короткая история или загадка — включаем интерес +
+
+
+ 2 +
+ Игровое задание + Чтение, счёт, логика — через механику игры +
+
+
+ 3 +
+ Рефлексия + Ребёнок сам рассказывает, чему научился +
+
+
+
+ +
+ Почему родители выбирают нас +

Три главных вопроса — честные ответы

+
+
+
+ +
+
+ Не перегрузят ли ребёнка? +

Занятия по 30–40 минут. Каждые 7 минут — смена активности. Ребёнок не устаёт.

+
+
+
+
+ +
+
+ Успеем ли до сентября? +

Да. Наша программа рассчитана на 4–6 месяцев. Первые результаты — через 3 недели.

+
+
+
+
+ +
+
+ Дорого? +

От 600 ₽ за занятие. Первое — бесплатно. А если не понравится — вернём деньги.

+
+
+
+
+
+ + + + +
+
+ Результаты наших учеников +

К чему мы приводим детей

+
+
+ 95% + поступают в школы и лицеи Щёлкова без стресса +
+
+ 3 нед. + — первый осмысленный слог у нечитавших детей +
+
+ 87% + родителей отмечают рост самостоятельности +
+
+ 2,5× + быстрее адаптируются в первом классе +
+
+
+
+ + + + +
+
+ Программы +

Выберите формат подготовки

+

Все программы ведут действующие педагоги начальных классов. + Группы до 8 человек — каждому ребёнку уделяем внимание.

+ +
+ +
+
+ +

+
+ +
+ + +
+ Интенсивность: + +
+ + + +
+ 📅 Расписание: +
    + +
  • + +
+
+ + + +
+ ⏱ Структура занятия (): +
    + + +
  • + + +
  • + +
+
+ + + +
+ Программа включает: +
    + +
  • + +
+
+ + + +
+ +
+ + за 4 недели +
+ + +
+ за одно занятие (вне абонемента) +
+ +
+ + + + + + +
+
+ +
+
+ 📖 +

Базовая программа

+
+
+

Заполните программы в админке → Настройки Подготовки к школе → Программы

+
+
+ +
+ +
+

Первое пробное занятие — бесплатно. При покупке абонемента на месяц — скидка 10%. + Записаться на бесплатное пробное

+
+
+ + 🔥 4 из 8 мест в группе 5–6 лет уже заняты. Успейте записаться! +
+
+
+ + + + + + + + + +
+
+

Наши преподаватели

+
+
+ +
+
+
+ + <?php echo esc_attr($t_name); ?> + + <?php echo esc_attr($t_name); ?> + +
+
+

+ +

+ + +

+ +
+
+
+ +
+
+
+
+ + + + +
+
+
+

🛡️ Гарантия результата

+

+ Если через 3 месяца ваш ребёнок не начнёт читать — + мы вернём деньги и продолжим обучение бесплатно, + пока не дойдём до результата. +

+ Так работают только те, кто уверен в своём методе +
+
+
+ + + + +
+
+

Часто задаваемые вопросы

+ ' + . '
' + . '' . esc_html($q) . '' + . '' + . '' + . '' + . '' + . '' + . '
' + . '
' + . '
' . wp_kses_post($a) . '
' + . '
'; + if ($count % 2 === 0) { + $col1 .= $accordion; + } else { + $col2 .= $accordion; + } + $count++; + endforeach; + if (!empty($col1) || !empty($col2)) : + ?> +
+
+
+
+ +
+ + + + + +
+

Что говорят родители

+ + 0) : + $items = array_values($review_items); + $render_card = function($item) { + $author = $item['review_author'] ?? ''; + $text = $item['review_text'] ?? ''; + $raw_rating = $item['review_rating'] ?? ''; + $avatar_id = !empty($item['review_avatar']) ? (int)$item['review_avatar'] : 0; + $stars = max(1, min(5, (int)$raw_rating)); + $name = $author ?: 'Анонимно'; + if (empty($text)) return ''; + ob_start(); + ?> +
+
+
+ + 'lw-avatar__img', 'loading' => 'lazy', 'alt' => esc_attr($name)]); ?> + + <?php echo esc_attr($name); ?> + +
+
+
+
+
Проверенный отзыв
+
+
+ + + + + +
+
+
+ +
+
+ +
+ 4) : ?> +
+ +
+ +
+ + +
+ + + + +
+
+
+

Первое занятие — бесплатно

+

Ребёнок познакомится с педагогом, попробует задания. Вы увидите методику своими глазами. Никакой оплаты и договоров.

+ + + + +

🔥 Осталось 2 места в группе 5–6 лет. Успейте!

+
+
+
+ + + + +
+
+

Наш адрес

+
+
+ +
Телефон:
+ + + + +
Почта:
+ + + + +
Адрес:
+
+ + + +
Наши соцсети:
+ + +
+
+
+
+
+
+
+ + + +
+ +' . "\n"; + echo '' . "\n"; + echo '' . "\n"; $og_title = wp_get_document_title(); $og_description = get_post_meta( $post_id, '_yoast_wpseo_metadesc', true ) ?: get_bloginfo( 'description' ); @@ -68,8 +73,17 @@ add_action( 'wp_head', function () { echo '' . "\n"; echo '' . "\n"; echo '' . "\n"; - echo '' . "\n"; + $og_site_name = get_option( 'branch_og_site_name' ) ?: sprintf( 'Частная школа %s %s', get_option( 'branch_name', 'Декарт' ), get_option( 'branch_city_prep', 'в Щёлково' ) ); + echo '' . "\n"; echo '' . "\n"; + + // Twitter Card (из того же featured image) + echo '' . "\n"; + echo '' . "\n"; + echo '' . "\n"; + if ( $thumb_id && $img_data ) { + echo '' . "\n"; + } }, 1 ); // Критический CSS для LCP вынесен в assets/css/reviews-page.css. @@ -96,15 +110,15 @@ $branch_messengers = get_option( 'branch_messengers', array() ); // ─── КОНТЕНТ СТРАНИЦЫ (Carbon Fields post_meta) ─── -// Метрики доверия -$metric_1_num = carbon_get_post_meta( $post_id, 'reviews_hero_metric_1_number' ) ?: '500+'; -$metric_1_lbl = carbon_get_post_meta( $post_id, 'reviews_hero_metric_1_label' ) ?: 'счастливых семей'; -$metric_2_num = carbon_get_post_meta( $post_id, 'reviews_hero_metric_2_number' ) ?: '12+'; -$metric_2_lbl = carbon_get_post_meta( $post_id, 'reviews_hero_metric_2_label' ) ?: 'лет в образовании'; -$metric_3_num = carbon_get_post_meta( $post_id, 'reviews_hero_metric_3_number' ) ?: '4.9'; -$metric_3_lbl = carbon_get_post_meta( $post_id, 'reviews_hero_metric_3_label' ) ?: 'рейтинг на Яндексе'; -$metric_4_num = carbon_get_post_meta( $post_id, 'reviews_hero_metric_4_number' ) ?: '14'; -$metric_4_lbl = carbon_get_post_meta( $post_id, 'reviews_hero_metric_4_label' ) ?: 'отзывов о школе'; +// Метрики доверия (только из Carbon Fields — никаких хардкод-значений) +$metric_1_num = carbon_get_post_meta( $post_id, 'reviews_hero_metric_1_number' ); +$metric_1_lbl = carbon_get_post_meta( $post_id, 'reviews_hero_metric_1_label' ); +$metric_2_num = carbon_get_post_meta( $post_id, 'reviews_hero_metric_2_number' ); +$metric_2_lbl = carbon_get_post_meta( $post_id, 'reviews_hero_metric_2_label' ); +$metric_3_num = carbon_get_post_meta( $post_id, 'reviews_hero_metric_3_number' ); +$metric_3_lbl = carbon_get_post_meta( $post_id, 'reviews_hero_metric_3_label' ); +$metric_4_num = carbon_get_post_meta( $post_id, 'reviews_hero_metric_4_number' ); +$metric_4_lbl = carbon_get_post_meta( $post_id, 'reviews_hero_metric_4_label' ); // Результаты $results_title = carbon_get_post_meta( $post_id, 'reviews_results_title' ) ?: 'Декарт в цифрах'; @@ -140,15 +154,47 @@ if ( ! $jsonld_img_url ) { $jsonld_img_url = $logo_id ? wp_get_attachment_url( $logo_id ) : ''; } -// ─── СОЦСЕТИ ДЛЯ JSON-LD ─── +// ─── ИЗОБРАЖЕНИЕ ШКОЛЫ ДЛЯ JSON-LD (image) ─── +// Используем featured image главной страницы (page_on_front). +// Schema.org рекомендует минимум 696px ширины. +$school_image_url = ''; +$front_page_id = (int) get_option( 'page_on_front' ); +if ( $front_page_id && has_post_thumbnail( $front_page_id ) ) { + $img_data = wp_get_attachment_image_src( get_post_thumbnail_id( $front_page_id ), 'full' ); + if ( $img_data && $img_data[1] >= 696 ) { + $school_image_url = $img_data[0]; + } +} + +// ─── СОЦСЕТИ ДЛЯ JSON-LD (sameAs) ─── $jsonld_social = array(); + +// 1. branch_social (Settings API) — формат: [['name' => 'VK', 'url' => 'https://...']] +// или CF social_media fallback: [['social_media_name' => '', 'social_media_link' => 'https://...']] if ( is_array( $branch_social ) ) { foreach ( $branch_social as $s ) { + // Settings API: ['name', 'url'] if ( ! empty( $s['url'] ) ) { $jsonld_social[] = $s['url']; } + // CF theme option social_media: ['social_media_name', 'social_media_link'] + if ( ! empty( $s['social_media_link'] ) ) { + $jsonld_social[] = $s['social_media_link']; + } } } + +// 2. branch_messengers — мессенджеры (WhatsApp, Telegram) тоже в sameAs +if ( is_array( $branch_messengers ) ) { + foreach ( $branch_messengers as $m ) { + if ( ! empty( $m['url'] ) ) { + $jsonld_social[] = $m['url']; + } + } +} + +// Удаляем дубликаты (если VK есть и в соцсетях, и в мессенджерах) +$jsonld_social = array_values( array_unique( $jsonld_social ) ); ?>
@@ -181,33 +227,39 @@ if ( is_array( $branch_social ) ) {

Отзывы о частной школе «Декарт»

Родители доверяют нам самое главное — вот что они говорят о нас

+ $metric_1_num, 'lbl' => $metric_1_lbl ); + } + if ( $metric_2_num && $metric_2_lbl ) { + $hero_metrics[] = array( 'num' => $metric_2_num, 'lbl' => $metric_2_lbl ); + } + if ( $metric_3_num && $metric_3_lbl ) { + $hero_metrics[] = array( 'num' => $metric_3_num, 'lbl' => $metric_3_lbl ); + } + if ( $metric_4_num && $metric_4_lbl ) { + $hero_metrics[] = array( 'num' => $metric_4_num, 'lbl' => $metric_4_lbl ); + } + if ( ! empty( $hero_metrics ) ) : ?>
+
- - -
-
- - -
-
- - -
-
- - + +
+
+ +
★★★★★ - 4.9 из 5 на основе 247 отзывов на внешних площадках + 4.9 из 5 на основе отзывов на внешних площадках
- - @@ -267,7 +319,12 @@ $intro_price_txt = carbon_get_post_meta( $post_id, 'reviews_intro_price_text' );
-

Режим работы школы: .

+ +

Режим работы школы: .

+

Стоимость обучения: . Узнать подробнее о ценах →

@@ -320,7 +377,7 @@ $intro_price_txt = carbon_get_post_meta( $post_id, 'reviews_intro_price_text' );
-

Отзывы родителей о частной школе в Щёлково

+

Отзывы родителей о частной школе

Все отзывы проходят проверку — мы связываемся с родителями и убеждаемся в достоверности каждого отзыва. Здесь собраны настоящие истории семей, чьи дети учатся в частной школе «Декарт» в Щёлково. Читайте, знакомьтесь и присоединяйтесь!

350; $batch = (int) ceil( $card_idx / 12 ); ?> -
+
" class="review-card__teacher-link">
-
✓ Проверенный отзыв
+
✓ Проверенный отзыв
@@ -395,7 +452,7 @@ $intro_price_txt = carbon_get_post_meta( $post_id, 'reviews_intro_price_text' );
- + @@ -562,7 +619,7 @@ $intro_price_txt = carbon_get_post_meta( $post_id, 'reviews_intro_price_text' ); - + + + Набор в 1 класс на 2026/27 учебный год открыт — осталось мест
📅 @@ -1061,40 +1118,130 @@ $org_address = array( 'streetAddress' => $branch_addr, 'addressLocality' => $branch_city, 'addressRegion' => $branch_region, - 'postalCode' => get_option( 'branch_postal_code', '' ) ?: '', + 'postalCode' => get_option( 'branch_postal_code', '' ) ?: carbon_get_theme_option( 'schema_postal_code' ) ?: '', 'addressCountry' => 'RU', ); +// ─── ДАННЫЕ СХЕМЫ (CF theme options «SEO и микроразметка» + Settings API fallback) ─── +$schema_description = carbon_get_theme_option( 'schema_description' ) ?: get_option( 'branch_schema_description', '' ); +$schema_founded = carbon_get_theme_option( 'schema_founded' ) ?: get_option( 'branch_founded', '' ); +$schema_map_url = carbon_get_theme_option( 'schema_map_url' ); +$schema_area_raw = carbon_get_theme_option( 'schema_area_served' ) ?: get_option( 'branch_area_served', '' ); +$hours_cf = carbon_get_theme_option( 'schema_hours' ); + +// ─── openingHoursSpecification (CF complex → Settings API textarea) ─── +$hours_spec = array(); +if ( ! empty( $hours_cf ) && is_array( $hours_cf ) ) { + foreach ( $hours_cf as $entry ) { + $day = isset( $entry['day_of_week'] ) ? trim( $entry['day_of_week'] ) : ''; + if ( empty( $day ) ) { + continue; + } + $is_off = ! empty( $entry['day_off'] ); + if ( $is_off ) { + $hours_spec[] = array( + '@type' => 'OpeningHoursSpecification', + 'dayOfWeek' => $day, + 'opens' => '00:00', + 'closes' => '00:00', + ); + } else { + $from = isset( $entry['opens'] ) ? trim( $entry['opens'] ) : ''; + $to = isset( $entry['closes'] ) ? trim( $entry['closes'] ) : ''; + if ( $from && $to ) { + $hours_spec[] = array( + '@type' => 'OpeningHoursSpecification', + 'dayOfWeek' => $day, + 'opens' => $from, + 'closes' => $to, + ); + } + } + } +} else { + // Fallback: читаем из текстового поля отзывов (только dayOfWeek|opens|closes) + $hours_raw = carbon_get_post_meta( $post_id, 'reviews_intro_hours' ); + if ( ! empty( $hours_raw ) && is_string( $hours_raw ) ) { + $lines = explode( "\n", $hours_raw ); + foreach ( $lines as $line ) { + $line = trim( $line ); + if ( empty( $line ) ) { + continue; + } + $parts = explode( '|', $line ); + $day = isset( $parts[0] ) ? trim( $parts[0] ) : ''; + if ( empty( $day ) ) { + continue; + } + if ( isset( $parts[2] ) && 'closed' === strtolower( trim( $parts[2] ) ) ) { + $hours_spec[] = array( + '@type' => 'OpeningHoursSpecification', + 'dayOfWeek' => $day, + 'opens' => '00:00', + 'closes' => '00:00', + ); + continue; + } + $from = isset( $parts[1] ) ? trim( $parts[1] ) : ''; + $to = isset( $parts[2] ) ? trim( $parts[2] ) : ''; + if ( $day && $from && $to ) { + $hours_spec[] = array( + '@type' => 'OpeningHoursSpecification', + 'dayOfWeek' => $day, + 'opens' => $from, + 'closes' => $to, + ); + } + } + } +} + +// ─── areaServed — города присутствия ─── +$area_served = array(); +$area_served[] = array( '@type' => 'City', 'name' => $branch_city ); +if ( ! empty( $schema_area_raw ) && is_string( $schema_area_raw ) ) { + $cities = array_map( 'trim', explode( ',', $schema_area_raw ) ); + foreach ( $cities as $c ) { + if ( $c && $c !== $branch_city ) { + $area_served[] = array( '@type' => 'City', 'name' => $c ); + } + } +} else { + // Fallback: только город филиала +} + +// ─── description — описание организации ─── +if ( ! empty( $schema_description ) && is_string( $schema_description ) ) { + $org_description = wp_strip_all_tags( trim( $schema_description ) ); +} else { + $org_description = 'Частная школа полного дня в ' . $branch_city . '. Обучение с 1 по 11 класс, подготовка к ЕГЭ и ОГЭ, индивидуальный подход.'; +} + $organization = array( - '@type' => 'School', + '@type' => array( 'School', 'LocalBusiness' ), '@id' => home_url( '/' ) . '#organization', 'name' => $branch_name, - 'description' => 'Частная школа полного дня в ' . $branch_city . '. Обучение с 1 по 11 класс, подготовка к ЕГЭ и ОГЭ, индивидуальный подход.', + 'description' => $org_description, 'url' => home_url( '/' ), 'address' => $org_address, - 'priceRange' => get_option( 'branch_price_range' ) ?: 'от 40 000 ₽/мес', - 'openingHoursSpecification' => array( - array( - '@type' => 'OpeningHoursSpecification', - 'dayOfWeek' => array( 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday' ), - 'opens' => '08:00', - 'closes' => '19:00', - ), - array( - '@type' => 'OpeningHoursSpecification', - 'dayOfWeek' => 'Saturday', - 'opens' => '09:00', - 'closes' => '14:00', - ), - ), - 'areaServed' => array( - array( '@type' => 'City', 'name' => $branch_city ), - array( '@type' => 'City', 'name' => 'Фрязино' ), - array( '@type' => 'City', 'name' => 'Монино' ), - ), - // foundingDate задаётся в branch-опциях (SEO-таб) или в CF schema_founding_date + 'areaServed' => $area_served, ); +// openingHoursSpecification — из CF или Settings API (условно) +if ( ! empty( $hours_spec ) ) { + $organization['openingHoursSpecification'] = $hours_spec; +} + +// hasMap — ссылка на карту (условно) +if ( ! empty( $schema_map_url ) && is_string( $schema_map_url ) ) { + $organization['hasMap'] = esc_url( trim( $schema_map_url ) ); +} + +// foundingDate — год основания (условно) +if ( ! empty( $schema_founded ) && is_string( $schema_founded ) ) { + $organization['foundingDate'] = trim( $schema_founded ); +} + // GeoCoordinates на уровне Organization (не внутри PostalAddress) if ( ! empty( $branch_coords ) && false !== strpos( $branch_coords, ',' ) ) { $coords_parts = explode( ',', $branch_coords ); @@ -1118,6 +1265,9 @@ if ( $branch_phone ) { if ( $jsonld_img_url ) { $organization['logo'] = $jsonld_img_url; } +if ( $school_image_url ) { + $organization['image'] = $school_image_url; +} if ( ! empty( $jsonld_social ) ) { $organization['sameAs'] = $jsonld_social; } @@ -1135,6 +1285,13 @@ if ( $branch_phone || $branch_email ) { $organization['contactPoint'] = array( $cp ); } +// AggregateRating — вкладываем напрямую в Organization (School), а не отдельным узлом @graph. +// Google показывает звёздочки в выдаче только когда aggregateRating — свойство Organization/LocalBusiness. +if ( $agg_rating ) { + unset( $agg_rating['itemReviewed'] ); + $organization['aggregateRating'] = $agg_rating; +} + // ─── WebSite ─── $ld_website = array( '@type' => 'WebSite', @@ -1143,6 +1300,14 @@ $ld_website = array( 'name' => $branch_name, 'inLanguage' => 'ru-RU', 'publisher' => array( '@id' => home_url( '/' ) . '#organization' ), + 'potentialAction' => array( + '@type' => 'SearchAction', + 'target' => array( + '@type' => 'EntryPoint', + 'urlTemplate' => home_url( '/' ) . '?s={search_term_string}', + ), + 'query-input' => 'required name=search_term_string', + ), ); // ─── WebPage ─── @@ -1152,7 +1317,6 @@ $ld_webpage = array( 'url' => get_permalink( $post_id ), 'inLanguage' => 'ru-RU', 'name' => wp_get_document_title() ?: 'Отзывы — ' . $branch_name, - 'description' => 'Реальные отзывы родителей и учеников о частной школе Декарт в Щёлково. Истории поступлений, мнения о программах и педагогах.', 'isPartOf' => array( '@id' => home_url( '/' ) . '#website' ), 'about' => array( '@id' => home_url( '/' ) . '#organization' ), 'speakable' => array( @@ -1161,6 +1325,32 @@ $ld_webpage = array( ), ); +// description — Yoast SEO → динамическая сборка с городом +$webpage_description = get_post_meta( $post_id, '_yoast_wpseo_metadesc', true ); +if ( ! $webpage_description ) { + $webpage_description = sprintf( + 'Реальные отзывы родителей и учеников о частной школе Декарт в %s. Истории поступлений, мнения о программах и педагогах.', + $branch_city + ); +} +$ld_webpage['description'] = wp_strip_all_tags( $webpage_description ); + +// image — featured image страницы (если есть) +$page_thumb_id = get_post_thumbnail_id( $post_id ); +if ( $page_thumb_id ) { + $page_img = wp_get_attachment_image_url( $page_thumb_id, 'full' ); + if ( $page_img ) { + $ld_webpage['image'] = esc_url( $page_img ); + } +} + +// datePublished / dateModified — даты публикации страницы (сигнал свежести) +$post_obj = get_post( $post_id ); +if ( $post_obj ) { + $ld_webpage['datePublished'] = get_the_date( 'c', $post_obj ); + $ld_webpage['dateModified'] = get_the_modified_date( 'c', $post_obj ); +} + // ─── Breadcrumb ─── $ld_breadcrumb = array( '@type' => 'BreadcrumbList', @@ -1188,11 +1378,6 @@ $ld_graph = array_merge( $ld_faq ); -// Если есть AggregateRating — добавляем к webpage -if ( $agg_rating ) { - $ld_graph[] = $agg_rating; -} - if ( ! empty( $ld_graph ) ) { $jsonld_data = array( '@context' => 'https://schema.org', diff --git a/wp-content/themes/dekart/podgotovka-k-shkole.css b/wp-content/themes/dekart/podgotovka-k-shkole.css new file mode 100644 index 0000000..cf34238 --- /dev/null +++ b/wp-content/themes/dekart/podgotovka-k-shkole.css @@ -0,0 +1,2549 @@ +/* ============================================================ + podgotovka-k-shkole.css — v2.0 (Redesign 2026) + Page-specific styles for "Подготовка к школе" + Loaded only via page-podgotovka-k-shkole.php template + ============================================================ */ + +/* ============================================================ + 1. DESIGN TOKENS (page-pksh scoped) + ============================================================ */ +.page-pksh { + --bg-deep: #0F172A; + --bg-soft-2026: #F8FAFC; + --navy: #0F172A; + --slate-600: #475569; + --slate-400: #94A3B8; + --radius-2026: 24px; + +} + +/* Unified purple design system (was orange in v1). + --accent defined in main.css :root (#7C3AED). */ + +/* ============================================================ + 2. BANNER — address & scarcity + ============================================================ */ +.banner__address { + font-family: 'Roboto', sans-serif; + font-size: 16px; + color: #fff; + text-align: center; + margin-bottom: 8px; + letter-spacing: 0.02em; +} + +.banner__scarcity { + font-family: 'Roboto', sans-serif; + font-size: 14px; + font-weight: 700; + color: #fff; + text-align: center; + margin: 0 0 10px; + padding: 6px 18px; +background: rgba(124, 58, 237, 0.2); + border-radius: 100px; + backdrop-filter: blur(4px); + display: inline-block; + max-width: fit-content; +} + +.banner__scarcity strong { + color: #C084FC; +} + +.btn-banner--main { + font-size: 16px; + padding: 14px 32px; +} + +@media (max-width: 860px) { + .banner__address { + font-size: 14px; + } + .banner__scarcity { + font-size: 12px; + padding: 4px 14px; + } + .btn-banner--main { + font-size: 14px; + padding: 12px 24px; + width: 100%; + max-width: 320px; + } +} + +/* ============================================================ + 3. BENTO LABELS & HEADINGS + ============================================================ */ +.bento-label { + display: inline-block; + font-size: 0.8125rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.08em; + color: var(--accent, #7C3AED); + margin-bottom: 8px; +} + +.bento-label--light { + color: rgba(255,255,255,0.8); +} + +.bento-h2 { + font-size: 1.625rem; + font-weight: 700; + line-height: 1.25; + color: var(--navy); + margin: 0 0 12px; +} + +.bento-h2--light { + color: #fff; +} + +.bento-p { + font-size: 1rem; + line-height: 1.6; + color: var(--slate-600); + margin: 0 0 20px; +} + +@media (min-width: 640px) { + .bento-h2 { + font-size: 1.875rem; + } +} + +/* ============================================================ + 4. STEPS-3 — How classes work + ============================================================ */ +.steps-3 { + display: flex; + flex-direction: column; + gap: 16px; + margin-top: 16px; +} + +.step { + display: flex; + align-items: flex-start; + gap: 14px; +} + +.step__num { + flex-shrink: 0; + width: 40px; + height: 40px; + border-radius: 50%; + background: linear-gradient(135deg, #7C3AED, #8B5CF6); + color: #fff; + display: flex; + align-items: center; + justify-content: center; + font-weight: 800; + font-size: 1rem; + box-shadow: 0 3px 10px rgba(124, 58, 237, 0.25); +} + +.step strong { + display: block; + font-size: 0.9375rem; + color: var(--navy); + margin-bottom: 2px; +} + +.step span:not(.step__num) { + display: block; + font-size: 0.875rem; + color: var(--slate-600); + line-height: 1.4; +} + +/* ============================================================ + 5. OBJECTIONS — Why us cards + ============================================================ */ +/* WHITE cards on warm #F8F4F0 section = bright, contrast resolved. + Warm border + generous shadow replaces lost figure/ground. */ +.bento-card--objections { + background: #FFFFFF; + border: 1.5px solid #EDE8DF; + box-shadow: 0 6px 24px rgba(0, 0, 0, 0.07); +} +.bento-card--objections:hover { + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); +} + +.objection-list { + display: flex; + flex-direction: column; + gap: 16px; +} + +.objection-item { + display: flex; + gap: 12px; + align-items: flex-start; +} + +.objection-item__icon { + flex-shrink: 0; + width: 32px; + height: 32px; + color: var(--accent, #7C3AED); + margin-top: 2px; + filter: drop-shadow(0 1px 3px rgba(124, 58, 237, 0.2)); +} + +.objection-item strong { + display: block; + font-size: 0.9375rem; + color: var(--navy); + margin-bottom: 2px; +} + +.objection-item p { + font-size: 0.875rem; + color: var(--slate-600); + line-height: 1.45; + margin: 0; +} + +/* ============================================================ + 6. RESULTS GRID — Highlight section + ============================================================ */ +.bento-card--highlight-results { + background: var(--bg-deep); + border-radius: var(--radius-2026); + padding: 32px 24px; +} + +@media (min-width: 640px) { + .bento-card--highlight-results { + padding: 40px 32px; + } +} + +.results-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 20px; + margin-top: 8px; +} + +@media (min-width: 640px) { + .results-grid { + grid-template-columns: repeat(4, 1fr); + gap: 24px; + } +} + +.result-item { + text-align: center; +} + +.result-item__value { + display: block; + font-size: 2.25rem; + font-weight: 800; + color: var(--accent, #7C3AED); + line-height: 1; + margin-bottom: 6px; +} + +@media (min-width: 640px) { + .result-item__value { + font-size: 2.75rem; + } +} + +.result-item__desc { + display: block; + font-size: 0.8125rem; + color: var(--slate-400); + line-height: 1.35; +} + +/* ============================================================ + 7. GUARANTEE Bento Card + ============================================================ */ +/* .bento-card--guarantee moved to .guarantee-block--centered */ + +/* ============================================================ + 8. (removed — FAQ moved to section 44) + ============================================================ */ + +/* ============================================================ + 9. PROGRAMS GRID + ============================================================ */ +.programs-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); + gap: 20px; + margin: 28px 0 20px; +} + +.program-card { + display: flex; + flex-direction: column; + border-radius: 20px; + overflow: hidden; + background: #fff; + box-shadow: 0 4px 20px rgba(0,0,0,0.06); + transition: transform 0.2s ease, box-shadow 0.2s ease; +} + +.program-card:hover { + transform: translateY(-4px); + box-shadow: 0 12px 32px rgba(0,0,0,0.1); +} + +.program-card__header { + padding: 18px 20px; + color: #fff; + display: flex; + align-items: center; + gap: 10px; +} + +.program-card--orange .program-card__header { background: linear-gradient(135deg, #C084FC, #A855F7); } +.program-card--green .program-card__header { background: linear-gradient(135deg, #22C55E, #16A34A); } +.program-card--blue .program-card__header { background: linear-gradient(135deg, #3B82F6, #2563EB); } +.program-card--purple .program-card__header { background: linear-gradient(135deg, #A855F7, #7C3AED); } + +.program-card__icon { + font-size: 1.5rem; + flex-shrink: 0; +} + +.program-card__title { + margin: 0; + font-size: 1.05rem; + font-weight: 700; + color: #fff; + line-height: 1.2; +} + +.program-card__body { + padding: 20px; + flex-grow: 1; + display: flex; + flex-direction: column; +} + +.program-card__list { + list-style: none; + padding: 0; + margin: 0 0 16px; +} + +.program-card__list li { + position: relative; + padding-left: 18px; + margin-bottom: 6px; + font-size: 0.9rem; + line-height: 1.4; + color: #374151; +} + +.program-card__list li::before { + content: "✓"; + position: absolute; + left: 0; + color: var(--accent, #7C3AED); + font-weight: 700; +} + +.program-card__meta { + display: flex; + flex-wrap: wrap; + gap: 6px; + margin-bottom: 12px; +} + +.program-card__meta-item { + font-size: 0.75rem; + padding: 3px 10px; + border-radius: 20px; + background: #F1F5F9; + color: #475569; + font-weight: 600; +} + +.program-card__price { + display: flex; + align-items: baseline; + gap: 6px; + margin-bottom: 14px; + margin-top: auto; +} + +.program-card__price-val { + font-size: 1.35rem; + font-weight: 800; + color: var(--navy); +} + +.program-card__price-period { + font-size: 0.8rem; + color: #94A3B8; +} + +.program-card__btn { + display: block; + width: 100%; + padding: 12px; + border: none; + border-radius: 12px; + font-family: inherit; + font-size: 1rem; + font-weight: 700; + color: #fff; + cursor: pointer; + background: var(--accent, #7C3AED); + transition: opacity 0.15s; +} + +.program-card__btn:hover { opacity: 0.9; } +.program-card__btn--green { background: #16A34A; } +.program-card__btn--blue { background: #2563EB; } +.program-card__btn--purple { background: #7C3AED; } + +.programs-note { + text-align: center; + padding: 16px 0 0; + font-size: 0.925rem; + color: var(--slate-600); +} + +.programs-note__link { + color: var(--accent, #7C3AED); + font-weight: 700; + text-decoration: underline; + text-underline-offset: 2px; +} + +@media (max-width: 639px) { + .programs-grid { + grid-template-columns: 1fr; + gap: 16px; + } + .program-card__header { + padding: 14px 16px; + } + .program-card__title { + font-size: 0.95rem; + } + .program-card__body { + padding: 16px; + } +} + +/* ============================================================ + 10. FINAL CTA + ============================================================ */ +.final-cta { + text-align: center; + padding: 24px 0; +} + +.final-cta__text { + font-size: 1rem; + color: var(--slate-600); + line-height: 1.6; + max-width: 540px; + margin: 0 auto 24px; +} + +.final-cta__footnote { + font-size: 0.8125rem; + color: var(--accent, #7C3AED); + font-weight: 600; + margin: 16px 0 0; +} + +.btn-primary--large { + padding: 18px 40px; + font-size: 1.125rem; + min-height: 56px; + border-radius: 32px; +} + +/* ============================================================ + 11. MOBILE OVERRIDES + ============================================================ */ +@media (max-width: 639px) { + .bento-card { + padding: 20px 16px; + border-radius: 20px; + } + + .bento-h2 { + font-size: 1.375rem; + } + + .result-item__value { + font-size: 1.75rem; + } +} + +/* ============================================================ + 11b. MOBILE — Fixed header compensation + Header is 76px fixed at top. Banner must not hide behind it. + ============================================================ */ +@media (max-width: 860px) { + .page-pksh .banner { + padding-top: 76px; + margin-top: -76px; /* fixed header compensation */ + } + .page-pksh .banner__content.mobile { + margin-top: 0; /* ensure no double gap */ + } +} + +/* ============================================================ + 11c. MOBILE — Banner scarcity on mobile wraps nicely + ============================================================ */ +@media (max-width: 639px) { + .banner__scarcity { + font-size: 12px; + padding: 4px 14px; + margin: 8px auto 0; + } + .btn-banner--main { + font-size: 14px; + padding: 12px 24px; + width: 100%; + max-width: 320px; + } +} + +/* ============================================================ + 12. ANCHOR NAVIGATION + ============================================================ */ +/* ═══════════════════════════════════════════════════════════════ + ANCHOR NAV — redesigned for desktop 2026-05 + + Problem: links were too small (8×18px padding, 14px font), + nav was 1280px wide (no alignment with 900px content axis of + sections 2-4), vertical rhythm was 12px vs section 80px. + + Solution: + • Container → 900px (aligns with Social/Micro/Guarantee axis) + • Flex-wrap 2 rows × 3 pills, centered + • Pills → 14×28px padding, 16px font (body-text scale) + • Purple hover with translateY(-2px) + glow shadow + • Vertical padding 48/56px (matches section rhythm) + ═══════════════════════════════════════════════════════════ */ +.pksh-anchor-nav { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 10px; + max-width: 900px; + margin: 0 auto; + padding: 48px 16px 56px; + overflow: visible; +} + +.pksh-anchor-link { + flex-shrink: 0; + padding: 14px 28px; + border-radius: 100px; + background: #FFFFFF; + color: #475569; + font-size: 1rem; + font-weight: 600; + text-decoration: none; + border: 1.5px solid #E2E8F0; + transition: all 0.2s ease; + white-space: nowrap; +} + +.pksh-anchor-link:hover, +.pksh-anchor-link:focus-visible { + background: #F5F3FF; + color: #7C3AED; + border-color: #7C3AED; + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(124, 58, 237, 0.15); +} + +.pksh-anchor-link--cta { + background: linear-gradient(135deg, #7C3AED, #8B5CF6); + color: #fff; + border-color: transparent; +} + +.pksh-anchor-link--cta:hover, +.pksh-anchor-link--cta:focus-visible { + background: linear-gradient(135deg, #6D28D9, #7C3AED); + color: #fff; + border-color: transparent; + box-shadow: 0 4px 12px rgba(124, 58, 237, 0.3); +} + +@media (max-width: 639px) { + .pksh-anchor-nav { + padding: 32px 16px 40px; + gap: 8px; + justify-content: center; + } + .pksh-anchor-link { + padding: 10px 18px; + font-size: 0.875rem; + min-height: 44px; + display: inline-flex; + align-items: center; + } +} + +/* ============================================================ + 13. FOMO SCARCITY BADGE + ============================================================ */ +.pksh-fomo { + display: flex; + align-items: center; + justify-content: center; + gap: 10px; + margin: 16px auto 0; + padding: 10px 24px; + background: linear-gradient(135deg, #F5F0FF, #EDE4FF); + border-radius: 100px; + max-width: fit-content; + border: 1px solid #D4C4F0; +} + +.pksh-fomo__dot { + width: 10px; + height: 10px; + border-radius: 50%; + background: var(--accent, #7C3AED); + flex-shrink: 0; + animation: pksh-pulse 2s infinite; +} + +@keyframes pksh-pulse { + 0%, 100% { opacity: 1; transform: scale(1); } + 50% { opacity: 0.6; transform: scale(1.3); } +} + +.pksh-fomo__text { + font-size: 0.875rem; + font-weight: 600; + color: #9A3412; +} + +/* ============================================================ + 14. OVERRIDE: fix CTA gap 640–860px + Sticky CTA appears at 860px to match when banner CTA hides + ============================================================ */ +@media (max-width: 860px) { + .sticky-cta-mobile { + display: block; + } + body { + padding-bottom: 80px; + } +} + +/* ============================================================ + 16. OVERRIDE: Teachers section — constrain on mobile + Swiper overflows viewport at <640px + ============================================================ */ +@media (max-width: 639px) { + .page-pksh .our-teachers .container { + padding-left: 16px !important; + padding-right: 16px !important; + } + .page-pksh .teachers-owl-wrapper { + padding: 0 !important; + } +} + +/* ============================================================ + 18. OVERRIDE: Program card buttons — accent gradient + Match brand CTAs (banner, sticky, final) instead of solid orange + ============================================================ */ +.page-pksh .program-card__btn { + background: linear-gradient(135deg, var(--accent, #7C3AED), var(--accent-500, #8B5CF6)) !important; + font-family: 'Roboto', sans-serif; + border-radius: var(--radius-pill, 28px); + padding: 14px 12px; + transition: opacity 0.15s, transform 0.15s, box-shadow 0.15s; +} +.page-pksh .program-card__btn:hover { + opacity: 0.95; + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(124, 58, 237, 0.3); +} +.page-pksh .program-card__btn--green, +.page-pksh .program-card__btn--blue, +.page-pksh .program-card__btn--purple { + background: linear-gradient(135deg, var(--accent, #7C3AED), var(--accent-500, #8B5CF6)) !important; +} + +/* ============================================================ + 19. OVERRIDE: Header btn-lilac — use accent + Legacy header button should match brand + ============================================================ */ +.page-pksh .btn-lilac { + background: linear-gradient(135deg, var(--accent, #7C3AED), var(--accent-500, #8B5CF6)) !important; + font-family: 'Roboto', sans-serif !important; + font-weight: 700 !important; + text-transform: none !important; + border-radius: var(--radius-pill, 28px) !important; + border: none !important; +} + +.page-pksh .btn-lilac:hover { + background: linear-gradient(135deg, var(--accent-hover, #6D28D9), var(--accent-700, #5B21B6)) !important; +} + +/* ============================================================ + 15. OVERRIDE: Banner CTA accent + Use accent (purple) for banner CTA to match brand + ============================================================ */ +.page-pksh .btn-banner--main { + background: linear-gradient(135deg, var(--accent, #7C3AED), var(--accent-500, #8B5CF6)); + border: none; + color: #fff; + font-family: 'Roboto', sans-serif; + font-weight: 700; + text-transform: none; + letter-spacing: 0; +} +.page-pksh .btn-banner--main:hover { + background: linear-gradient(135deg, var(--accent-hover, #6D28D9), var(--accent-700, #5B21B6)); +} + +/* ============================================================ + 21. DESKTOP LAYOUT — ширину.всё. + Force ALL bento sections to fill max-width (1280px). + Fix: inline-block-like collapse when content narrower. + ============================================================ */ +.page-pksh .bento { + width: 100%; +} + +/* Inner grid items fill their cells (CSS Grid default is stretch) */ +.page-pksh .bento__full, +.page-pksh .bento__half, +.page-pksh .bento__wide { + min-width: 0; /* prevent grid overflow from long words */ + box-sizing: border-box; +} + +/* ── 21b. Social Counters — center content ── */ +.page-pksh .social-counters { + width: 100%; + display: flex; + justify-content: space-evenly; + align-items: center; + flex-wrap: wrap; + gap: 24px; +} + +.page-pksh .social-counter { + flex: 1 1 180px; + max-width: 280px; + display: flex; + align-items: center; + gap: 14px; +} + +/* ── 21c. Programs grid — fill bento width ── */ +.page-pksh .programs-grid { + width: 100%; +} + +/* ── 21d. Final CTA — full width + centered content ── */ +.page-pksh #final-cta .bento__full { + width: 100%; + max-width: 700px; + margin: 0 auto; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; +} + +/* ── 21f. Consistent section vertical spacing ── */ +.page-pksh .pksh-section + .pksh-section { + /* Sections already have padding: 80px 0; no extra margin needed */ +} +.page-pksh .pksh-section + .pksh-anchor-nav, +.page-pksh .pksh-anchor-nav + .pksh-section { + margin-top: 0; +} +.page-pksh .pksh-section + :not(.pksh-section):not(.pksh-anchor-nav) { + /* map, etc. — no extra spacing */ +} + +/* ── 21g. Guarantee card ── fill height ── */ +/* (removed — guarantee uses .guarantee-block--centered now) */ + +/* ============================================================ + 22. DESKTOP — program cards 4-col on wide screens + ============================================================ */ +@media (min-width: 1100px) { + .page-pksh .programs-grid { + grid-template-columns: repeat(4, 1fr); + } +} + +/* ============================================================ + 23. DESKTOP — teacher cards in bento ── constrain within grid + Teachers.php uses .container with padding:20px 90px which + overflows when bento is 1280px. Reduce padding to grid padding. + ============================================================ */ +.page-pksh #teachers .our-teachers .container { + max-width: 100%; + width: 100%; + padding: 20px 24px 40px; +} + +/* Teacher slides — fix fixed width on desktop */ +.page-pksh .teachers-owl .swiper-slide { + width: auto !important; + flex: 0 0 236px; +} + +/* ============================================================ + 23b. Price section (legacy) — prevent narrow collapse + The price section uses .container with padding, outside bento grid + ============================================================ */ +.page-pksh .price .container { + max-width: 1280px; + padding-left: 32px; + padding-right: 32px; +} + +/* ============================================================ + 25. BANNER GUARANTEE MICRO + ============================================================ */ +.banner__guarantee { + font-family: 'Roboto', sans-serif; + font-size: 13px; + font-weight: 600; + color: #FFD43E; + text-align: center; + margin: 10px 0 0; + padding: 8px 18px; + background: rgba(15, 23, 42, 0.6); + border: 1px solid rgba(255, 212, 62, 0.3); + border-radius: 100px; + display: inline-block; + max-width: fit-content; + backdrop-filter: blur(4px); +} + +.banner__guarantee strong { + color: #fff; +} + +@media (max-width: 860px) { + .banner__guarantee { + font-size: 11px; + padding: 6px 14px; + } +} + +/* ============================================================ + 26. GUARANTEE HERO BLOCK (Risk Reversal showcase) + Unified to purple design system: warm neutral card × + purple border/accents. Orange → purple migration. + ============================================================ */ +.guarantee-hero { + display: flex; + align-items: center; + gap: 32px; + max-width: 900px; + margin: 0 auto; + padding: 32px 24px; + background: linear-gradient(135deg, #F8F4F0 0%, #F0EBE5 50%, #F8F4F0 100%); + border: 2px solid #7C3AED; + border-radius: var(--radius-2026, 24px); +} + +.guarantee-hero__shield { + flex-shrink: 0; + font-size: 4rem; + line-height: 1; +} + +.guarantee-hero__content { + flex: 1; +} + +.guarantee-hero__text { + font-size: 1rem; + line-height: 1.6; + color: var(--slate-600, #475569); + margin: 0 0 18px; +} + +.guarantee-hero__text strong { + color: #6D28D9; +} + +.guarantee-hero__btn { + padding: 14px 32px; + font-size: 1rem; +} + +.guarantee-hero__badges { + display: flex; + flex-direction: column; + align-items: center; + gap: 12px; + flex-shrink: 0; +} + +@media (max-width: 639px) { + .guarantee-hero { + flex-direction: column; + text-align: center; + gap: 16px; + padding: 24px 20px; + } + .guarantee-hero__badges { + flex-direction: row; + gap: 16px; + } + .guarantee-hero__shield { + font-size: 3rem; + } +} + +/* ============================================================ + 26b. GUARANTEE HERO — section background + spacing override + Base .pksh-section--alt gives cool #F8FAFC — clashes with + warm palette. White keeps the visual rhythm consistent: + gradient → white → warm stone → white → nav + Padding reduced from 80px → 32/48 for 80px gap rhythm. + ============================================================ */ +.page-pksh .bento[aria-label="Гарантия"] { + background: #FFFFFF; + padding: 32px 32px 48px; +} + +@media (max-width: 860px) { + .page-pksh .bento[aria-label="Гарантия"] { + padding: 24px 16px 32px; + } +} + +/* ============================================================ + 27. MICRO-COMMITMENT (checklist download) + ============================================================ */ +.micro-commit { + display: flex; + align-items: center; + gap: 40px; + max-width: 900px; + margin: 0 auto; + padding: 32px 24px; + background: #fff; + border-radius: var(--radius-2026, 24px); + box-shadow: 0 8px 32px rgba(0,0,0,0.06); +} + +.micro-commit__content { + flex: 1; +} + +.micro-commit__visual { + flex-shrink: 0; + width: 120px; + height: 120px; + background: #F5F0FF; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; +} + +.micro-commit__btn { + padding: 14px 32px; + font-size: 1rem; + margin-top: 8px; +} + +.micro-commit__disclaimer { + font-size: 0.75rem; + color: #94A3B8; + margin: 8px 0 0; +} + +@media (max-width: 639px) { + .micro-commit { + flex-direction: column; + text-align: center; + gap: 20px; + padding: 24px 20px; + } + .micro-commit__visual { + width: 80px; + height: 80px; + } +} + +/* ============================================================ + 28. DESKTOP STICKY CTA + ============================================================ */ +.sticky-cta-desktop { + display: none; + position: fixed; + bottom: 0; + left: 0; + right: 0; + z-index: 999; + background: rgba(255,255,255,0.95); + backdrop-filter: blur(12px); + border-top: 1px solid #E2E8F0; + padding: 12px 32px; + box-shadow: 0 -4px 20px rgba(0,0,0,0.06); + animation: stickyFadeIn 0.3s ease; +} + +@keyframes stickyFadeIn { + from { opacity: 0; transform: translateY(16px); } + to { opacity: 1; transform: translateY(0); } +} + +.sticky-cta-desktop__inner { + max-width: 1280px; + margin: 0 auto; + display: flex; + align-items: center; + justify-content: space-between; + gap: 24px; +} + +.sticky-cta-desktop__info { + display: flex; + align-items: center; + gap: 16px; +} + +.sticky-cta-desktop__badge { + display: inline-block; + padding: 4px 14px; + background: var(--accent, #7C3AED); + color: #fff; + font-size: 0.8125rem; + font-weight: 700; + border-radius: 100px; +} + +.sticky-cta-desktop__text { + font-size: 0.9375rem; + color: var(--navy, #0F172A); + font-weight: 500; +} + +.sticky-cta-desktop__text strong { + color: var(--accent, #7C3AED); +} + +.sticky-cta-desktop__btn { + padding: 14px 32px; + font-size: 1rem; + font-weight: 700; + border: none; + border-radius: 32px; + background: linear-gradient(135deg, var(--accent, #7C3AED), var(--accent-500, #8B5CF6)); + color: #fff; + cursor: pointer; + font-family: 'Roboto', sans-serif; + transition: opacity 0.15s, transform 0.15s; + white-space: nowrap; +} + +.sticky-cta-desktop__btn:hover { + opacity: 0.95; + transform: translateY(-1px); +} + +/* Desktop sticky — show after scrolling past header (~200px) via IntersectionObserver + but default to hidden. Will be shown by JS. */ +@media (min-width: 861px) { + .sticky-cta-desktop { + display: block; + transform: translateY(100%); + transition: transform 0.3s ease; + } + .sticky-cta-desktop.visible { + transform: translateY(0); + } + body { + padding-bottom: 0; + } +} + +/* ============================================================ + 29. TAP TARGET SIZE FIX (Mobile 48px minimum) + ============================================================ */ +@media (max-width: 639px) { + .page-pksh .btn-primary, + .page-pksh .btn-banner--main, + .page-pksh .program-card__btn, + .page-pksh .sticky-cta-btn, + .page-pksh .guarantee-hero__btn, + .page-pksh .micro-commit__btn { + min-height: 48px; + padding-top: 14px; + padding-bottom: 14px; + font-size: 1rem; + } + + /* (FAQ trigger removed — FAQ uses box__accordion now) */ + + /* Social counters — make entire card tappable */ + .page-pksh .social-counter { + min-height: 48px; + } + + /* Final CTA footnote — ensure sufficient height */ + .page-pksh .final-cta__footnote { + padding: 8px 0; + } +} + +/* ============================================================ + 30. SCARCITY ANIMATION & VISUAL WEIGHT + ============================================================ */ +.banner__scarcity { + animation: scarcityPulse 2s ease-in-out infinite; +} + +@keyframes scarcityPulse { + 0%, 100% { transform: scale(1); background: rgba(249, 115, 22, 0.25); } + 50% { transform: scale(1.03); background: rgba(249, 115, 22, 0.35); } +} + +/* Hover on scarcity increases urgency */ +.banner__scarcity:hover { + animation-play-state: paused; + background: rgba(249, 115, 22, 0.4); +} + +/* ============================================================ + 31. BANNER ADDRESS — visual enhancement + ============================================================ */ +.banner__address { + display: flex; + align-items: center; + justify-content: center; + gap: 6px; + opacity: 0.9; +} + +/* ============================================================ + 32. FOMO SCARCITY — make more urgent + Replace pulsing dot with stronger indicator + ============================================================ */ +.pksh-fomo { + cursor: pointer; + transition: transform 0.2s, box-shadow 0.2s; +} + +.pksh-fomo:hover { + transform: scale(1.02); + box-shadow: 0 4px 16px rgba(234, 88, 12, 0.15); +} + +/* ============================================================ + 33. TEACHERS — show experience/credentials + Teacher direction already shows. Style enhancement. + ============================================================ */ +.page-pksh .ourteacher_title { + font-size: 0.8125rem; + min-height: 36px; + display: flex; + align-items: center; + justify-content: center; + text-align: center; + padding: 0 4px; +} + +/* ============================================================ + 34. TWO-COLUMN PROGRAMS (Desktop) + Override 4-col to 2-col with feature comparison + ============================================================ */ +@media (min-width: 1100px) { + .page-pksh .programs-grid { + grid-template-columns: repeat(2, 1fr) !important; + } +} + +/* ============================================================ + 36. SCROLL PROGRESS INDICATOR (optional enhancement) + ============================================================ */ +.page-pksh .pksh-scroll-progress { + position: fixed; + top: 0; + left: 0; + height: 3px; + background: linear-gradient(90deg, var(--accent, #7C3AED), #A855F7); + z-index: 10000; + width: 0%; + transition: width 0.1s linear; +} + +/* ============================================================ + 37. MOBILE BANNER OVERRIDE — show CTA inside banner__content + Main.css hides .banner__content .btn-write on mobile. + We moved button INSIDE .banner__content.mobile — unhide. + ============================================================ */ +@media (max-width: 860px) { + .page-pksh .banner__content.mobile .btn-write { + display: block !important; + width: 100%; + max-width: 320px; + margin: 10px auto 0; + padding: 14px 24px; + font-size: 16px; + border-radius: 32px; + background: linear-gradient(135deg, var(--accent, #7C3AED), var(--accent-500, #8B5CF6)); + border: none; + color: #fff; + font-weight: 700; + font-family: 'Roboto', sans-serif; + cursor: pointer; + transition: opacity 0.15s; + } + .page-pksh .banner__content.mobile .btn-write:hover { + opacity: 0.95; + } + + .page-pksh .banner__content.mobile .banner__scarcity { + display: block; + margin: 8px auto 0; + font-size: 12px; + } + + .page-pksh .banner__content.mobile .banner__guarantee { + display: inline-block; + margin: 8px auto 0; + font-size: 11px; + } + + .page-pksh .banner__content.mobile .banner__address { + font-size: 13px; + margin-bottom: 6px; + opacity: 0.85; + } + + /* Mobile banner content — ensure proper spacing for stacked elements */ + .page-pksh .banner__content.mobile { + padding: 16px 20px; + display: flex; + flex-direction: column; + align-items: center; + gap: 2px; + } + + .page-pksh .banner__content.mobile .page_title { + font-size: 22px; + line-height: 1.2; + margin: 4px 0; + } + + .page-pksh .banner__content.mobile .banner_text { + font-size: 15px; + margin: 4px 0; + } +} + +/* ============================================================ + 38. PKSH ANCHOR NAV — scroll offset for fixed header + ============================================================ */ +.page-pksh #how-it-works, +.page-pksh #results, +.page-pksh #programs, +.page-pksh #teachers, +.page-pksh #results, +.page-pksh #programs, +.page-pksh #teachers, +.page-pksh #faq, +.page-pksh #final-cta { + scroll-margin-top: 100px; +} + +/* ============================================================ + 39. HERO — light warm background (neuro-optimized for ЦА) + Psychology: warm cream (safe, home, care) → soft sage (growth, nature, trust) + Text: deep navy for authority, slate for readability + CTA: purple accent on light bg for contrast + premium feel + ============================================================ */ + +/* ── Hero container ── */ +.page-pksh .hero-pksh { + position: relative; + min-height: 600px; + display: flex; + flex-direction: column; + overflow: hidden; + /* Warm cream → soft sage: home + nature = safe growth */ + background: linear-gradient(135deg, #FCFAF2 0%, #F5F0E8 30%, #E6EDE6 70%, #DCE5DA 100%); +} + +/* ── Background layer ── */ +.hero-pksh__bg { + position: absolute; + inset: 0; + z-index: 0; + pointer-events: none; +} + +/* ── Blobs — very muted natural tones ── */ +.hero-pksh__blob { + position: absolute; + border-radius: 50%; + filter: blur(80px); + will-change: transform; +} + +.hero-pksh__blob--1 { + width: 560px; height: 560px; + background: #D4C5A9; /* warm tan — earth/nurture */ + top: -200px; right: -120px; + opacity: 0.10; + animation: heroBlob1 8s ease-in-out infinite alternate; +} + +.hero-pksh__blob--2 { + width: 420px; height: 420px; + background: #A8C5B5; /* sage — growth/calm */ + bottom: -140px; left: -80px; + opacity: 0.08; + animation: heroBlob2 10s ease-in-out infinite alternate; +} + +.hero-pksh__blob--3 { + width: 280px; height: 280px; + background: #E8D5C0; /* peach — warmth/play */ + top: 40%; left: 45%; + opacity: 0.06; + animation: heroBlob3 6s ease-in-out infinite alternate; +} + +@keyframes heroBlob1 { + 0% { transform: translate(0, 0) scale(1); } + 100% { transform: translate(-40px, 30px) scale(1.08); } +} +@keyframes heroBlob2 { + 0% { transform: translate(0, 0) scale(1); } + 100% { transform: translate(30px, -20px) scale(1.05); } +} +@keyframes heroBlob3 { + 0% { transform: translate(0, 0) scale(1); opacity: 0.06; } + 100% { transform: translate(20px, 10px) scale(1.12); opacity: 0.09; } +} + +/* ── Dot pattern — dark dots on light bg ── */ +.hero-pksh__pattern { + position: absolute; + inset: 0; + background-image: radial-gradient(rgba(0, 0, 0, 0.04) 1px, transparent 1px); + background-size: 24px 24px; +} + +/* ── Breadcrumbs ── */ +.hero-pksh__breadcrumbs { + position: relative; + z-index: 2; + padding-top: 24px; +} + +@media (max-width: 860px) { + .hero-pksh__breadcrumbs { + padding-top: 96px; + } +} + +.hero-pksh__breadcrumbs .breadcrumbs a, +.hero-pksh__breadcrumbs .breadcrumbs span { + color: #94A3B8; +} + +.hero-pksh__breadcrumbs .breadcrumbs a:hover { + color: #475569; +} + +/* ── Main layout grid ── */ +.hero-pksh__layout { + position: relative; + z-index: 1; + flex: 1; + display: grid; + grid-template-columns: 1fr 1fr; + gap: 40px; + max-width: 1280px; + margin: 0 auto; + padding: 32px 32px 48px; + width: 100%; + align-items: center; +} + +/* ── Content column (left) ── */ +.hero-pksh__content { + display: flex; + flex-direction: column; + gap: 14px; +} + +/* ── Address pill ── */ +.hero-pksh__address { + display: inline-flex; + align-items: center; + gap: 6px; + font-family: 'Roboto', sans-serif; + font-size: 15px; + font-weight: 500; + color: #64748B; + background: rgba(0, 0, 0, 0.03); + backdrop-filter: blur(8px); + -webkit-backdrop-filter: blur(8px); + padding: 8px 18px; + border-radius: 100px; + max-width: fit-content; + border: 1px solid rgba(0, 0, 0, 0.06); + transition: background 0.2s; +} + +.hero-pksh__address svg { + width: 16px; height: 16px; + flex-shrink: 0; + color: #94A3B8; +} + +/* ── Headline — deep navy for authority + confidence ── */ +.hero-pksh__title { + font-family: 'Oswald', sans-serif; + font-size: 48px; + font-weight: 600; + line-height: 1.08; + color: #1E293B; + margin: 4px 0; + text-shadow: none; + max-width: 580px; +} + +/* ── Subtitle ── */ +.hero-pksh__subtitle { + font-family: 'Roboto', sans-serif; + font-size: 20px; + font-weight: 400; + line-height: 1.5; + color: #475569; + margin: 0; + max-width: 500px; +} + +/* ── Actions (CTA + scarcity) ── */ +.hero-pksh__actions { + display: flex; + flex-direction: column; + gap: 10px; + margin-top: 6px; +} + +/* ── CTA — purple on light = premium contrast ── */ +.hero-pksh__cta { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 18px 40px; + font-family: 'Roboto', sans-serif; + font-size: 18px; + font-weight: 700; + color: #fff; + background: linear-gradient(135deg, #7C3AED, #A855F7); + border: none; + border-radius: 100px; + cursor: pointer; + transition: transform 0.2s ease, box-shadow 0.2s ease, opacity 0.2s ease; + box-shadow: 0 8px 28px rgba(124, 58, 237, 0.25); + max-width: fit-content; + text-transform: none; + letter-spacing: 0; +} + +.hero-pksh__cta:hover { + transform: translateY(-2px); + box-shadow: 0 12px 36px rgba(124, 58, 237, 0.35); + opacity: 0.97; +} + +.hero-pksh__cta:active { + transform: translateY(0); + box-shadow: 0 4px 12px rgba(124, 58, 237, 0.20); +} + +/* ── Scarcity — warm amber urgency (not alarm) ── */ +.hero-pksh__scarcity { + font-family: 'Roboto', sans-serif; + font-size: 14px; + font-weight: 600; + color: #92400E; + background: #FEF3C7; + padding: 8px 20px; + border-radius: 100px; + max-width: fit-content; + border: 1px solid rgba(146, 64, 14, 0.12); + animation: heroScarcityPulse 2.5s ease-in-out infinite; +} + +.hero-pksh__scarcity strong { + color: #78350F; + font-weight: 700; +} + +@keyframes heroScarcityPulse { + 0%, 100% { transform: scale(1); background: #FEF3C7; } + 50% { transform: scale(1.02); background: #FDE68A; } +} + +/* ── Trust bar ── */ +.hero-pksh__trust { + display: flex; + flex-wrap: wrap; + gap: 20px; + margin-top: 6px; +} + +.hero-pksh__trust-item { + display: inline-flex; + align-items: center; + gap: 6px; + font-family: 'Roboto', sans-serif; + font-size: 14px; + color: #64748B; +} + +.hero-pksh__trust-icon { + font-size: 16px; + line-height: 1; +} + +.hero-pksh__trust-label strong { + color: #1E293B; + font-weight: 700; +} + +/* ── Visual column (right) ── */ +.hero-pksh__visual { + position: relative; + display: flex; + align-items: center; + justify-content: center; + min-height: 420px; +} + +/* ── Image frame ── */ +.hero-pksh__frame { + width: 100%; + max-width: 420px; + aspect-ratio: 3 / 4; + border-radius: 24px; + overflow: hidden; + box-shadow: 0 28px 72px rgba(0, 0, 0, 0.06); + background: rgba(255, 255, 255, 0.6); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + border: 1px solid rgba(0, 0, 0, 0.04); +} + +.hero-pksh__img { + width: 100%; + height: 100%; + position: relative; +} + +/* Placeholder — light version */ +.hero-pksh__img-placeholder { + width: 100%; height: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 16px; + background: linear-gradient(135deg, rgba(124, 58, 237, 0.03), rgba(249, 115, 22, 0.03)); +} + +.hero-pksh__placeholder-icon svg circle, +.hero-pksh__placeholder-icon svg path { + fill: rgba(0, 0, 0, 0.06); +} + +.hero-pksh__placeholder-icon svg { + display: block; +} + +.hero-pksh__placeholder-label { + font-family: 'Roboto', sans-serif; + font-size: 13px; + font-weight: 500; + color: rgba(0, 0, 0, 0.25); + letter-spacing: 0.02em; +} + +/* ── Floating badges ── */ +.hero-pksh__float { + position: absolute; + display: flex; + align-items: center; + gap: 8px; + padding: 10px 20px; + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + border-radius: 100px; + font-family: 'Roboto', sans-serif; + font-size: 14px; + font-weight: 600; + color: #1E293B; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.04); + white-space: nowrap; + animation: heroFloat 4s ease-in-out infinite; + border: 1px solid rgba(0, 0, 0, 0.04); +} + +.hero-pksh__float--1 { top: 8%; right: -8px; animation-delay: 0s; } +.hero-pksh__float--2 { bottom: 28%; left: -24px; animation-delay: 1.2s; } +.hero-pksh__float--3 { bottom: 6%; right: 12%; animation-delay: 2.6s; } + +.hero-pksh__float-icon { + font-size: 18px; + line-height: 1; +} + +@keyframes heroFloat { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-8px); } +} + +/* ── Decorative dots ── */ +.hero-pksh__dot { + position: absolute; + border-radius: 50%; + background: rgba(0, 0, 0, 0.06); + pointer-events: none; +} + +.hero-pksh__dot--1 { width: 14px; height: 14px; top: 18%; left: 8%; } +.hero-pksh__dot--2 { width: 8px; height: 8px; top: 65%; left: 12%; } +.hero-pksh__dot--3 { width: 18px; height: 18px; bottom: 44%; right: 4%; } +.hero-pksh__dot--4 { width: 6px; height: 6px; bottom: 14%; right: 28%;} + +/* ============================================================ + 39b. HERO — Responsive (Tablet) + ============================================================ */ +@media (max-width: 1024px) { + .hero-pksh__layout { gap: 32px; padding: 24px 24px 48px; } + .hero-pksh__title { font-size: 40px; } + .hero-pksh__frame { max-width: 360px; } + .hero-pksh__float--1 { right: 0; } + .hero-pksh__float--2 { left: -12px; } +} + +/* ============================================================ + 39c. HERO — Responsive (Mobile < 860px) + ============================================================ */ +@media (max-width: 860px) { + .page-pksh .hero-pksh { min-height: auto; } + .hero-pksh__layout { grid-template-columns: 1fr; gap: 28px; padding: 16px 16px 48px; } + .hero-pksh__content { gap: 12px; align-items: flex-start; } + .hero-pksh__title { font-size: 32px; max-width: 100%; } + .hero-pksh__subtitle { font-size: 17px; max-width: 100%; } + .hero-pksh__address { font-size: 13px; padding: 6px 14px; } + .hero-pksh__cta { width: 100%; max-width: 100%; font-size: 16px; padding: 16px 24px; min-height: 52px; justify-content: center; text-align: center; } + .hero-pksh__actions { width: 100%; } + .hero-pksh__scarcity { width: 100%; max-width: 100%; text-align: center; font-size: 13px; padding: 8px 16px; box-sizing: border-box; } + .hero-pksh__trust { justify-content: flex-start; gap: 14px; } + .hero-pksh__trust-item { font-size: 12px; } + .hero-pksh__trust-icon { font-size: 14px; } + .hero-pksh__visual { min-height: 320px; order: 1; } + .hero-pksh__frame { max-width: 300px; } + .hero-pksh__float--1 { top: 4%; right: 0; font-size: 12px; padding: 6px 14px; } + .hero-pksh__float--2 { bottom: 22%; left: -8px; font-size: 12px; padding: 6px 14px; } + .hero-pksh__float--3 { bottom: 2%; right: 5%; font-size: 12px; padding: 6px 14px; } + .hero-pksh__dot--1 { top: 10%; left: 4%; } + .hero-pksh__dot--2 { top: 55%; left: 6%; } + .hero-pksh__dot--3 { bottom: 35%; right: 4%; } + .hero-pksh__dot--4 { bottom: 10%; right: 20%; } +} + +/* ============================================================ + 39d. HERO — Small mobile (< 480px) + ============================================================ */ +@media (max-width: 480px) { + .hero-pksh__title { font-size: 26px; } + .hero-pksh__subtitle { font-size: 15px; } + .hero-pksh__trust { gap: 10px; } + .hero-pksh__trust-item { font-size: 11px; gap: 4px; } + .hero-pksh__visual { min-height: 260px; } + .hero-pksh__frame { max-width: 240px; } +} + +/* ============================================================ + 39e. HERO — hide old mobile banner (safety net) + ============================================================ */ +.page-pksh .banner__content.mobile { + display: none !important; +} + +/* ============================================================ + 39f. Reduced motion — respect user preference + ============================================================ */ +@media (prefers-reduced-motion: reduce) { + .hero-pksh__blob, + .hero-pksh__float, + .hero-pksh__scarcity { animation: none !important; } + .hero-pksh__cta { transition: none !important; } +} + +/* ============================================================ + 40. SOCIAL COUNTERS — warm card design (hero-compatible) + Matches hero's light warm aesthetic. + Cards: warm cream bg, purple icon accents, subtle shadow. + ============================================================ */ + +/* ── Section background + spacing consistent with hero padding ── */ +/* NARROW section — constrained 900px content. White bg lets cards + (#F5EDE0 with border+shadow) do the visual work. */ +.page-pksh .bento[aria-label="Социальное доказательство"] { + background: #FFFFFF; + padding: 32px 32px 40px; +} + +@media (max-width: 860px) { + .page-pksh .bento[aria-label="Социальное доказательство"] { + padding: 24px 16px 32px; + } +} + +/* ── Grid: 3 columns desktop, 1 col mobile ── */ +/* Max-width / margin matches micro-commit card (900px) for vertical alignment. */ +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counters { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 16px; + max-width: 900px; + margin: 0 auto; + width: 100%; +} + +@media (max-width: 639px) { + .page-pksh .bento[aria-label="Социальное доказательство"] .social-counters { + grid-template-columns: 1fr; + gap: 12px; + } +} + +@media (min-width: 640px) and (max-width: 860px) { + .page-pksh .bento[aria-label="Социальное доказательство"] .social-counters { + gap: 14px; + } +} + +/* ── Individual counter card ── */ +/* Contrast analysis: + Section bg #F5F2EB = hsl(38,22%,94%) — warm cream. + Card bg #F5EDE0 = hsl(35,38%,92%) — 2pp darker. + Border #E4D7C4 — warm tan. + Shadow 0 4px 16px rgba(0,0,0,0.05) — adds depth. + Card well-defined via 3 cues: border, shadow, warm-tone shift (cards are more yellow). +*/ +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counter { + display: flex; + align-items: center; + gap: 16px; + padding: 20px 24px; + background: #F5EDE0; + border: 1px solid #E4D7C4; + border-radius: 16px; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.05); + flex: none; + min-width: 0; + max-width: none; + transition: box-shadow 0.2s ease, transform 0.2s ease, border-color 0.2s ease; +} + +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counter:hover { + box-shadow: 0 8px 28px rgba(0, 0, 0, 0.06); + transform: translateY(-2px); + border-color: #D4C4AC; +} + +@media (max-width: 860px) { + .page-pksh .bento[aria-label="Социальное доказательство"] .social-counter { + padding: 16px 18px; + gap: 14px; + } +} + +/* ── Icon container ── */ +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counter__icon { + font-size: 24px; + flex-shrink: 0; + width: 48px; + height: 48px; + display: flex; + align-items: center; + justify-content: center; + background: linear-gradient(135deg, rgba(124, 58, 237, 0.10), rgba(168, 85, 247, 0.10)); + border-radius: 12px; +} + +@media (max-width: 860px) { + .page-pksh .bento[aria-label="Социальное доказательство"] .social-counter__icon { + width: 42px; + height: 42px; + font-size: 20px; + } +} + +/* ── Number (stat value) ── */ +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counter__number { + font-family: 'Oswald', sans-serif; + font-size: 28px; + font-weight: 600; + color: #7C3AED; + line-height: 1; + white-space: nowrap; +} + +@media (max-width: 860px) { + .page-pksh .bento[aria-label="Социальное доказательство"] .social-counter__number { + font-size: 24px; + } +} + +/* ── Label ── */ +.page-pksh .bento[aria-label="Социальное доказательство"] .social-counter__label { + font-family: 'Roboto', sans-serif; + font-size: 13px; + color: #64748B; + line-height: 1.35; + margin-top: 4px; +} + +@media (max-width: 860px) { + .page-pksh .bento[aria-label="Социальное доказательство"] .social-counter__label { + font-size: 12px; + } +} + +/* ============================================================ + 41. MICRO-COMMITMENT — warm section, white card, animated SVG + Unlike social counters (white bg × cream cards), + this section alternates: warm bg × white card. + Creates vertical rhythm and visual distinction. + SVG ring: slow rotation = calm, not flashy. + ============================================================ */ + +/* NARROW section — constrained 900px content. White bg */ +.page-pksh .bento[aria-label="Скачать чек-лист"] { + background: #FFFFFF; + padding: 40px 32px 48px; +} + +@media (max-width: 860px) { + .page-pksh .bento[aria-label="Скачать чек-лист"] { + padding: 32px 16px 40px; + } +} + +/* ── Full-width sections: warm #F8F4F0 alternation ── */ +.page-pksh .bento[aria-label="Как проходят занятия"], +.page-pksh .bento#teachers { + background: #F8F4F0; +} + +/* ── Section 6 cards: white on warm, with definition ── */ +.page-pksh #how-it-works .bento-card--soft { + background: #FFFFFF; + border: 1.5px solid #EDE8DF; + box-shadow: 0 6px 24px rgba(0, 0, 0, 0.07); +} +.page-pksh #how-it-works .bento-card--soft:hover { + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); +} + +/* ── Card — white bg with warm border + shadow for depth ── */ +.page-pksh .bento[aria-label="Скачать чек-лист"] .micro-commit { + display: flex; + align-items: center; + gap: 40px; + max-width: 900px; + margin: 0 auto; + padding: 36px 32px; + background: #FFFFFF; + border: 1.5px solid #DED3C0; + border-radius: 24px; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.06); +} + +@media (max-width: 860px) { + .page-pksh .bento[aria-label="Скачать чек-лист"] .micro-commit { + flex-direction: column; + text-align: center; + padding: 28px 20px; + gap: 24px; + border-width: 1px; + } +} + +/* ── Visual — document preview placeholder (replaces circle+ring) ── */ +.page-pksh .bento[aria-label="Скачать чек-лист"] .micro-commit__visual { + flex-shrink: 0; + width: 130px; + height: 170px; + position: relative; + display: flex; + align-items: center; + justify-content: center; + background: #FFFFFF; + border: 1.5px solid #DED3C0; + border-radius: 12px; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.04); +} + +@media (max-width: 860px) { + .page-pksh .bento[aria-label="Скачать чек-лист"] .micro-commit__visual { + width: 96px; + height: 126px; + } +} + +/* ── Checklist illustration SVG fills the visual container ── */ +.page-pksh .micro-commit__svg { + width: 100%; + height: 100%; + display: block; +} + +/* ── Content ── */ +.page-pksh .bento[aria-label="Скачать чек-лист"] .micro-commit__content { + flex: 1; +} + +/* ── Tag "Бесплатно" — purple accent (was orange) ── */ +.page-pksh .bento[aria-label="Скачать чек-лист"] .bento-label { + color: #7C3AED; +} + +/* ── H2 heading — slightly larger for conviction ── */ +.page-pksh .bento[aria-label="Скачать чек-лист"] .bento-h2 { + font-size: 1.75rem; + color: #1E293B; +} + +@media (max-width: 860px) { + .page-pksh .bento[aria-label="Скачать чек-лист"] .bento-h2 { + font-size: 1.375rem; + } +} + +/* ── Description text ── */ +.page-pksh .bento[aria-label="Скачать чек-лист"] .bento-p { + font-size: 1rem; + color: #475569; + line-height: 1.6; +} + +/* ── CTA button — accent gradient, enhanced sizing ── */ +.page-pksh .bento[aria-label="Скачать чек-лист"] .micro-commit__btn { + margin-top: 8px; + padding: 16px 36px; + font-size: 1rem; + border-radius: 100px; + box-shadow: 0 4px 16px rgba(124, 58, 237, 0.20); + transition: transform 0.2s ease, box-shadow 0.2s ease; +} + +.page-pksh .bento[aria-label="Скачать чек-лист"] .micro-commit__btn:hover { + transform: translateY(-2px); + box-shadow: 0 8px 24px rgba(124, 58, 237, 0.30); +} + +/* ── Disclaimer — subtle on warm card bg ── */ +.page-pksh .bento[aria-label="Скачать чек-лист"] .micro-commit__disclaimer { + font-size: 0.75rem; + color: #94A3B8; + margin: 8px 0 0; +} + +/* ============================================================ + 42. REVIEWS — standalone section (camp-style) + lw-card rendering from Carbon Fields complex field. + Same pattern as .camp-reviews on camp page. + ============================================================ */ + +/* ── Section full-width background ── */ +.page-pksh .pksh-reviews { + position: relative; + padding: 80px 32px; + max-width: 1280px; + margin: 0 auto; +} + +/* ── Layout utilities (scoped) ── */ +.page-pksh .pksh-reviews .lw-scroll-x { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + padding-bottom: 8px; +} +.page-pksh .pksh-reviews .lw-scroll-x::-webkit-scrollbar { + height: 6px; +} +.page-pksh .pksh-reviews .lw-scroll-x::-webkit-scrollbar-thumb { + background: #ccc; + border-radius: 8px; +} + +.page-pksh .pksh-reviews .lw-grid { + display: grid; +} +.page-pksh .pksh-reviews .lw-grid--3 { + grid-template-columns: repeat(3, 1fr); +} +.page-pksh .pksh-reviews .lw-gap-20 { + gap: 20px; +} + +.page-pksh .pksh-reviews .lw-flex { + display: flex; +} +.page-pksh .pksh-reviews .lw-flex--row { + flex-direction: row; +} +.page-pksh .pksh-reviews .lw-flex--col { + flex-direction: column; +} +.page-pksh .pksh-reviews .lw-gap-12 { + gap: 12px; +} +.page-pksh .pksh-reviews .lw-items-center { + align-items: center; +} + +/* ── Card ── */ +.page-pksh .pksh-reviews .lw-card { + background: #FFFFFF; + border-radius: 20px; + padding: 20px; + display: flex; + flex-direction: column; + transition: box-shadow 0.3s ease, transform 0.3s ease; +} + +/* ── Avatar ── */ +.page-pksh .pksh-reviews .lw-avatar { + border-radius: 50%; + overflow: hidden; + flex-shrink: 0; + background: rgba(124, 58, 237, 0.08); + display: flex; + align-items: center; + justify-content: center; +} +.page-pksh .pksh-reviews .lw-avatar--48 { + width: 48px; + height: 48px; +} +.page-pksh .pksh-reviews .lw-avatar__img { + width: 100%; + height: 100%; + object-fit: cover; + display: block; +} + +/* ── Typography ── */ +.page-pksh .pksh-reviews .lw-text-dark { + color: #1c2b2d; +} +.page-pksh .pksh-reviews .lw-font-semibold { + font-weight: 600; +} + +/* ── Spacing ── */ +.page-pksh .pksh-reviews .lw-mt-8 { + margin-top: 8px; +} + +/* ── Badge ── */ +.page-pksh .pksh-reviews .lw-badge { + display: inline-flex; + align-items: center; + padding: 4px 10px; + border-radius: 50px; + font-size: 11px; + font-weight: 600; + line-height: 1.2; + white-space: nowrap; + margin-left: auto; + flex-shrink: 0; +} +.page-pksh .pksh-reviews .lw-badge--verified { + background: rgba(124, 58, 237, 0.08); + color: #7C3AED; +} + +/* ── Stars ── */ +.page-pksh .pksh-reviews .lw-stars { + display: flex; + gap: 2px; + align-items: center; +} +.page-pksh .pksh-reviews .lw-star { + color: #D1D5DB; + flex-shrink: 0; +} +.page-pksh .pksh-reviews .lw-star--filled { + color: #FFD43E; +} + +/* ── Card text ── */ +.page-pksh .pksh-reviews .lw-card__text { + font-size: 14px; + line-height: 1.55; + color: #475569; + word-break: break-word; +} + +/* ── Desktop: flex-wrap centered grid ── */ +.page-pksh .pksh-reviews .lw-scroll-x { + overflow: visible; + padding: 0; +} +.page-pksh .pksh-reviews .lw-grid--3 { + display: flex; + flex-wrap: wrap; + gap: 30px; + justify-content: center; +} +.page-pksh .pksh-reviews .lw-grid--3 .lw-card { + width: calc(25% - 23px); + min-width: 280px; + padding: 24px; + box-shadow: 0 2px 16px rgba(0,0,0,0.06); +} +.page-pksh .pksh-reviews .lw-grid--3 .lw-card:hover { + box-shadow: 0 8px 32px rgba(0,0,0,0.1); + transform: translateY(-4px); +} + +@media (max-width: 1200px) { + .page-pksh .pksh-reviews .lw-grid--3 .lw-card { + width: calc(50% - 15px); + min-width: 280px; + } +} + +@media (max-width: 768px) { + .page-pksh .pksh-reviews { + padding: 40px 0; + } + .page-pksh .pksh-reviews .lw-scroll-x { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + padding: 0 0 8px 16px; + margin: 0; + } + .page-pksh .pksh-reviews .lw-grid--3 { + display: flex; + gap: 12px; + overflow-x: auto; + scroll-snap-type: x mandatory; + flex-wrap: nowrap; + justify-content: flex-start; + padding: 0 0 4px 0; + margin: 0; + -webkit-overflow-scrolling: touch; + } + .page-pksh .pksh-reviews .lw-grid--3 .lw-card { + flex: 0 0 280px; + width: auto; + min-width: 0; + scroll-snap-align: start; + } + /* Mobile: all cards visible regardless of pagination state */ + .page-pksh .pksh-reviews .lw-card { + display: flex !important; + } + .page-pksh .pksh-reviews__actions { + display: none !important; + } +} + +@media (max-width: 480px) { + .page-pksh .pksh-reviews .lw-grid--3 .lw-card { + flex: 0 0 250px; + } +} + +/* ============================================================ + 43. REVIEWS — pagination / load more + ============================================================ */ +/* Default collapsed: show 2 rows per breakpoint */ +.page-pksh .pksh-reviews [data-pksh-collapsed] .lw-card:nth-child(n+9) { + display: none; +} +@media (max-width: 1200px) { + .page-pksh .pksh-reviews [data-pksh-collapsed] .lw-card:nth-child(n+5) { + display: none; + } +} +/* Expanded: override nth-child, show all */ +.page-pksh .pksh-reviews [data-pksh-expanded] .lw-card { + display: flex; +} +.page-pksh .pksh-reviews__actions { + display: flex; + justify-content: center; + margin-top: 32px; +} +.page-pksh .pksh-reviews__toggle { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 12px 32px; + font-size: 15px; + font-weight: 600; + font-family: inherit; + color: #7C3AED; + background: rgba(124, 58, 237, 0.08); + border: 1.5px solid rgba(124, 58, 237, 0.2); + border-radius: 100px; + cursor: pointer; + transition: background 0.2s, border-color 0.2s, transform 0.15s; +} +.page-pksh .pksh-reviews__toggle:hover { + background: rgba(124, 58, 237, 0.15); + border-color: rgba(124, 58, 237, 0.35); + transform: translateY(-1px); +} +.page-pksh .pksh-reviews__toggle:active { + transform: translateY(0); +} + +/* ============================================================ + 44. CONTACTS — как на странице лагеря + ============================================================ */ +.page-pksh .pksh-contact { + padding: 0; + background: transparent; + box-shadow: none; +} +.page-pksh .pksh-contact__wrapper { + display: flex; + gap: 30px; + align-items: stretch; +} +.page-pksh .pksh-contact__info { + width: 35%; + display: flex; + flex-direction: column; + gap: 8px; + padding: 32px 0; +} +.page-pksh .pksh-contact__subtitle { + font-size: 15px; + font-weight: 700; + line-height: 1.3; + color: var(--slate-500, #64748B); + text-transform: uppercase; + letter-spacing: 0.06em; + margin-top: 12px; +} +.page-pksh .pksh-contact__subtitle:first-child { + margin-top: 0; +} +.page-pksh .pksh-contact__value { + font-size: clamp(17px, 2vw, 22px); + font-weight: 600; + line-height: 1.3; + color: var(--accent, #7C3AED); + text-decoration: none; +} +.page-pksh .pksh-contact__value:hover { + text-decoration: underline; +} +.page-pksh .pksh-contact__social { + display: flex; + flex-wrap: wrap; + gap: 12px; +} +.page-pksh .pksh-contact__social-link { + display: inline-flex; + align-items: center; + font-size: clamp(16px, 1.8vw, 20px); + font-weight: 600; + color: var(--accent, #7C3AED); + text-decoration: none; + transition: color 0.2s; + position: relative; +} +.page-pksh .pksh-contact__social-link:hover { + color: var(--accent-hover, #6D28D9); +} +.page-pksh .pksh-contact__social-link + .pksh-contact__social-link::before { + content: '·'; + margin-right: 12px; + color: var(--slate-400, #94A3B8); + font-weight: 400; +} +.page-pksh .pksh-contact__map { + flex: 1; + border-radius: 24px; + overflow: hidden; + min-height: 400px; + box-shadow: 0 4px 20px rgba(0,0,0,0.08); +} + +@media (max-width: 768px) { + .page-pksh .pksh-contact__wrapper { + flex-direction: column-reverse; + } + .page-pksh .pksh-contact__info { + width: 100%; + padding: 0; + } + .page-pksh .pksh-contact__map { + min-height: 280px; + margin: 0 -20px; + border-radius: 0; + box-shadow: none; + } +} + +/* ============================================================ + 45. FAQ — как на странице лагеря (pksh-faq) + ============================================================ */ +.page-pksh .pksh-faq { + padding: 0; + background: transparent; + box-shadow: none; +} +.page-pksh .pksh-faq__wrapper { + display: flex; + gap: 30px; +} +.page-pksh .pksh-faq__col { + width: 50%; + display: flex; + flex-direction: column; + gap: 0; + border-top: 1px solid var(--slate-200, #E2E8F0); +} +.page-pksh .pksh-faq .box__accordion { + position: relative; + cursor: pointer; + border-bottom: 1px solid var(--slate-200, #E2E8F0); + border-radius: 0; +} +.page-pksh .pksh-faq .box__accordion_label { + position: relative; + padding: 20px 0; + cursor: pointer; + display: flex; + align-items: center; + gap: 20px; + justify-content: space-between; + padding-left: 0; +} +.page-pksh .pksh-faq .box__accordion_label span { + font-size: clamp(17px, 2vw, 21px); + line-height: 1.3; + font-weight: 600; + color: var(--navy, #1c2b2d); +} +.page-pksh .pksh-faq .box__accordion_label svg { + width: 36px; + height: 36px; + padding: 8px; + border-radius: 50%; + background: var(--accent, #7C3AED); + stroke: #fff; + transition: background 0.2s; + flex-shrink: 0; +} +.page-pksh .pksh-faq .box__accordion_label svg g { + stroke: #fff; +} +.page-pksh .pksh-faq .active .box__accordion_label svg { + rotate: 45deg; + background: var(--accent-hover, #6D28D9); +} +.page-pksh .pksh-faq .box__accordion_content { + display: flex; + position: relative; + overflow: hidden; + max-height: 0; + transition: max-height 0.3s; + gap: 20px; + align-items: center; +} +.page-pksh .pksh-faq .box__accordion_content-text { + display: flex; + flex-direction: column; + gap: 10px; + font-size: 16px; + line-height: 1.6; + color: var(--slate-600, #475569); + padding-bottom: 20px; +} + +@media (max-width: 768px) { + .page-pksh .pksh-faq__wrapper { + flex-direction: column; + gap: 0; + } + .page-pksh .pksh-faq__col { + width: 100%; + border-top: none; + } + .page-pksh .pksh-faq__col:first-child { + border-top: 1px solid var(--slate-200, #E2E8F0); + } +} + +/* ============================================================ + 46. TEACHERS — camp-style cards + ============================================================ */ +.page-pksh .pksh-section--teachers { + background: var(--bg-soft-2026, #F8FAFC); +} + +.pksh-teachers__wrapper { + display: flex; + flex-wrap: wrap; + gap: 24px; + justify-content: center; +} + +.pksh-teachers__item { + width: calc(25% - 18px); + min-width: 220px; + max-width: 280px; +} + +.pksh-teachers__card { + background: #fff; + border-radius: 20px; + overflow: hidden; + box-shadow: 0 2px 12px rgba(0,0,0,0.06); + transition: transform 0.25s ease, box-shadow 0.25s ease; + display: flex; + flex-direction: column; + height: 100%; +} + +.pksh-teachers__card:hover { + transform: translateY(-4px); + box-shadow: 0 8px 24px rgba(0,0,0,0.10); +} + +.pksh-teachers__card-top { + background: linear-gradient(135deg, rgba(124, 58, 237, 0.05), rgba(139, 92, 246, 0.08)); + display: flex; + justify-content: center; + padding: 24px 20px 16px; +} + +.pksh-teachers__photo { + width: 120px; + height: 120px; + border-radius: 50%; + object-fit: cover; + border: 4px solid #fff; + box-shadow: 0 4px 12px rgba(0,0,0,0.08); +} + +.pksh-teachers__card-body { + padding: 12px 20px 20px; + display: flex; + flex-direction: column; + gap: 6px; + flex: 1; +} + +.pksh-teachers__name { + font-size: 1.0625rem; + font-weight: 700; + line-height: 1.3; + color: var(--navy, #0F172A); + text-align: center; + margin: 0; +} + +.pksh-teachers__subj { + font-size: 0.8125rem; + line-height: 1.4; + color: var(--accent, #7C3AED); + text-align: center; + font-weight: 600; + margin: 0; +} + +.pksh-teachers__about { + font-size: 0.8125rem; + line-height: 1.5; + color: var(--slate-600, #475569); + text-align: center; + margin: 2px 0 0; +} + +@media (max-width: 768px) { + .pksh-teachers__item { + width: calc(50% - 12px); + min-width: 0; + max-width: none; + } + .pksh-teachers__wrapper { + gap: 16px; + } + .pksh-teachers__card-top { + padding: 20px 16px 12px; + } + .pksh-teachers__photo { + width: 100px; + height: 100px; + } + .pksh-teachers__card-body { + padding: 10px 16px 16px; + gap: 4px; + } + .pksh-teachers__name { + font-size: 1rem; + } + .pksh-teachers__subj, + .pksh-teachers__about { + font-size: 0.75rem; + } +} + +@media (max-width: 480px) { + .pksh-teachers__item { + width: 100%; + max-width: 280px; + } +} + +@supports (scrollbar-width: thin) { + .pksh-teachers__scroll-x { + scrollbar-width: thin; + scrollbar-color: #ccc transparent; + } +} +.pksh-teachers__scroll-x::-webkit-scrollbar { + height: 6px; +} +.pksh-teachers__scroll-x::-webkit-scrollbar-thumb { + background: #ccc; + border-radius: 8px; +} diff --git a/wp-content/themes/dekart/template-parts/block-banner.php b/wp-content/themes/dekart/template-parts/block-banner.php index 5cca066..2c90c78 100644 --- a/wp-content/themes/dekart/template-parts/block-banner.php +++ b/wp-content/themes/dekart/template-parts/block-banner.php @@ -1,24 +1,53 @@ - diff --git a/wp-content/themes/dekart/template-parts/block-price.php b/wp-content/themes/dekart/template-parts/block-price.php index c7a1eb3..206442d 100644 --- a/wp-content/themes/dekart/template-parts/block-price.php +++ b/wp-content/themes/dekart/template-parts/block-price.php @@ -1,5 +1,31 @@ 0 || $price_hour2 > 0 || $price_hour3 > 0 || $price_hour4 > 0); +$has_discounts = ($price_hour_discount1 > 0 || $price_hour_discount2 > 0 || $price_hour_discount3 > 0 || $price_hour_discount4 > 0); +if ($has_prices || $has_discounts) : ?>
@@ -19,27 +45,6 @@ $check_btn_discont = carbon_get_theme_option( 'check_btn_discont' );
@@ -117,4 +122,5 @@ $check_btn_discont = carbon_get_theme_option( 'check_btn_discont' );
-
\ No newline at end of file + + \ No newline at end of file diff --git a/wp-content/themes/dekart/template-parts/reviews.php b/wp-content/themes/dekart/template-parts/reviews.php index afc1cfc..66c53a1 100644 --- a/wp-content/themes/dekart/template-parts/reviews.php +++ b/wp-content/themes/dekart/template-parts/reviews.php @@ -131,6 +131,9 @@ if ($the_query->have_posts()) :
+