const EditorSlot = ({ path, type, required = false, hideable = false, as: As = "div", className = "", children, ...rest }) => ( {children} ); const Static = ({ as: As = "div", className = "", children, ...rest }) => ( {children} ); const IMAGE_ASSETS = { hero: { url: "https://picsum.photos/seed/rubezh-advisory-hero/1400/1050", alt: "Рабочее место финансового консультанта с документами и графиками", width: 1400, height: 1050, }, }; const StockImage = ({ image, alt, className = "", loading = "lazy" }) => ( {alt ); function useMagnetic(ref) { React.useEffect(() => { const el = ref.current; if (!el || window.matchMedia("(prefers-reduced-motion: reduce)").matches) return undefined; const onMove = (e) => { const rect = el.getBoundingClientRect(); const x = e.clientX - rect.left - rect.width / 2; const y = e.clientY - rect.top - rect.height / 2; el.style.transform = `translate(${x * 0.12}px, ${y * 0.12}px)`; }; const onLeave = () => { el.style.transform = "translate(0, 0)"; }; el.addEventListener("mousemove", onMove); el.addEventListener("mouseleave", onLeave); return () => { el.removeEventListener("mousemove", onMove); el.removeEventListener("mouseleave", onLeave); }; }, [ref]); } function useCounter(target, active, duration = 1400) { const [value, setValue] = React.useState(0); React.useEffect(() => { if (!active) return undefined; const numeric = parseFloat(String(target).replace(/[^\d.]/g, "")); if (Number.isNaN(numeric)) return undefined; let start = null; let raf; const step = (ts) => { if (!start) start = ts; const p = Math.min((ts - start) / duration, 1); const eased = 1 - Math.pow(1 - p, 3); setValue(Math.round(numeric * eased)); if (p < 1) raf = requestAnimationFrame(step); }; raf = requestAnimationFrame(step); return () => cancelAnimationFrame(raf); }, [target, active, duration]); return value; } function useTypewriter(phrases, interval = 3200) { const [idx, setIdx] = React.useState(0); const [text, setText] = React.useState(""); const [phase, setPhase] = React.useState("typing"); React.useEffect(() => { if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) { setText(phrases[0]); return undefined; } const phrase = phrases[idx]; let timer; if (phase === "typing") { if (text.length < phrase.length) { timer = setTimeout(() => setText(phrase.slice(0, text.length + 1)), 42); } else { timer = setTimeout(() => setPhase("pause"), 900); } } else if (phase === "pause") { timer = setTimeout(() => setPhase("deleting"), 400); } else { if (text.length > 0) { timer = setTimeout(() => setText(text.slice(0, -1)), 24); } else { setIdx((i) => (i + 1) % phrases.length); setPhase("typing"); } } return () => clearTimeout(timer); }, [text, phase, idx, phrases]); return text; } const IconChart = () => ( ); const IconShield = () => ( ); const IconCheck = () => ( ); const IconChevronDown = () => ( ); const IconQuote = () => ( ); const IconArrow = () => ( ); // Header is a controlled chrome block (TASK-013 / ADR-005), data-driven from // window.LP_CHROME.header with data-header-* hooks for live editor overlay. const HEADER_DEFAULTS = { sticky: true, variant: "split", logo: { mode: "text", text: "Рубеж Advisory", imageUrl: "", imageAlt: "Логотип", height: 28 }, links: [ { label: "Услуги", href: "#features" }, { label: "Кому", href: "#use_cases" }, { label: "Кейсы", href: "#case_studies" }, { label: "FAQ", href: "#faq" }, ], cta: { enabled: true, label: "Консультация", href: "#lead_form" }, }; function Nav() { const raw = (typeof window !== "undefined" && window.LP_CHROME && window.LP_CHROME.header) || {}; const cfg = { ...HEADER_DEFAULTS, ...raw }; const logo = { ...HEADER_DEFAULTS.logo, ...(raw.logo || {}) }; const cta = { ...HEADER_DEFAULTS.cta, ...(raw.cta || {}) }; const links = Array.isArray(raw.links) ? raw.links : HEADER_DEFAULTS.links; const navClass = "site-nav site-nav--" + (cfg.variant || "split") + (cfg.sticky ? " site-nav--sticky" : ""); return ( ); } // Footer is a regular editable section (TASK-013) with section id + EditorSlot fields. function FooterSection() { return ( ); } function HeroSection() { const magneticRef = React.useRef(null); useMagnetic(magneticRef); const badges = [ "18 лет практики", "CFA · ACCA", "152-ФЗ · NDA", "Ответ за 24 ч", ]; return (
); } function ProblemSection() { const items = [ "Доход растёт, а структура активов не успевает — решения принимаются на эмоциях, не по стратегии", "Налоги съедают маржу: ИП, дивиденды и зарплата не оптимизированы под ваш статус резидента", "Бизнес и личные финансы переплетены — риски для семьи и компании не разделены юридически", "Банковский менеджер предлагает продукты банка, а не независимую стратегию под ваши цели", ]; return (
Когда капитал растёт быстрее, чем система
{items.map((quote, i) => (
{quote}
))}
На диагностике разберём вашу ситуацию и покажем, где теряются деньги — без продажи банковских продуктов и скрытых комиссий. Записаться на диагностику
); } function BenefitsSection() { const items = [ { title: "Стратегия портфеля", desc: "Аллокация под горизонт, риск-профиль и валютные цели — без шаблонных схем" }, { title: "Налоговая архитектура", desc: "Легальная оптимизация для ИП, ООО, самозанятых и частных инвесторов" }, { title: "Защита капитала", desc: "Разделение активов, страхование рисков, резервный фонд на 12–18 месяцев" }, { title: "Roadmap на год", desc: "Конкретные шаги после первой встречи — с датами, суммами и ответственными" }, ]; return (
Что меняется после работы с экспертом Не готовые схемы — решения под ваш доход, статус и цели семьи
{items.map((item, i) => (
{item.title} {item.desc}
))}
); } function FeaturesSection() { const prompts = [ "Оптимизировать налоги при дивидендах ИП…", "Собрать портфель на 15 млн с валютой 40%…", "Разделить активы бизнеса и семьи…", ]; const typed = useTypewriter(prompts); const features = [ { title: "Диагностика 360°", body: "Аудит активов, налогов, страховок и долговых обязательств за одну сессию" }, { title: "Налоговый календарь", body: "Напоминания о сроках, оптимальные даты выплат и отчётности" }, { title: "Инвестиционный комитет", body: "Ежеквартальный разбор портфеля с фиксацией решений в протоколе" }, { title: "Конфиденциальный vault", body: "Документы и расчёты хранятся на серверах в РФ, доступ по NDA" }, ]; return (
Компетенции Инструменты независимого советника
Всё, что нужно для управления капиталом — без привязки к продуктам одного банка

Запрос клиента

{typed}
{features.map((f, i) => (
{f.title} {f.body}
))}
); } function UseCasesSection() { const cases = [ { segment: "Предприниматели", title: "IT и сервисный бизнес", desc: "Дивиденды, зарплата, ИИС и валютная подушка при доходе 2–8 млн/мес" }, { segment: "Инвесторы", title: "Частный капитал 15–80 млн", desc: "Ребалансировка, снижение комиссий, план пассивного дохода" }, { segment: "Самозанятые", title: "Эксперты и консультанты", desc: "Переход между режимами, накопления, страхование дохода" }, { segment: "Семьи", title: "Совместные активы", desc: "Наследование, трасты, разделение рисков между супругами" }, ]; return (
Кому подходит формат Работаем с клиентами, у которых финансовые решения влияют на бизнес и семью
{cases.map((c, i) => (
{c.segment} {c.title} {c.desc} Обсудить задачу
))}
); } function ProcessSection() { const steps = [ { label: "Шаг 1", time: "45 мин", title: "Диагностика", body: "Разбираем цели, активы, налоги. Вы получаете 3–5 приоритетных шагов." }, { label: "Шаг 2", time: "5–7 дней", title: "Стратегия", body: "Готовим roadmap: аллокация, налоговая схема, календарь действий." }, { label: "Шаг 3", time: "ежемесячно", title: "Сопровождение", body: "Контроль исполнения, корректировки при изменении законов и рынка." }, { label: "Шаг 4", time: "ежеквартально", title: "Комитет", body: "Сводный отчёт, ребалансировка, фиксация решений в протоколе." }, ]; return (
Как мы работаем Путь от хаоса к системе
    {steps.map((step, i) => (
  1. {i + 1}
    {step.label} {step.time}
    {step.title} {step.body}
  2. ))}
); } function TrustSection() { const ref = React.useRef(null); const [active, setActive] = React.useState(false); React.useEffect(() => { const el = ref.current; if (!el) return undefined; const io = new IntersectionObserver(([entry]) => { if (entry.isIntersecting) { setActive(true); io.disconnect(); } }, { threshold: 0.3 }); io.observe(el); return () => io.disconnect(); }, []); const c0 = useCounter(18, active); const c1 = useCounter(412, active); const stats = [ { value: `${c0}+`, raw: "18+", label: "лет практики" }, { value: `${c1}+`, raw: "412+", label: "клиентов" }, { value: "₽3,4 млрд", raw: "₽3,4 млрд", label: "активов под сопровождением", noAnim: true }, ]; const creds = [ "CFA Charterholder · ACCA · член СРО", "Бывший директор private banking в топ-5 банке РФ", "Публикации в РБК, Forbes Russia, Коммерсантъ", "152-ФЗ · NDA · данные только в РФ", ]; return (
Цифры, которые можно проверить
{stats.map((s, i) => (
{s.noAnim ? s.raw : s.value} {s.label}
))}
{creds.map((label, i) => (
{label}
))}
); } function CaseStudiesSection() { const cases = [ { tag: "Предприниматель · e-commerce · 4,2 млн/мес", problem: "Дивиденды и зарплата смешаны, налог 27%+. Портфель в рублях без валютной диверсификации.", solution: "Реструктурировали выплаты, выстроили ИИС и брокерский счёт, добавили 32% в валютные ETF.", results: ["Налоговая нагрузка -5,2 п.п. легально", "Валютная подушка на 16 месяцев", "Единый dashboard бизнес + личное"], quote: "«Наконец понимаю, сколько могу инвестировать без риска для операционки.»", speaker: "Дмитрий Воронцов, основатель маркетплейса", }, { tag: "Инвестор · 52 года · капитал 38 млн ₽", problem: "23 инструмента без стратегии, комиссии брокеров, страх не успеть выйти на пенсию.", solution: "Сократили до 9 позиций, настроили ребалансировку, план пассивного дохода к 57 годам.", results: ["Комиссии -37%", "Целевая доходность 11,4% с контролируемым риском", "План cash-flow на 20 лет"], quote: "«Перестал проверять котировки каждый день — есть план и ответственный эксперт.»", speaker: "Елена Миронова, директор по развитию", }, ]; return (
Результаты клиентов
{cases.map((c, i) => (
{c.tag}

Задача

{c.problem}

Решение

{c.solution}
    {c.results.map((r, ri) => (
  • {r}
  • ))}
{c.quote} {c.speaker}
Обсудить похожий кейс
))}
); } function PricingSection() { const plans = [ { name: "Диагностика", price: "0 ₽", period: "45 минут", desc: "Разбор ситуации и 3–5 приоритетных шагов", features: ["Аудит активов и налогов", "PDF с рекомендациями", "Без обязательств"], featured: false, cta: "Записаться бесплатно", }, { name: "Сопровождение", price: "от 95 000 ₽", period: "/ месяц", desc: "Персональный roadmap и ежемесячный контроль", features: ["Стратегия портфеля", "Налоговый календарь", "Чат с экспертом", "Квартальный комитет"], featured: true, cta: "Обсудить формат", }, { name: "Private Office", price: "индивидуально", period: "", desc: "Семейный офис: активы от 100 млн ₽", features: ["Выделенный советник", "Юридическое сопровождение", "Наследственное планирование", "24/7 приоритет"], featured: false, cta: "Запросить встречу", }, ]; return (
Форматы Прозрачные форматы работы Стоимость сопровождения зависит от объёма активов — обсудим после диагностики
{plans.map((plan, i) => (
{plan.featured && Популярный} {plan.name} {plan.desc}
{plan.price} {plan.period}
    {plan.features.map((f, fi) => (
  • {f}
  • ))}
{plan.cta}
))}
); } function FaqSection() { const [openIdx, setOpenIdx] = React.useState(0); const toggle = (i) => setOpenIdx((prev) => (prev === i ? -1 : i)); const items = [ { q: "Сколько стоит консультация?", a: "Первая диагностика 45 минут — бесплатно. Сопровождение обсуждается после разбора ситуации. Цена зависит от объёма активов — без скрытых комиссий от банков." }, { q: "Вы управляете моими деньгами?", a: "Нет. Мы консультируем и сопровождаем решения — счета остаются у вас у брокера или банка. Не принимаем деньги на свой счёт." }, { q: "Это инвестиционная рекомендация?", a: "Материалы носят информационный характер. Персональные рекомендации — только после KYC и договора. Доходность в прошлом не гарантирует будущую." }, { q: "Как проходит первая встреча?", a: "45 минут онлайн или очно: цели, активы, налоги. Вы получаете 3–5 приоритетных шагов. Если формат подходит — предложим план сопровождения." }, { q: "Что в чек-листе?", a: "PDF «12 ошибок частного инвестора в 2025»: налоги, валюта, страхование, структура портфеля. Отправим на email после заявки." }, { q: "Работаете с иностранными активами?", a: "Да — учитываем валютный контроль, CRS и санкционные ограничения. Структурируем решения под резидентство РФ." }, ]; return (
Частые вопросы
{items.map((item, i) => { const isOpen = openIdx === i; return (
{item.a}
); })}
); } function CtaSection() { return (
); } function LeadFormSection() { const [state, setState] = React.useState("idle"); const [values, setValues] = React.useState({ name: "", phone: "", email: "" }); const [errors, setErrors] = React.useState({}); const validate = () => { const e = {}; if (!values.name.trim()) e.name = "Укажите ваше имя"; if (!values.phone.trim()) e.phone = "Введите номер телефона"; if (!values.email.trim()) e.email = "Укажите email для чек-листа"; return e; }; const handleChange = (field) => (ev) => { setValues((v) => ({ ...v, [field]: ev.target.value })); if (errors[field]) setErrors((err) => ({ ...err, [field]: "" })); }; const handleSubmit = (ev) => { ev.preventDefault(); const e = validate(); if (Object.keys(e).length) { setErrors(e); return; } setState("loading"); setTimeout(() => setState("success"), 1200); }; return (
Конфиденциальная заявка Оставьте контакты — пришлём чек-лист и предложим время диагностики в течение 24 часов.
  • 152-ФЗ · данные в РФ
  • NDA по запросу
  • Без спама и рассылок
{state === "success" ? (
Заявка принята Мы свяжемся в течение 24 часов. Чек-лист отправим на указанный email.
) : (
Запись на консультацию
Имя {errors.name && {errors.name}}
Телефон {errors.phone && {errors.phone}}
Email {errors.email && {errors.email}}
45 минут · Конфиденциально · Без обязательств Ответим в течение 24 часов в рабочие дни

Нажимая кнопку, вы соглашаетесь с политикой обработки данных

)}
); } Object.assign(window, { Nav, FooterSection, HeroSection, ProblemSection, BenefitsSection, FeaturesSection, UseCasesSection, ProcessSection, TrustSection, CaseStudiesSection, PricingSection, FaqSection, CtaSection, LeadFormSection, EditorSlot, });