Test commit from debug
This commit is contained in:
parent
c7bd6cef74
commit
80f259cbee
10
.gitignore
vendored
10
.gitignore
vendored
@ -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
|
||||
|
||||
45
AGENTS.md
45
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.
|
||||
|
||||
@ -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" }
|
||||
}
|
||||
}
|
||||
0
wp-content/mu-plugins/acf-loader.php
Executable file → Normal file
0
wp-content/mu-plugins/acf-loader.php
Executable file → Normal file
56
wp-content/themes/dekart/assets/css/front-page.css
Normal file
56
wp-content/themes/dekart/assets/css/front-page.css
Normal file
@ -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);
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
2988
wp-content/themes/dekart/assets/css/podgotovka-k-shkole.css
Normal file
2988
wp-content/themes/dekart/assets/css/podgotovka-k-shkole.css
Normal file
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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');
|
||||
})
|
||||
})
|
||||
|
||||
/* ── 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');
|
||||
}
|
||||
});
|
||||
});
|
||||
45
wp-content/themes/dekart/assets/js/front-page.js
Normal file
45
wp-content/themes/dekart/assets/js/front-page.js
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* front-page.js — обработчики для шаблона front-page.php
|
||||
* Извлечены из inline <script> в отдельный файл
|
||||
*/
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const tabs = document.querySelectorAll('.tab-clicked');
|
||||
if (!tabs.length) return;
|
||||
|
||||
tabs.forEach(function (tab) {
|
||||
tab.addEventListener('click', function (event) {
|
||||
const tabBtn = event.currentTarget;
|
||||
const tabsBlock = tabBtn.closest('[class*="tabs"]') || tabBtn.parentNode.parentNode.parentNode;
|
||||
const tabNum = tabBtn.parentNode.getAttribute('data-tab-btn');
|
||||
const content = tabsBlock.querySelector('.tabs-content');
|
||||
|
||||
if (!content || !tabNum) return;
|
||||
|
||||
// Анимация переключения табов
|
||||
content.style.opacity = '0';
|
||||
content.style.filter = 'blur(5px)';
|
||||
content.style.left = '-50%';
|
||||
|
||||
tabsBlock.querySelectorAll('.tab').forEach(function (t) {
|
||||
t.classList.remove('active');
|
||||
});
|
||||
const activeBtn = tabsBlock.querySelector('[data-tab-btn="' + tabNum + '"]');
|
||||
if (activeBtn) activeBtn.classList.add('active');
|
||||
|
||||
setTimeout(function () {
|
||||
content.style.opacity = '';
|
||||
content.style.filter = '';
|
||||
content.style.left = '';
|
||||
|
||||
tabsBlock.querySelectorAll('.page-tab').forEach(function (t, i) {
|
||||
if (i !== Number(tabNum) - 1) {
|
||||
t.classList.remove('active');
|
||||
} else {
|
||||
t.classList.add('active');
|
||||
}
|
||||
});
|
||||
}, 300);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -39,7 +39,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
// ───────────────────────────────────────────────
|
||||
document.querySelectorAll('.review-card__btn-more').forEach(function (btn) {
|
||||
btn.addEventListener('click', function () {
|
||||
const textBlock = this.parentNode.querySelector('.lw-card__text');
|
||||
const textBlock = this.closest('.lw-card').querySelector('.lw-card__text');
|
||||
if (textBlock) {
|
||||
textBlock.classList.toggle('review-card__text--expanded');
|
||||
this.textContent = textBlock.classList.contains('review-card__text--expanded')
|
||||
|
||||
171
wp-content/themes/dekart/deploy-runner.php
Normal file
171
wp-content/themes/dekart/deploy-runner.php
Normal file
@ -0,0 +1,171 @@
|
||||
<?php
|
||||
/**
|
||||
* Deploy Runner — HTTP-triggered migration executor
|
||||
* Usage: https://site.com/wp-content/themes/dekart/deploy-runner.php?migrate=003
|
||||
*
|
||||
* Self-destructs after execution (renames to .done).
|
||||
* Requires wp-config.php for DB credentials.
|
||||
*/
|
||||
|
||||
// Prevent WordPress from intercepting
|
||||
define('WP_USE_THEMES', false);
|
||||
|
||||
$allowed_migrations = ['003', '004'];
|
||||
|
||||
$migrate = isset($_GET['migrate']) ? $_GET['migrate'] : '';
|
||||
|
||||
if (!in_array($migrate, $allowed_migrations)) {
|
||||
header('Content-Type: text/plain');
|
||||
die("Usage: ?migrate=003 (allowed: " . implode(', ', $allowed_migrations) . ")\n");
|
||||
}
|
||||
|
||||
// Load WordPress config for DB credentials
|
||||
$wp_config_path = dirname(__FILE__) . '/../../../wp-config.php';
|
||||
if (!file_exists($wp_config_path)) {
|
||||
// Try parent directory
|
||||
$wp_config_path = dirname(__FILE__) . '/../../wp-config.php';
|
||||
}
|
||||
if (!file_exists($wp_config_path)) {
|
||||
$wp_config_path = dirname(__FILE__) . '/../wp-config.php';
|
||||
}
|
||||
|
||||
require_once $wp_config_path;
|
||||
|
||||
header('Content-Type: text/plain; charset=utf-8');
|
||||
echo "=== Deploy Runner: migration $migrate ===\n\n";
|
||||
|
||||
// ─── Shared helpers ──────────────────────────────────────────────────
|
||||
function dp_get_wpdb() {
|
||||
$conn = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
|
||||
if (!$conn) {
|
||||
die("DB connection failed: " . mysqli_connect_error() . "\n");
|
||||
}
|
||||
echo "Connected to DB: " . DB_NAME . "\n";
|
||||
return $conn;
|
||||
}
|
||||
|
||||
function dp_get_theme_dir() {
|
||||
// Our deploy-runner lives in the theme root
|
||||
$theme_dir = dirname(__FILE__);
|
||||
echo "Theme dir: {$theme_dir}\n";
|
||||
return $theme_dir;
|
||||
}
|
||||
|
||||
if ($migrate === '003') {
|
||||
// Fix banner_text typo: rарантированная → гарантированная
|
||||
$conn = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
|
||||
if (!$conn) {
|
||||
die("DB connection failed: " . mysqli_connect_error() . "\n");
|
||||
}
|
||||
echo "Connected to DB: " . DB_NAME . "\n\n";
|
||||
|
||||
$post_id = 2;
|
||||
$meta_keys = ['_banner_text', 'banner_text'];
|
||||
$fixed = 0;
|
||||
|
||||
foreach ($meta_keys as $meta_key) {
|
||||
$res = mysqli_query($conn,
|
||||
"SELECT meta_id, meta_value FROM wp_postmeta WHERE post_id = $post_id AND meta_key = '$meta_key'");
|
||||
|
||||
while ($row = mysqli_fetch_assoc($res)) {
|
||||
$old_val = $row['meta_value'];
|
||||
$new_val = str_replace('rарантированная', 'гарантированная', $old_val);
|
||||
$new_val = str_replace('rантированная', 'гантированная', $new_val);
|
||||
|
||||
if ($new_val !== $old_val) {
|
||||
$meta_id = (int)$row['meta_id'];
|
||||
$escaped = mysqli_real_escape_string($conn, $new_val);
|
||||
mysqli_query($conn,
|
||||
"UPDATE wp_postmeta SET meta_value = '$escaped' WHERE meta_id = $meta_id");
|
||||
echo "✅ FIXED meta_id=$meta_key key=$meta_key\n";
|
||||
echo " OLD: $old_val\n";
|
||||
echo " NEW: $new_val\n\n";
|
||||
$fixed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($fixed === 0) {
|
||||
echo "✅ Nothing to fix — typo already corrected\n";
|
||||
}
|
||||
|
||||
echo "\nTotal meta values updated: $fixed\n";
|
||||
mysqli_close($conn);
|
||||
}
|
||||
|
||||
if ($migrate === '004') {
|
||||
// ─── 004a: Remove post 740 (custom-css-js orphan) ───
|
||||
$conn = dp_get_wpdb();
|
||||
|
||||
$post_740 = mysqli_query($conn, "SELECT ID FROM wp_posts WHERE ID = 740 AND post_type = 'custom-css-js'");
|
||||
if (mysqli_num_rows($post_740) > 0) {
|
||||
// Hard-delete post + meta
|
||||
mysqli_query($conn, "DELETE FROM wp_posts WHERE ID = 740");
|
||||
mysqli_query($conn, "DELETE FROM wp_postmeta WHERE post_id = 740");
|
||||
echo "✅ DELETED post ID 740 (custom-css-js)\n";
|
||||
|
||||
// Remove physical file if exists
|
||||
$theme_dir = dp_get_theme_dir();
|
||||
$upload_dir = dirname(dirname($theme_dir)) . '/uploads';
|
||||
$files_to_check = [
|
||||
$upload_dir . '/custom-css-js/740.css',
|
||||
$upload_dir . '/custom-css-js/740.min.css',
|
||||
];
|
||||
foreach ($files_to_check as $file) {
|
||||
if (file_exists($file)) {
|
||||
unlink($file);
|
||||
echo "✅ DELETED file: {$file}\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
echo "ℹ️ Post ID 740 not found — already removed\n";
|
||||
}
|
||||
|
||||
// ─── 004b: Clean wp_custom_css option ───
|
||||
// We need wp-load.php for get_option/update_option
|
||||
$wp_load = dirname(__FILE__) . '/../../../wp-load.php';
|
||||
if (!file_exists($wp_load)) {
|
||||
$wp_load = dirname(__FILE__) . '/../../wp-load.php';
|
||||
}
|
||||
if (file_exists($wp_load)) {
|
||||
require_once $wp_load;
|
||||
echo "✅ Loaded WordPress\n";
|
||||
|
||||
$option_name = 'wp_custom_css';
|
||||
$current = get_option($option_name, '');
|
||||
if (!empty($current)) {
|
||||
$before = strlen($current);
|
||||
$cleaned = preg_replace('/\.(pksh|ms-|ms-text-)[^}]+}\s*/', '', $current);
|
||||
$cleaned = preg_replace('/\.(pksh|ms-|ms-text-)[^{]*\{\s*\}\s*/', '', $cleaned);
|
||||
$cleaned = trim($cleaned);
|
||||
$after = strlen($cleaned);
|
||||
$diff = $before - $after;
|
||||
|
||||
if ($diff > 0) {
|
||||
update_option($option_name, $cleaned);
|
||||
echo "✅ wp_custom_css: {$before} → {$after} chars (removed {$diff})\n";
|
||||
} else {
|
||||
echo "ℹ️ wp_custom_css unchanged ({$before} chars)\n";
|
||||
}
|
||||
} else {
|
||||
echo "ℹ️ wp_custom_css option is empty\n";
|
||||
}
|
||||
|
||||
if (function_exists('opcache_reset')) {
|
||||
opcache_reset();
|
||||
echo "✅ OPcache reset\n";
|
||||
}
|
||||
} else {
|
||||
echo "⚠️ wp-load.php not found — skipping wp_custom_css cleanup\n";
|
||||
}
|
||||
|
||||
mysqli_close($conn);
|
||||
}
|
||||
|
||||
echo "\n=== Migration complete ===\n";
|
||||
|
||||
// Self-destruct: rename this file
|
||||
$self = __FILE__;
|
||||
$done = $self . '.done';
|
||||
rename($self, $done);
|
||||
echo "Self-destruct: renamed to " . basename($done) . "\n";
|
||||
@ -19,10 +19,15 @@
|
||||
'theme_location' => 'top',
|
||||
) );
|
||||
?>
|
||||
<nav class="footer_links" aria-label="Дополнительные ссылки">
|
||||
<ul class="footer_links-col">
|
||||
<li><a href="/otzyvy/">Отзывы</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="footer__col">
|
||||
<button class="btn-write btn-lilac desktop"><?php esc_html_e('Записаться', 'dekart'); ?></button>
|
||||
<button class="btn-write btn-lilac mobile"><?php esc_html_e('Бесплатное занятие', 'dekart'); ?></button>
|
||||
<button class="btn-write btn-primary desktop"><?php esc_html_e('Бесплатное пробное', 'dekart'); ?></button>
|
||||
<button class="btn-write btn-primary mobile"><?php esc_html_e('Бесплатно', 'dekart'); ?></button>
|
||||
<div class="footer__link-icon">
|
||||
<img width="19" height="32"
|
||||
src="<?php echo esc_url( get_template_directory_uri() ); ?>/assets/images/icon-location.svg"
|
||||
@ -69,7 +74,20 @@
|
||||
alt="Закрыть"
|
||||
loading="lazy">
|
||||
</button>
|
||||
<?php echo carbon_get_theme_option('site_bitrix_script'); ?>
|
||||
<?php
|
||||
// Приоритет: page-specific meta > theme option
|
||||
$b24_script = '';
|
||||
if ( is_singular() ) {
|
||||
$page_script = carbon_get_post_meta( get_the_ID(), 'pksh_bitrix_script' );
|
||||
if ( ! empty( $page_script ) ) {
|
||||
$b24_script = $page_script;
|
||||
}
|
||||
}
|
||||
if ( empty( $b24_script ) ) {
|
||||
$b24_script = carbon_get_theme_option('site_bitrix_script');
|
||||
}
|
||||
echo $b24_script;
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -90,5 +108,24 @@ document.addEventListener("DOMContentLoaded", function() {
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- ✅ Sticky CTA Mobile -->
|
||||
<div class="sticky-cta-mobile" aria-hidden="true">
|
||||
<button class="sticky-cta-btn btn-write" aria-label="Записаться на бесплатное пробное">
|
||||
Записаться на бесплатное
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- ✅ Sticky CTA Desktop (появляется при скролле) -->
|
||||
<div class="sticky-cta-desktop" aria-hidden="true">
|
||||
<div class="sticky-cta-desktop__inner">
|
||||
<div class="sticky-cta-desktop__info">
|
||||
<span class="sticky-cta-desktop__badge">🎯 Подготовка к школе</span>
|
||||
<span class="sticky-cta-desktop__text">ул. Комсомольская, 11 — первое занятие <strong>бесплатно</strong></span>
|
||||
</div>
|
||||
<button class="sticky-cta-desktop__btn btn-write">Записаться на бесплатное пробное</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -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' ) ?: 'Декарт';
|
||||
?>
|
||||
<main class="main-page">
|
||||
|
||||
@ -61,14 +66,14 @@ $post_id = get_the_ID();
|
||||
<h2 class="page_h2">Наши услуги</h2>
|
||||
<div class="advantages__block-content">
|
||||
<div class="advantages__block-row">
|
||||
<div class="advantages__block-item" style="border:2px solid #A05A95">
|
||||
<div class="advantages__block-item advantages__block-item--school">
|
||||
<div class="advantages__block-item_title">Начальная школа</div>
|
||||
<p>Обучение ведётся по программе «Перспектива» и методике Занкова в соответствии с ФГОС, включая изучение английского языка с 1 класса.</p>
|
||||
<div class="advantages__block-item-img">
|
||||
<a href="/nachalnaya-shkola/">Узнать подробнее ></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="advantages__block-item" style="border:2px solid #F682A5">
|
||||
<div class="advantages__block-item advantages__block-item--preschool">
|
||||
<?php // ИСПРАВЛЕНО: была опечатка a/vantages__block-item_title ?>
|
||||
<div class="advantages__block-item_title">Подготовка к школе</div>
|
||||
<p>Программа для будущих первоклассников: развитие базовых навыков, логики и речи через игровые задания.</p>
|
||||
@ -76,7 +81,7 @@ $post_id = get_the_ID();
|
||||
<a href="/podgotovka-k-shkole/">Узнать подробнее ></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="advantages__block-item" style="border:2px solid #FEDF6F">
|
||||
<div class="advantages__block-item advantages__block-item--afterschool">
|
||||
<div class="advantages__block-item_title">Группы продлённого дня</div>
|
||||
<p>Помощь с домашними заданиями, творческие и развивающие занятия.</p>
|
||||
<div class="advantages__block-item-img">
|
||||
@ -85,21 +90,21 @@ $post_id = get_the_ID();
|
||||
</div>
|
||||
</div>
|
||||
<div class="advantages__block-row">
|
||||
<div class="advantages__block-item" style="border:2px solid #F9A474">
|
||||
<div class="advantages__block-item advantages__block-item--exam">
|
||||
<div class="advantages__block-item_title">Подготовка к экзаменам ОГЭ, ЕГЭ и ВПР</div>
|
||||
<p>Интенсивная подготовка к экзаменам ВПР, ОГЭ и ЕГЭ по всем предметам школьной программы.</p>
|
||||
<div class="advantages__block-item-img">
|
||||
<a href="https://schelkovo.dekart-school.ru/">Узнать подробнее ></a>
|
||||
<a href="<?php echo esc_url( home_url( '/' ) ); ?>">Узнать подробнее ></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="advantages__block-item" style="border:2px solid #C9DA8F">
|
||||
<div class="advantages__block-item advantages__block-item--camp">
|
||||
<div class="advantages__block-item_title">Летний городской лагерь</div>
|
||||
<p>Образование, творчество и наука в тематических сменах.</p>
|
||||
<div class="advantages__block-item-img">
|
||||
<a href="/gorodskoj-lager/">Узнать подробнее ></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="advantages__block-item" style="border:2px solid #B8CEDC">
|
||||
<div class="advantages__block-item advantages__block-item--clubs">
|
||||
<div class="advantages__block-item_title">Кружки и секции</div>
|
||||
<p>Творческие студии, спортивные секции и развивающие занятия для детей всех возрастов.</p>
|
||||
<div class="advantages__block-item-img"></div>
|
||||
@ -120,11 +125,11 @@ $post_id = get_the_ID();
|
||||
$block_text_1 = '<p>В нашей частной школе в Щелково мы знаем каждого ученика по имени. Небольшие классы до 12 человек, педагоги с опытом от 10 лет и углублённый английский с 1 класса. Работаем по программе «Перспектива» и методике Занкова. Принимаем детей из Щелково, Фрязино и Ивантеевки. Лицензия Министерства образования Московской области.</p>';
|
||||
}
|
||||
?>
|
||||
<section class="info__block" style="padding-bottom:0;margin-top:40px">
|
||||
<section class="info__block info__block--compact">
|
||||
<div class="container">
|
||||
<div class="info__block-wrapper">
|
||||
<div class="info__block-content">
|
||||
<div class="info__block-content_text" style="max-width:100%">
|
||||
<div class="info__block-content_text info__block-content_text--full">
|
||||
<?php echo wp_kses_post( $block_text_1 ); ?>
|
||||
</div>
|
||||
</div>
|
||||
@ -132,12 +137,22 @@ $post_id = get_the_ID();
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="cta-block" style="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">
|
||||
<section class="cta-block">
|
||||
<div class="container">
|
||||
<div class="cta-wrapper" style="max-width:900px;margin:0 auto">
|
||||
<h2 class="page_h2" style="margin-bottom:20px;line-height:1.3">Запишитесь на бесплатную экскурсию по школе и познакомьтесь с нашей программой!</h2>
|
||||
<p style="font-size:1.2rem;color:#444;margin-bottom:30px">Получите персональную консультацию и узнайте стоимость обучения прямо сейчас.</p>
|
||||
<button class="btn-write btn-lilac btn-page" style="margin:0 auto;display:block;padding:18px 45px;font-size:1.3rem;box-shadow:0 4px 15px rgba(160,90,149,.3)">Записаться на экскурсию</button>
|
||||
<div class="cta-wrapper">
|
||||
<h2 class="page_h2">Запишитесь на бесплатную экскурсию по школе и познакомьтесь с нашей программой!</h2>
|
||||
<p>Получите персональную консультацию и узнайте стоимость обучения прямо сейчас.</p>
|
||||
<button class="btn-write btn-lilac btn-page">Записаться на экскурсию</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ССЫЛКА НА СТРАНИЦУ ОТЗЫВОВ ДЛЯ УСИЛЕНИЯ ПЕРЕЛИНКОВКИ -->
|
||||
<section class="reviews-link-block">
|
||||
<div class="container">
|
||||
<div class="reviews-link-wrapper">
|
||||
<p>Узнайте, что говорят о нас родители и ученики →</p>
|
||||
<a href="/otzyvy/" class="btn-outline btn-page">Читать все отзывы</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@ -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": "<?php echo esc_attr( $branch_phone ?: '+79303334151' ); ?>",
|
||||
"email": "<?php echo esc_attr( $branch_email ?: 'shelkovo@dekart-school.ru' ); ?>",
|
||||
"contactType": "customer service",
|
||||
"areaServed": "RU",
|
||||
"availableLanguage": "Russian"
|
||||
@ -296,27 +311,7 @@ $post_id = get_the_ID();
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php
|
||||
?>
|
||||
<script>
|
||||
document.addEventListener('click', function(event) {
|
||||
if (!event.target.classList.contains('tab-clicked')) return;
|
||||
var tabsBlock = event.target.parentNode.parentNode.parentNode;
|
||||
var tabNum = event.target.parentNode.getAttribute('data-tab-btn');
|
||||
var content = tabsBlock.querySelector('.tabs-content');
|
||||
if (!content) return;
|
||||
content.style.cssText = 'opacity:0;filter:blur(5px);left:-50%';
|
||||
tabsBlock.querySelectorAll('.tab').forEach(function(t){ t.classList.remove('active'); });
|
||||
tabsBlock.querySelector('[data-tab-btn="' + tabNum + '"]').classList.add('active');
|
||||
setTimeout(function() {
|
||||
content.style.cssText = '';
|
||||
tabsBlock.querySelectorAll('.page-tab').forEach(function(t, i) {
|
||||
if (i !== Number(tabNum) - 1) t.classList.remove('active');
|
||||
else t.classList.add('active');
|
||||
});
|
||||
}, 300);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<?php get_template_part('template-parts/map'); ?>
|
||||
|
||||
|
||||
@ -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( '<p style="color: #64748b; font-size: 13px; margin: 0 0 12px;">Секция: <strong>.reviews-intro</strong> — SEO-текст в начале страницы. Управляется из админки, чтобы можно было править текст без редактирования шаблона.</p>' ),
|
||||
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 '<meta property="og:image" content="' . wp_get_attachment_url($snippet) . '" >' . "\n";
|
||||
if ( ! is_a( $term, 'WP_Term' ) || empty( $term->term_id ) ) {
|
||||
return;
|
||||
}
|
||||
$snippet = carbon_get_term_meta( $term->term_id, 'snippet' );
|
||||
if ( $snippet ) {
|
||||
echo '<meta property="og:image" content="' . esc_url( wp_get_attachment_url( $snippet ) ) . '" >' . "\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() {
|
||||
<label>Полное название организации</label>
|
||||
<input type="text" name="branch_name" value="<?php echo esc_attr( get_option( 'branch_name', 'Декарт' ) ); ?>">
|
||||
</div>
|
||||
<div class="branch-field">
|
||||
<label>OG: Site Name (для мета-тега og:site_name)</label>
|
||||
<input type="text" name="branch_og_site_name" value="<?php echo esc_attr( get_option( 'branch_og_site_name', 'Частная школа Декарт в Щёлково' ) ); ?>" style="width:100%;max-width:500px">
|
||||
<p class="desc">Значение тега <code>og:site_name</code> — отображается в сниппетах Яндекса и Google. Рекомендуется: «Частная школа Декарт в Щёлково». Если оставить пустым — будет использован заголовок сайта из настроек WordPress.</p>
|
||||
</div>
|
||||
<div class="branch-field">
|
||||
<label>Ценовой диапазон</label>
|
||||
<input type="text" name="branch_price_range" value="<?php echo esc_attr( get_option( 'branch_price_range', '$$' ) ); ?>">
|
||||
<p class="desc">Для микроразметки. Например: "$", "$$", "$$$".</p>
|
||||
</div>
|
||||
<div class="branch-field">
|
||||
<label>Средний рейтинг школы (для метрик)</label>
|
||||
<input type="text" name="branch_avg_rating" value="<?php echo esc_attr( get_option( 'branch_avg_rating', '4.9' ) ); ?>" style="width:100%;max-width:120px">
|
||||
<p class="desc">Отображается в блоке метрик на странице отзывов. Пример: 4.9</p>
|
||||
</div>
|
||||
<div class="branch-field">
|
||||
<label>Оставшиеся места (для триггера срочности)</label>
|
||||
<input type="number" name="branch_remaining_seats" value="<?php echo esc_attr( get_option( 'branch_remaining_seats', '12' ) ); ?>" style="width:100%;max-width:120px" min="0">
|
||||
<p class="desc">Отображается в финальном CTA на странице отзывов: «осталось N мест».</p>
|
||||
</div>
|
||||
<div class="branch-field">
|
||||
<label>Логотип организации (ID вложения)</label>
|
||||
<input type="number" name="branch_logo" value="<?php echo esc_attr( get_option( 'branch_logo', '' ) ); ?>" min="0" style="max-width:120px">
|
||||
<p class="desc">ID изображения из Медиафайлы. Для JSON-LD image.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="branch-section collapsed">
|
||||
<h2>⏰ РЕЖИМ РАБОТЫ</h2>
|
||||
<div class="branch-section-body">
|
||||
<div class="branch-field">
|
||||
<label>Режим работы школы</label>
|
||||
<input type="text" name="branch_hours" value="<?php echo esc_attr( get_option( 'branch_hours', 'ежедневно с 8:00 до 19:00, кроме воскресенья' ) ); ?>" style="width:100%;max-width:500px">
|
||||
<p class="desc">Текст с режимом работы. Появляется на странице отзывов после вступительного текста.</p>
|
||||
<label>Описание организации (для Schema.org)</label>
|
||||
<textarea name="branch_schema_description" rows="3" style="width:100%;max-width:500px"><?php echo esc_textarea( get_option( 'branch_schema_description', '' ) ); ?></textarea>
|
||||
<p class="desc">Появляется в сниппете Google и Яндекса как описание организации. Рекомендуется 1–2 предложения: тип школы, какие классы, особенности. Пример: «Частная школа полного дня в Щёлково. Обучение с 1 по 11 класс, подготовка к ЕГЭ и ОГЭ, индивидуальный подход.» Если пусто — собирается автоматически из названия и города филиала.</p>
|
||||
</div>
|
||||
<div class="branch-field">
|
||||
<label>Города присутствия (для Schema.org areaServed)</label>
|
||||
<input type="text" name="branch_area_served" value="<?php echo esc_attr( get_option( 'branch_area_served', 'Щёлково, Фрязино, Монино' ) ); ?>" style="width:100%;max-width:500px">
|
||||
<p class="desc">Города через запятую, где работает школа. Первым укажите город филиала. Влияет на локальный п | ||||