Files
roi24/index_ibm.html
T

1301 lines
56 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="ru" data-theme="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ROI24 — Данные. Без шума.</title>
<meta name="description" content="Один дашборд. Все ключевые цифры. Подключаем 1С, CRM, банки и рекламу.">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
/* ============================================================
IBM DESIGN LANGUAGE — LIGHT & DARK THEMES
Carbon Design System principles: clarity, consistency, motion
============================================================ */
/* ── DARK THEME (default) ── */
[data-theme="dark"] {
--bg: #050507;
--surface: #0c0c0f;
--card: #111115;
--text: #f0f0f2;
--text-sec: #71717a;
--text-dim: #3f3f46;
--border: rgba(255,255,255,0.08);
--border-strong: rgba(255,255,255,0.16);
--accent: #22c55e;
--accent-dim: rgba(34,197,94,0.08);
--accent-glow: rgba(34,197,94,0.25);
--blue: #3b82f6;
--blue-dim: rgba(59,130,246,0.08);
--amber: #f59e0b;
--amber-dim: rgba(245,158,11,0.08);
--red: #ef4444;
--red-dim: rgba(239,68,68,0.08);
--grid-opacity: 0.025;
--shadow-card: none;
--shadow-card-hover: none;
--dash-shadow: none;
--dash-glow-opacity: 0.06;
--nav-glass: rgba(5,5,7,0.7);
--nav-scrolled: rgba(5,5,7,0.92);
}
/* ── LIGHT THEME (IBM Carbon light mode) ── */
[data-theme="light"] {
--bg: #f4f4f4;
--surface: #ffffff;
--card: #fafafa;
--text: #161616;
--text-sec: #5b5b5b;
--text-dim: #8d8d8d;
--border: rgba(0,0,0,0.08);
--border-strong: rgba(0,0,0,0.16);
--accent: #0f62fe;
--accent-dim: rgba(15,98,254,0.06);
--accent-glow: rgba(15,98,254,0.15);
--blue: #0052cc;
--blue-dim: rgba(0,82,204,0.06);
--amber: #f7b32c;
--amber-dim: rgba(247,179,44,0.06);
--red: #da1e28;
--red-dim: rgba(218,30,40,0.06);
--grid-opacity: 0.03;
--shadow-card: 0 2px 8px rgba(0,0,0,0.06), 0 0 1px rgba(0,0,0,0.12);
--shadow-card-hover: 0 4px 16px rgba(0,0,0,0.08), 0 0 1px rgba(0,0,0,0.16);
--dash-shadow: 0 8px 32px rgba(0,0,0,0.08), 0 0 1px rgba(0,0,0,0.12);
--dash-glow-opacity: 0;
--nav-glass: rgba(244,244,244,0.85);
--nav-scrolled: rgba(255,255,255,0.95);
}
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
background: var(--bg); color: var(--text); font-family: var(--font);
line-height: 1.5; overflow-x: hidden;
-webkit-font-smoothing: antialiased;
transition: background 0.5s var(--ease-out), color 0.5s var(--ease-out);
}
:root {
--font: 'IBM Plex Sans', -apple-system, 'Segoe UI', sans-serif;
--mono: 'IBM Plex Mono', 'SF Mono', monospace;
--grid: 8px;
--ease-out: cubic-bezier(0.22, 1, 0.36, 1);
}
/* ── BACKGROUND — grid + ambient gradient ── */
body::before {
content: ''; position: fixed; inset: 0; z-index: 0;
pointer-events: none;
background-image:
linear-gradient(rgba(255,255,255,var(--grid-opacity)) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,255,255,var(--grid-opacity)) 1px, transparent 1px);
background-size: calc(var(--grid) * 12) calc(var(--grid) * 12);
}
[data-theme="dark"] body::before {
background-image:
linear-gradient(rgba(255,255,255,var(--grid-opacity)) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,255,255,var(--grid-opacity)) 1px, transparent 1px);
}
[data-theme="light"] body::before {
background-image:
linear-gradient(rgba(0,0,0,0.04) 1px, transparent 1px),
linear-gradient(90deg, rgba(0,0,0,0.04) 1px, transparent 1px);
}
body::after {
content: ''; position: fixed; inset: 0; z-index: -1;
pointer-events: none;
background:
radial-gradient(ellipse 60% 40% at 50% 20%, rgba(34,197,94,0.04) 0%, transparent 100%),
radial-gradient(ellipse 40% 30% at 80% 70%, rgba(59,130,246,0.03) 0%, transparent 100%);
}
[data-theme="light"] body::after {
background:
radial-gradient(ellipse 60% 40% at 30% 10%, rgba(15,98,254,0.03) 0%, transparent 100%),
radial-gradient(ellipse 40% 30% at 70% 80%, rgba(247,179,44,0.02) 0%, transparent 100%);
}
a { text-decoration: none; color: inherit; }
img { max-width: 100%; display: block; }
ul { list-style: none; }
/* ── LAYOUT ── */
.wrap {
max-width: 1280px; margin: 0 auto; padding: 0 32px;
}
section { padding: 120px 0; position: relative; z-index: 1; }
.section-label {
font-size: 0.6875rem; text-transform: uppercase;
letter-spacing: 0.18em; color: var(--accent);
margin-bottom: 16px; font-weight: 600;
font-family: 'IBM Plex Mono', 'SF Mono', monospace;
display: inline-flex; align-items: center; gap: 10px;
}
.section-label::after {
content: ''; flex: 0 0 auto; width: 24px; height: 1px;
background: var(--accent); opacity: 0.5;
}
.section-title {
font-size: clamp(1.75rem, 3vw, 2.5rem); font-weight: 700;
letter-spacing: -0.03em; line-height: 1.15; margin-bottom: 16px;
}
/* ── HEADER ── */
.header {
position: fixed; top: 0; left: 0; right: 0; z-index: 100;
height: 64px; display: flex; align-items: center;
background: var(--nav-glass); backdrop-filter: blur(24px) saturate(180%);
border-bottom: 1px solid transparent;
transition: all 0.4s var(--ease-out);
}
.header.scrolled {
background: var(--nav-scrolled);
border-bottom-color: var(--border);
}
[data-theme="light"] .header.scrolled {
box-shadow: 0 1px 4px rgba(0,0,0,0.06);
}
.header .wrap {
display: flex; align-items: center; justify-content: space-between; width: 100%;
}
.logo {
font-size: 1.125rem; font-weight: 700; letter-spacing: -0.03em;
display: flex; align-items: center; gap: 10px;
}
.logo-mark {
width: 32px; height: 32px; border-radius: 6px;
background: var(--accent); display: flex; align-items: center;
justify-content: center; font-family: 'IBM Plex Mono', 'SF Mono', monospace;
font-size: 0.8125rem; font-weight: 700; color: #fff;
transition: transform 0.3s var(--ease-out);
}
[data-theme="dark"] .logo-mark { color: #000; }
.logo:hover .logo-mark { transform: rotate(-6deg) scale(1.05); }
.nav { display: flex; align-items: center; gap: 40px; }
.nav a {
font-size: 0.8125rem; color: var(--text-sec);
transition: color 0.2s; letter-spacing: 0.01em; position: relative;
}
.nav a::after {
content: ''; position: absolute; bottom: -4px; left: 0; width: 0;
height: 1px; background: var(--accent); transition: width 0.3s var(--ease-out);
}
.nav a:hover { color: var(--text); }
.nav a:hover::after { width: 100%; }
.header-actions { display: flex; align-items: center; gap: 16px; }
.header-phone {
font-size: 0.8125rem; color: var(--text-sec); font-family: 'IBM Plex Mono', 'SF Mono', monospace;
transition: color 0.2s;
}
.header-phone:hover { color: var(--text); }
/* Theme toggle */
.theme-toggle {
width: 40px; height: 40px; border-radius: 8px; border: 1px solid var(--border);
background: transparent; cursor: pointer; display: flex; align-items: center;
justify-content: center; color: var(--text-sec); transition: all 0.3s var(--ease-out);
flex-shrink: 0;
}
.theme-toggle:hover {
background: var(--accent-dim); color: var(--accent);
border-color: var(--accent);
}
.theme-toggle svg { width: 18px; height: 18px; }
.theme-toggle .icon-sun { display: none; }
.theme-toggle .icon-moon { display: block; }
[data-theme="light"] .theme-toggle .icon-sun { display: block; }
[data-theme="light"] .theme-toggle .icon-moon { display: none; }
/* Buttons */
.btn {
display: inline-flex; align-items: center; justify-content: center;
gap: 8px; padding: 10px 20px; border-radius: 4px;
font-weight: 600; font-size: 0.8125rem; cursor: pointer;
border: none; transition: all 0.3s var(--ease-out);
letter-spacing: 0.01em; position: relative; overflow: hidden;
}
.btn::before {
content: ''; position: absolute; inset: 0;
background: linear-gradient(135deg, rgba(255,255,255,0.1) 0%, transparent 50%);
opacity: 0; transition: opacity 0.3s;
}
.btn:hover::before { opacity: 1; }
.btn-accent {
background: var(--accent); color: #000; font-family: 'IBM Plex Mono', 'SF Mono', monospace;
}
[data-theme="light"] .btn-accent { color: #fff; }
.btn-accent:hover { background: #16a34a; transform: translateY(-1px); box-shadow: 0 8px 24px var(--accent-dim); }
.btn-outline {
background: transparent; border: 1px solid var(--border-strong);
color: var(--text);
}
.btn-outline:hover { border-color: var(--text); background: rgba(128,128,128,0.05); }
.btn-lg { padding: 14px 28px; font-size: 0.875rem; }
/* ── HERO ── */
.hero {
padding: 160px 0 80px; min-height: 90vh;
display: flex; align-items: center;
border-bottom: 1px solid var(--border);
position: relative; overflow: hidden;
}
.hero-inner {
display: grid; grid-template-columns: 1fr 1fr; gap: 80px;
align-items: start;
}
.hero-left { padding-top: 20px; }
.hero-label {
font-size: 0.6875rem; text-transform: uppercase;
letter-spacing: 0.2em; color: var(--accent);
margin-bottom: 24px; font-family: 'IBM Plex Mono', 'SF Mono', monospace;
display: flex; align-items: center; gap: 8px;
}
.hero-label::before {
content: ''; width: 16px; height: 1px; background: var(--accent);
}
h1 {
font-size: clamp(3rem, 6vw, 5rem); font-weight: 700;
letter-spacing: -0.04em; line-height: 0.95; margin-bottom: 24px;
}
h1 .accent { color: var(--accent); }
.hero-sub {
font-size: 1.125rem; color: var(--text-sec);
margin-bottom: 40px; max-width: 440px; line-height: 1.65;
}
.hero-actions { display: flex; gap: 12px; flex-wrap: wrap; }
.hero-meta {
margin-top: 48px; padding-top: 32px;
border-top: 1px solid var(--border);
display: flex; gap: 48px;
}
.hero-meta-item {
display: flex; flex-direction: column; gap: 4px;
}
.hero-meta-value {
font-size: 1.75rem; font-weight: 700; font-family: 'IBM Plex Mono', 'SF Mono', monospace;
letter-spacing: -0.03em;
}
.hero-meta-label {
font-size: 0.75rem; color: var(--text-dim);
text-transform: uppercase; letter-spacing: 0.08em;
}
/* ── DASHBOARD PANEL ── */
.hero-right {
border: 1px solid var(--border);
background: var(--surface);
position: relative;
animation: dashFloat 6s ease-in-out infinite;
box-shadow: var(--dash-shadow);
transition: background 0.5s var(--ease-out), box-shadow 0.5s var(--ease-out);
}
@keyframes dashFloat {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-6px); }
}
.dash-glow {
position: absolute; top: -40%; left: -20%; width: 140%; height: 140%;
background: radial-gradient(circle, var(--accent), transparent 50%);
pointer-events: none; opacity: var(--dash-glow-opacity);
transition: opacity 0.6s var(--ease-out);
filter: blur(60px);
}
.hero-right:hover .dash-glow { opacity: calc(var(--dash-glow-opacity) * 2.5); }
.dash-header {
display: flex; align-items: center; justify-content: space-between;
padding: 16px 24px; border-bottom: 1px solid var(--border);
position: relative; z-index: 1;
}
.dash-brand {
font-size: 0.75rem; font-weight: 500; font-family: 'IBM Plex Mono', 'SF Mono', monospace;
letter-spacing: 0.05em; display: flex; align-items: center; gap: 8px;
}
.dash-brand svg { flex-shrink: 0; }
.dash-status {
display: flex; align-items: center; gap: 6px;
font-size: 0.6875rem; color: var(--accent); font-family: 'IBM Plex Mono', 'SF Mono', monospace;
}
.dash-dot {
width: 6px; height: 6px; background: var(--accent);
border-radius: 50%; animation: pulse 2s infinite;
}
@keyframes pulse {
0%,100% { opacity:1; box-shadow: 0 0 0 0 var(--accent-glow); }
50% { opacity:0.3; box-shadow: 0 0 0 4px transparent; }
}
.dash-body { display: grid; position: relative; z-index: 1; }
.dash-big {
grid-column: 1 / -1; padding: 40px 24px;
border-bottom: 1px solid var(--border); text-align: right;
}
.dash-big-label {
font-size: 0.6875rem; color: var(--text-dim);
text-transform: uppercase; letter-spacing: 0.12em;
margin-bottom: 8px; font-family: 'IBM Plex Mono', 'SF Mono', monospace;
}
.dash-big-value {
font-size: clamp(3rem, 5vw, 5rem); font-weight: 700;
font-family: 'IBM Plex Mono', 'SF Mono', monospace;
line-height: 1;
}
.dash-big-value .accent { color: var(--accent); }
.dash-big-trend {
display: inline-flex; align-items: center; gap: 6px;
margin-left: 16px; font-size: 0.875rem; color: var(--accent);
font-weight: 600;
}
.trend-icon { width: 14px; height: 14px; }
.dash-cell {
padding: 24px; border-bottom: 1px solid var(--border);
border-right: 1px solid var(--border);
}
.dash-cell:nth-child(2n) { border-right: none; }
.dash-cell-label {
font-size: 0.6875rem; color: var(--text-dim);
text-transform: uppercase; letter-spacing: 0.1em;
margin-bottom: 8px; font-family: 'IBM Plex Mono', 'SF Mono', monospace;
}
.dash-cell-value {
font-size: 1.5rem; font-weight: 600; font-family: 'IBM Plex Mono', 'SF Mono', monospace;
letter-spacing: -0.02em; margin-bottom: 4px;
transition: color 0.3s;
}
.dash-cell-sub {
font-size: 0.75rem; color: var(--text-sec);
transition: color 0.3s;
}
.dash-tri { display: grid; grid-template-columns: 1fr 1fr 1fr; }
.dash-mini {
padding: 20px; border-right: 1px solid var(--border); text-align: center;
}
.dash-mini:last-child { border-right: none; }
.dash-mini-label {
font-size: 0.625rem; color: var(--text-dim);
text-transform: uppercase; letter-spacing: 0.1em;
margin-bottom: 8px; font-family: 'IBM Plex Mono', 'SF Mono', monospace;
}
.dash-mini-value {
font-size: 1.25rem; font-weight: 600; font-family: 'IBM Plex Mono', 'SF Mono', monospace;
margin-bottom: 4px;
transition: color 0.4s var(--ease-out), transform 0.3s var(--ease-out);
}
.dash-mini-bar {
height: 3px; border-radius: 2px;
background: var(--border); overflow: hidden; margin-top: 8px;
}
.dash-mini-fill {
height: 100%; border-radius: 2px; background: var(--accent);
width: 0; transition: width 1.2s var(--ease-out), background 0.4s;
}
.dash-toggle { display: flex; border-top: 1px solid var(--border); }
.dash-toggle-btn {
flex: 1; padding: 10px; border: none; background: transparent;
font-size: 0.6875rem; color: var(--text-dim); cursor: pointer;
font-family: 'IBM Plex Mono', 'SF Mono', monospace; text-transform: uppercase;
letter-spacing: 0.08em; transition: all 0.3s var(--ease-out);
border-right: 1px solid var(--border); position: relative;
}
.dash-toggle-btn:last-child { border-right: none; }
.dash-toggle-btn::before {
content: ''; position: absolute; bottom: 0; left: 0; right: 0;
height: 2px; background: var(--accent);
transform: scaleX(0); transform-origin: center;
transition: transform 0.3s var(--ease-out);
}
.dash-toggle-btn.active, .dash-toggle-btn:hover {
background: var(--accent-dim); color: var(--accent);
}
.dash-toggle-btn.active::before, .dash-toggle-btn:hover::before {
transform: scaleX(1);
}
/* ── MANIFESTO ── */
.manifesto { padding: 160px 0; border-bottom: 1px solid var(--border); }
.manifesto-inner {
max-width: 1280px; margin: 0 auto; padding: 0 32px;
display: grid; grid-template-columns: 1fr 1fr; gap: 80px;
align-items: center;
}
.manifesto-number {
font-size: 8rem; font-weight: 700; font-family: 'IBM Plex Mono', 'SF Mono', monospace;
letter-spacing: -0.05em; line-height: 0.9;
color: var(--text-dim);
}
.manifesto-number .accent { color: var(--accent); }
.manifesto-content h2 {
font-size: clamp(2rem, 3.5vw, 3.5rem); font-weight: 700;
letter-spacing: -0.03em; line-height: 1.05; margin-bottom: 24px;
}
.manifesto-content p {
font-size: 1rem; color: var(--text-sec); line-height: 1.7;
margin-bottom: 16px; max-width: 480px;
}
/* ── PROBLEMS — horizontal row ── */
.problem-card {
padding: 40px 32px; border-right: 1px solid var(--border);
border-bottom: 1px solid var(--border);
position: relative; transition: all 0.4s var(--ease-out);
display: flex; gap: 32px; align-items: flex-start;
background: var(--surface);
}
.problem-card:nth-child(3n) { border-right: none; }
.problem-card:nth-last-child(-n+3) { border-bottom: none; }
.problem-card:hover {
background: var(--accent-dim);
}
.problem-icon {
flex-shrink: 0; width: 80px; height: 80px;
border: 1px solid rgba(239,68,68,0.15);
border-radius: 12px; display: flex; align-items: center;
justify-content: center; margin: 0;
color: var(--red); opacity: 0.7;
transition: all 0.4s var(--ease-out);
background: var(--red-dim);
}
[data-theme="light"] .problem-icon {
border-color: rgba(218,30,40,0.15);
}
.problem-card:hover .problem-icon {
opacity: 1; transform: scale(1.08);
box-shadow: 0 0 0 4px var(--red-dim);
}
.problem-icon svg { width: 36px; height: 36px; stroke-width: 1.2; }
.problem-body {
display: flex; flex-direction: column; gap: 12px;
}
.problem-num {
font-size: 0.6875rem; color: var(--text-dim);
font-family: 'IBM Plex Mono', 'SF Mono', monospace; letter-spacing: 0.05em;
}
.problem-card h3 {
font-size: 1.375rem; font-weight: 700; letter-spacing: -0.02em;
}
.problem-card p {
font-size: 0.9375rem; color: var(--text-sec); line-height: 1.6;
max-width: 400px;
}
/* ── SOLUTION ── */
.solution-section { border-bottom: 1px solid var(--border); }
.sol-card {
padding: 48px 32px; border-right: 1px solid var(--border);
border-bottom: 1px solid var(--border);
transition: all 0.4s var(--ease-out); position: relative;
background: var(--surface);
box-shadow: var(--shadow-card);
}
.sol-card:nth-child(3n) { border-right: none; }
.sol-card:nth-last-child(-n+3) { border-bottom: none; }
.sol-card:hover {
background: var(--accent-dim);
transform: translateY(-2px);
box-shadow: var(--shadow-card-hover);
}
.sol-icon {
width: 60px; height: 60px; border: 1px solid var(--accent);
border-radius: 12px; display: flex; align-items: center;
justify-content: center; margin-bottom: 24px;
transition: all 0.3s var(--ease-out);
}
.sol-card:hover .sol-icon {
transform: scale(1.05);
box-shadow: 0 0 0 4px var(--accent-dim);
}
.sol-card h3 {
font-size: 1.125rem; font-weight: 700; margin-bottom: 10px;
letter-spacing: -0.01em;
}
.sol-card p {
font-size: 0.875rem; color: var(--text-sec); line-height: 1.6;
}
/* ── COMPARISON TABLE ── */
.comparison { background: var(--surface); border-bottom: 1px solid var(--border); }
.comp-table {
width: 100%; border-collapse: collapse; font-size: 0.875rem;
}
.comp-table thead th {
text-align: left; padding: 20px 24px;
font-weight: 500; font-size: 0.6875rem;
color: var(--text-dim); text-transform: uppercase;
letter-spacing: 0.12em; border-bottom: 1px solid var(--border-strong);
}
.comp-table thead th:last-child { color: var(--accent); }
.comp-table tbody td {
padding: 18px 24px; border-bottom: 1px solid var(--border);
color: var(--text-sec); transition: background 0.2s;
}
.comp-table tbody tr:hover td { background: rgba(128,128,128,0.03); }
.comp-yes { color: var(--accent); font-weight: 600; }
.comp-no { color: var(--text-dim); }
/* ── HOW IT WORKS ── */
.steps { border-bottom: 1px solid var(--border); }
.steps-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 0; }
.step {
padding: 32px 24px; border-right: 1px solid var(--border);
position: relative; transition: all 0.3s var(--ease-out);
}
.step:last-child { border-right: none; }
.step:hover { background: var(--accent-dim); }
.step-num {
font-size: 2.5rem; font-weight: 700; font-family: 'IBM Plex Mono', 'SF Mono', monospace;
color: var(--accent); letter-spacing: -0.03em;
margin-bottom: 16px; line-height: 1; opacity: 0.6;
transition: opacity 0.3s;
}
.step:hover .step-num { opacity: 1; }
.step h3 { font-size: 1rem; font-weight: 700; margin-bottom: 6px; letter-spacing: -0.01em; }
.step p { font-size: 0.8125rem; color: var(--text-sec); line-height: 1.6; }
.step-time { font-size: 0.6875rem; color: var(--text-dim); font-family: 'IBM Plex Mono', 'SF Mono', monospace; margin-top: 12px; }
/* ── PRICING ── */
.pricing { border-bottom: 1px solid var(--border); }
.price-card {
max-width: 560px; margin: 0 auto;
border: 1px solid var(--border-strong); padding: 64px 48px;
text-align: center; position: relative;
transition: all 0.4s var(--ease-out);
background: var(--surface);
box-shadow: var(--shadow-card);
}
.price-card:hover {
border-color: var(--accent);
box-shadow: var(--shadow-card-hover);
transform: translateY(-4px);
}
.price-card::before {
content: ''; position: absolute; top: 0; left: 0; right: 0;
height: 2px; background: var(--accent);
}
.price-name {
font-size: 0.75rem; text-transform: uppercase;
letter-spacing: 0.15em; color: var(--text-dim);
font-family: 'IBM Plex Mono', 'SF Mono', monospace; margin-bottom: 24px;
}
.price-amount {
font-size: 4rem; font-weight: 700; font-family: 'IBM Plex Mono', 'SF Mono', monospace;
letter-spacing: -0.04em; margin-bottom: 8px;
transition: color 0.3s;
}
.price-amount .unit { font-size: 0.25em; color: var(--text-sec); font-weight: 400; }
.price-sub { font-size: 0.875rem; color: var(--text-sec); margin-bottom: 40px; }
.price-features { text-align: left; margin-bottom: 40px; }
.price-features li {
padding: 12px 0; border-bottom: 1px solid var(--border);
font-size: 0.875rem; color: var(--text-sec);
display: flex; align-items: flex-start; gap: 12px;
transition: color 0.2s;
}
.price-features li:hover { color: var(--text); }
.price-features li::before {
content: ''; display: inline-block; width: 16px; height: 16px;
flex-shrink: 0; margin-top: 2px;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 13.5l-5-5 1.4-1.4L6.5 10.7l5.6-5.6 1.4 1.4z' fill='%2322c55e'/%3E%3C/svg%3E");
background-size: contain; background-repeat: no-repeat;
}
.price-cta { margin-top: 8px; }
.price-guarantee {
margin-top: 24px; font-size: 0.75rem; color: var(--text-dim);
font-style: italic;
}
/* ── FAQ ── */
.faq-list { max-width: 800px; margin: 0 auto; }
.faq-item { border-bottom: 1px solid var(--border); }
.faq-q {
display: flex; align-items: center; justify-content: space-between;
padding: 24px 0; cursor: pointer; font-size: 1rem;
font-weight: 600; letter-spacing: -0.01em; transition: color 0.2s;
}
.faq-q:hover { color: var(--accent); }
.faq-q::after {
content: '+'; font-family: 'IBM Plex Mono', 'SF Mono', monospace; font-size: 1.25rem;
color: var(--text-dim); transition: transform 0.3s var(--ease-out);
flex-shrink: 0; margin-left: 16px;
}
.faq-item.open .faq-q::after { transform: rotate(45deg); }
.faq-a { max-height: 0; overflow: hidden; transition: max-height 0.5s var(--ease-out); }
.faq-item.open .faq-a { max-height: 400px; }
.faq-a-inner {
padding: 0 0 24px; font-size: 0.875rem; color: var(--text-sec);
line-height: 1.7;
}
/* ── FOOTER ── */
.footer {
padding: 64px 0; border-top: 1px solid var(--border);
font-size: 0.75rem; color: var(--text-dim);
}
.footer-inner {
display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; gap: 40px;
}
.footer-col h4 {
font-size: 0.6875rem; text-transform: uppercase;
letter-spacing: 0.12em; color: var(--text-sec);
margin-bottom: 16px; font-family: 'IBM Plex Mono', 'SF Mono', monospace;
}
.footer-col a, .footer-col p {
display: block; color: var(--text-dim);
margin-bottom: 8px; transition: color 0.2s;
}
.footer-col a:hover { color: var(--text); }
.footer-bottom {
margin-top: 48px; padding-top: 24px;
border-top: 1px solid var(--border);
display: flex; justify-content: space-between;
}
/* ── ANIMATIONS ── */
.reveal {
opacity: 0; transform: translateY(28px);
transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out);
}
.reveal.visible { opacity: 1; transform: translateY(0); }
.reveal-delay-1 { transition-delay: 0.1s; }
.reveal-delay-2 { transition-delay: 0.2s; }
.reveal-delay-3 { transition-delay: 0.3s; }
.reveal-delay-4 { transition-delay: 0.4s; }
.hero-left > * {
opacity: 0; transform: translateY(20px);
transition: opacity 0.6s var(--ease-out), transform 0.6s var(--ease-out);
}
.hero-left.loaded > * { opacity: 1; transform: translateY(0); }
.hero-left.loaded > *:nth-child(1) { transition-delay: 0.1s; }
.hero-left.loaded > *:nth-child(2) { transition-delay: 0.2s; }
.hero-left.loaded > *:nth-child(3) { transition-delay: 0.3s; }
.hero-left.loaded > *:nth-child(4) { transition-delay: 0.4s; }
.hero-left.loaded > *:nth-child(5) { transition-delay: 0.5s; }
.hero-left.loaded > *:nth-child(6) { transition-delay: 0.6s; }
.hero-right {
opacity: 0; transform: translateX(30px);
transition: opacity 0.8s var(--ease-out) 0.3s, transform 0.8s var(--ease-out) 0.3s,
box-shadow 0.5s var(--ease-out), background 0.5s var(--ease-out);
}
.hero-right.loaded { opacity: 1; transform: translateX(0); }
/* ── RESPONSIVE ── */
@media (max-width: 1024px) {
.hero-inner { grid-template-columns: 1fr; gap: 48px; }
.hero-right { max-width: 600px; }
.manifesto-inner { grid-template-columns: 1fr; gap: 32px; }
.manifesto-number { font-size: 4rem; }
.problems-grid, .solution-grid { grid-template-columns: 1fr; }
.problem-card, .sol-card { border-right: none; flex-direction: column; gap: 20px; }
.problem-icon { width: 60px; height: 60px; }
.problem-icon svg { width: 28px; height: 28px; }
.steps-grid { grid-template-columns: repeat(2, 1fr); }
.step:nth-child(2) { border-right: none; }
.step:nth-child(n+3) { border-top: 1px solid var(--border); }
.footer-inner { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 640px) {
.wrap { padding: 0 16px; }
section { padding: 80px 0; }
.hero { padding-top: 120px; }
h1 { font-size: clamp(2.25rem, 8vw, 3.5rem); }
.hero-meta { gap: 24px; flex-wrap: wrap; }
.dash-tri { grid-template-columns: 1fr; }
.dash-cell { border-right: none; }
.steps-grid { grid-template-columns: 1fr; }
.step { border-right: none; border-bottom: 1px solid var(--border); }
.step:last-child { border-bottom: none; }
.footer-inner { grid-template-columns: 1fr; }
.footer-bottom { flex-direction: column; gap: 12px; }
.nav { display: none; }
.price-card { padding: 40px 24px; }
.price-amount { font-size: 3rem; }
}
</style>
</head>
<body>
<!-- ── HEADER ── -->
<header class="header" id="header">
<div class="wrap">
<div class="logo">
<div class="logo-mark">R</div>
ROI24
</div>
<nav class="nav">
<a href="#solution">Решение</a>
<a href="#how">Как работает</a>
<a href="#compare">Сравнение</a>
<a href="#pricing">Тариф</a>
<a href="#faq">FAQ</a>
</nav>
<div class="header-actions">
<span class="header-phone">+7 (999) 123-45-67</span>
<a href="#cta" class="btn btn-accent">Обсудить проект</a>
<button class="theme-toggle" id="themeToggle" aria-label="Переключить тему">
<svg class="icon-moon" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5">
<path d="M17 12.5A7.5 7.5 0 1 1 7.5 3a5.5 5.5 0 0 0 9.5 9.5z"/>
</svg>
<svg class="icon-sun" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5">
<circle cx="10" cy="10" r="4"/><path d="M10 2v2M10 16v2M2 10h2M16 10h2M4.93 4.93l1.41 1.41M13.66 13.66l1.41 1.41M4.93 15.07l1.41-1.41M13.66 6.34l1.41-1.41"/>
</svg>
</button>
</div>
</div>
</header>
<!-- ── HERO ── -->
<section class="hero" id="hero">
<div class="wrap">
<div class="hero-inner">
<div class="hero-left" id="heroLeft">
<div class="hero-label">ДАННЫЕ. БЕЗ ШУМА.</div>
<h1>Вы теряете<br>деньги, <span class="accent">не зная</span><br>почему</h1>
<p class="hero-sub">
Один дашборд с 10 ключевыми метриками вашего бизнеса.
Обновляется автоматически из 1С, CRM и банков.
Смотрится с телефона каждое утро.
</p>
<div class="hero-actions">
<a href="#cta" class="btn btn-accent btn-lg">
<svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5">
<path d="M3 8h10M9 4l4 4-4 4"/>
</svg>
Получить демо за 3 дня
</a>
<a href="#compare" class="btn btn-outline btn-lg">Сравнить</a>
</div>
<div class="hero-meta">
<div class="hero-meta-item">
<span class="hero-meta-value" data-count="3">3</span>
<span class="hero-meta-label">Дня настройки</span>
</div>
<div class="hero-meta-item">
<span class="hero-meta-value" data-count="10">10</span>
<span class="hero-meta-label">Ключевых метрик</span>
</div>
<div class="hero-meta-item">
<span class="hero-meta-value" data-count="5">5+</span>
<span class="hero-meta-label">Источников</span>
</div>
</div>
</div>
<div class="hero-right" id="heroRight">
<div class="dash-glow"></div>
<div class="dash-header">
<span class="dash-brand">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.2">
<rect x="2" y="8" width="3" height="6" rx="0.5"/>
<rect x="6.5" y="5" width="3" height="9" rx="0.5"/>
<rect x="11" y="2" width="3" height="12" rx="0.5"/>
</svg>
ROI24 / DASHBOARD
</span>
<span class="dash-status"><span class="dash-dot"></span> LIVE</span>
</div>
<div class="dash-body">
<div class="dash-big">
<div class="dash-big-label">Выручка за 30 дней</div>
<div class="dash-big-value" id="bigValue">
12.4М <span class="accent">₽</span>
<span class="dash-big-trend">
<svg class="trend-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5">
<path d="M8 12V4M8 4l-3 3M8 4l3 3"/>
</svg>
12%
</span>
</div>
</div>
<div class="dash-cell">
<div class="dash-cell-label">Маржа</div>
<div class="dash-cell-value" style="color: var(--accent);" id="marginValue">23.4%</div>
<div class="dash-cell-sub" id="marginNote">↑ 2.1% к прошлому месяцу</div>
</div>
<div class="dash-cell">
<div class="dash-cell-label">Касса</div>
<div class="dash-cell-value" id="cashValue">4.8М ₽</div>
<div class="dash-cell-sub" id="cashNote">Дебиторка: 1.2М</div>
</div>
<div class="dash-tri" id="dashTri">
<div class="dash-mini">
<div class="dash-mini-label">Конверсия</div>
<div class="dash-mini-value" style="color: var(--blue);" id="mini1Val">2.8%</div>
<div class="dash-mini-bar"><div class="dash-mini-fill" id="mini1Bar" style="width:0%; background: var(--blue);"></div></div>
</div>
<div class="dash-mini">
<div class="dash-mini-label">CAC</div>
<div class="dash-mini-value" style="color: var(--amber);" id="mini2Val">890₽</div>
<div class="dash-mini-bar"><div class="dash-mini-fill" id="mini2Bar" style="width:0%; background: var(--amber);"></div></div>
</div>
<div class="dash-mini">
<div class="dash-mini-label">ROI рекл.</div>
<div class="dash-mini-value" style="color: var(--accent);" id="mini3Val">91%</div>
<div class="dash-mini-bar"><div class="dash-mini-fill" id="mini3Bar" style="width:0%; background: var(--accent);"></div></div>
</div>
</div>
</div>
<div class="dash-toggle">
<button class="dash-toggle-btn active">E-com</button>
<button class="dash-toggle-btn">Услуги</button>
<button class="dash-toggle-btn">Производство</button>
</div>
</div>
</div>
</div>
</section>
<!-- ── MANIFESTO ── -->
<section class="manifesto">
<div class="manifesto-inner">
<div class="manifesto-number reveal">70<span class="accent">%</span></div>
<div class="manifesto-content reveal reveal-delay-2">
<div class="section-label">Проблема</div>
<h2>Компаний не видят<br>деньги в кассе<br>до конца месяца</h2>
<p>Данные разбросаны по 1С, CRM, банкам, рекламным кабинетам. Каждый отчёт — ручная сводка за неделю. Когда увидели проблему — деньги уже потеряны.</p>
<p><strong style="color: var(--text);">ROI24 собирает всё в один дашборд.</strong> Обновляется автоматически. Вы видите цифры как в банковском приложении.</p>
</div>
</div>
</section>
<!-- ── PROBLEMS ── -->
<section>
<div class="wrap">
<div class="section-label reveal">Три боли</div>
<h2 class="section-title reveal reveal-delay-1">Почему вы принимаете решения в темноте</h2>
<div class="problems-grid" style="margin-top: 48px;">
<div class="problem-card reveal reveal-delay-1">
<div class="problem-icon">
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.2">
<circle cx="4" cy="8" r="2"/><circle cx="12" cy="8" r="2"/>
<path d="M6 7l2-2M10 9l2-2"/>
</svg>
</div>
<div class="problem-body">
<div class="problem-num">01</div>
<h3>Данные разбросаны</h3>
<p>Пять источников данных — 1С, CRM, онлайн-банки, рекламные кабинеты, кассы. Каждый раз — ручная сводка. Нет единой картины.</p>
</div>
</div>
<div class="problem-card reveal reveal-delay-2">
<div class="problem-icon">
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.2">
<path d="M1 8s2.5-4 7-4 7 4 7 4-2.5 4-7 4-7-4-7-4z"/>
<circle cx="8" cy="8" r="2"/><path d="M2 2l12 12"/>
</svg>
</div>
<div class="problem-body">
<div class="problem-num">02</div>
<h3>Не видно, где теряете</h3>
<p>Знаете, что выручка есть. Но не видите: какая реклама работает, какой менеджер теряет клиентов, какие точки убыточны.</p>
</div>
</div>
<div class="problem-card reveal reveal-delay-3">
<div class="problem-icon">
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.2">
<circle cx="8" cy="8" r="6"/><path d="M8 4v4l3 2"/>
</svg>
</div>
<div class="problem-body">
<div class="problem-num">03</div>
<h3>Отчёты приходят поздно</h3>
<p>В понедельник смотрите отчёт за прошлую неделю. Когда увидели проблему — деньги уже потеряны.</p>
</div>
</div>
</div>
</div>
</section>
<!-- ── SOLUTION ── -->
<section id="solution" class="solution-section">
<div class="wrap">
<div class="section-label reveal">Решение</div>
<h2 class="section-title reveal reveal-delay-1">Один дашборд. Все ключевые цифры.</h2>
<div class="solution-grid">
<div class="sol-card reveal reveal-delay-1">
<div class="sol-icon">
<svg width="28" height="28" viewBox="0 0 16 16" fill="none" stroke="var(--accent)" stroke-width="1.5">
<path d="M9 2L4 8.5h4l-1 5.5L12 7.5H8L9 2z"/>
</svg>
</div>
<h3>Живые данные</h3>
<p>Обновляются автоматически — 1С, CRM, банки, реклама. Данные сами приходят в дашборд каждый час.</p>
</div>
<div class="sol-card reveal reveal-delay-2">
<div class="sol-icon">
<svg width="28" height="28" viewBox="0 0 16 16" fill="none" stroke="var(--accent)" stroke-width="1.5">
<path d="M1 8s2.5-4 7-4 7 4 7 4-2.5 4-7 4-7-4-7-4z"/>
<circle cx="8" cy="8" r="2"/>
</svg>
</div>
<h3>Видно где теряете</h3>
<p>Цветовые индикаторы: зелёный, жёлтый, красный. Три секунды — и вы видите, какая метрика вышла за нормы.</p>
</div>
<div class="sol-card reveal reveal-delay-3">
<div class="sol-icon">
<svg width="28" height="28" viewBox="0 0 16 16" fill="none" stroke="var(--accent)" stroke-width="1.5">
<rect x="4" y="2" width="8" height="12" rx="1.5"/>
<line x1="7" y1="11.5" x2="9" y2="11.5"/>
</svg>
</div>
<h3>С телефона</h3>
<p>Собственник смотрит дашборд за завтраком. Не нужно открывать ноутбук, логиниться в 1С.</p>
</div>
</div>
</div>
</section>
<!-- ── HOW IT WORKS ── -->
<section id="how" class="steps">
<div class="wrap">
<div class="section-label reveal">Процесс</div>
<h2 class="section-title reveal reveal-delay-1">От звонка до дашборда — 3 дня</h2>
<div class="steps-grid" style="margin-top: 48px;">
<div class="step reveal reveal-delay-1">
<div class="step-num">01</div>
<h3>Брифинг</h3>
<p>30 минут. Звоним, узнаём бизнес.</p>
<div class="step-time">30 мин</div>
</div>
<div class="step reveal reveal-delay-2">
<div class="step-num">02</div>
<h3>Подключение</h3>
<p>1С, CRM, банки, реклама.</p>
<div class="step-time">1–2 дня</div>
</div>
<div class="step reveal reveal-delay-3">
<div class="step-num">03</div>
<h3>Настройка</h3>
<p>Дашборд под ваши 10 метрик.</p>
<div class="step-time">1–2 дня</div>
</div>
<div class="step reveal reveal-delay-4">
<div class="step-num">04</div>
<h3>Демо</h3>
<p>Показываем результат.</p>
<div class="step-time">30 мин</div>
</div>
<div class="step reveal">
<div class="step-num">05</div>
<h3>Запуск</h3>
<p>Доступ, обучение, авто-обновление.</p>
<div class="step-time">День запуска</div>
</div>
</div>
</div>
</section>
<!-- ── COMPARISON ── -->
<section id="compare" class="comparison">
<div class="wrap">
<div class="section-label reveal">Сравнение</div>
<h2 class="section-title reveal reveal-delay-1">Без ROI24 / С ROI24</h2>
<table class="comp-table reveal reveal-delay-2" style="margin-top: 48px;">
<thead>
<tr><th>Параметр</th><th>Без ROI24</th><th>С ROI24</th></tr>
</thead>
<tbody>
<tr><td>Данные</td><td class="comp-no">5+ источников</td><td class="comp-yes">1 дашборд</td></tr>
<tr><td>Обновление</td><td class="comp-no">Ручной ввод</td><td class="comp-yes">Авто, каждый час</td></tr>
<tr><td>Время на отчёты</td><td class="comp-no">3+ часа / неделя</td><td class="comp-yes">0 мин</td></tr>
<tr><td>Актуальность</td><td class="comp-no">30 дней</td><td class="comp-yes">Живые данные</td></tr>
<tr><td>Видно, где теряете</td><td class="comp-no">✕</td><td class="comp-yes">✓</td></tr>
<tr><td>Мобильный доступ</td><td class="comp-no">Нет</td><td class="comp-yes">Да, телефон</td></tr>
<tr><td>Стоимость (год)</td><td class="comp-no">100К + 40К зарплат</td><td class="comp-yes">100К + 20К поддержка</td></tr>
<tr><td>Окупаемость</td><td class="comp-no">Не видно</td><td class="comp-yes">3–8 месяцев</td></tr>
</tbody>
</table>
</div>
</section>
<!-- ── PRICING ── -->
<section id="pricing" class="pricing">
<div class="wrap">
<div class="text-center" style="margin-bottom: 48px;">
<div class="section-label reveal" style="justify-content:center;">Тариф</div>
<h2 class="section-title reveal reveal-delay-1" style="margin:0 auto;">Один тариф. Всё включено.</h2>
</div>
<div class="price-card reveal">
<div class="price-name">Настройка под ключ</div>
<div class="price-amount">100 000 <span class="unit">₽</span></div>
<div class="price-sub">Единоразово. Поддержка 20 000 ₽/мес после 30 дней.</div>
<ul class="price-features">
<li>Подключение 1С / CRM / банки / реклама</li>
<li>Настройка 10 ключевых метрик</li>
<li>Дашборд, заточенный под ваш бизнес</li>
<li>Обучение команды работе с дашбордом</li>
<li>30 дней поддержки и донастройки</li>
<li>Автоматическое обновление источников</li>
</ul>
<a href="#cta" class="btn btn-accent btn-lg price-cta">Обсудить проект</a>
<div class="price-guarantee">30-дневная гарантия. Если дашборд не устроит — вернём деньги.</div>
</div>
</div>
</section>
<!-- ── FAQ ── -->
<section id="faq">
<div class="wrap">
<div class="section-label reveal">Вопросы</div>
<h2 class="section-title reveal reveal-delay-1" style="margin-bottom: 48px;">Возражения</h2>
<div class="faq-list">
<div class="faq-item reveal reveal-delay-1">
<div class="faq-q">Почему 100К? Это же дорого.</div>
<div class="faq-a"><div class="faq-a-inner">Это не шаблон. Это настройка под ваш бизнес: ваши 10 метрик, ваши 5 источников, ваше обучение команды. Шаблоны от 20К, но они бесполезны.</div></div>
</div>
<div class="faq-item reveal reveal-delay-2">
<div class="faq-q">А если не подойдёт?</div>
<div class="faq-a"><div class="faq-a-inner">30-дневная гарантия. Работаем по этапам — вы видите результат после каждого. Если не то — останавливаемся и возвращаем деньги.</div></div>
</div>
<div class="faq-item reveal reveal-delay-3">
<div class="faq-q">Сколько времени займёт настройка?</div>
<div class="faq-a"><div class="faq-a-inner">3–5 дней. Первый дашборд — за 72 часа. Потом донастраиваем.</div></div>
</div>
<div class="faq-item reveal reveal-delay-4">
<div class="faq-q">А какие данные можно подключить?</div>
<div class="faq-a"><div class="faq-a-inner">1С, amoCRM, Битрикс24, Яндекс.Директ, VK Ads, онлайн-банки, кассы. Если не знаете — напишите, скажем.</div></div>
</div>
<div class="faq-item reveal">
<div class="faq-q">Можно проще? Дешевле?</div>
<div class="faq-a"><div class="faq-a-inner">Нет. "Проще" = "не работает". 50+ проектов показали: меньше 10 метрик — не видно картину. Больше 10 — шум. Наш баланс — максимум пользы.</div></div>
</div>
<div class="faq-item reveal reveal-delay-1">
<div class="faq-q">Поддержка после запуска?</div>
<div class="faq-a"><div class="faq-a-inner">30 дней включено. Далее 20 000 ₽/мес: мониторинг, техподдержка. Или отключаете — дашборд продолжает работать.</div></div>
</div>
</div>
</div>
</section>
<!-- ── FOOTER ── -->
<footer class="footer">
<div class="wrap">
<div class="footer-inner">
<div class="footer-col">
<h4>ROI24</h4>
<p>Живые цифры бизнеса за 3 дня.</p>
<p>Автоматизированные дашборды для собственников.</p>
</div>
<div class="footer-col">
<h4>Контакты</h4>
<a href="tel:+799****4567">+7 (999) 123-45-67</a>
<a href="#">Telegram</a>
<a href="#">hello@roi24.ru</a>
</div>
<div class="footer-col">
<h4>Решение</h4>
<a href="#solution">О решении</a>
<a href="#compare">Сравнение</a>
<a href="#pricing">Тариф</a>
<a href="#faq">FAQ</a>
</div>
<div class="footer-col">
<h4>Юридическое</h4>
<p>ИНН: 7712345678</p>
<p>ОГРН: 1237700123456</p>
<a href="#">Политика конфиденциальности</a>
<a href="#">152-ФЗ</a>
<a href="#">Оферта</a>
</div>
</div>
<div class="footer-bottom">
<span>© 2026 ROI24. Все права защищены.</span>
<span>Данные на серверах в Москве. SSL.</span>
</div>
</div>
</footer>
<script>
/* ── THEME TOGGLE ── */
const html = document.documentElement;
const themeToggle = document.getElementById('themeToggle');
// Check saved preference
const savedTheme = localStorage.getItem('roi24-theme');
if (savedTheme) {
html.setAttribute('data-theme', savedTheme);
}
themeToggle.addEventListener('click', () => {
const current = html.getAttribute('data-theme');
const next = current === 'dark' ? 'light' : 'dark';
html.setAttribute('data-theme', next);
localStorage.setItem('roi24-theme', next);
});
/* ── HEADER SCROLL ── */
const header = document.getElementById('header');
window.addEventListener('scroll', () => {
header.classList.toggle('scrolled', window.scrollY > 40);
}, { passive: true });
/* ── HERO ENTRANCE ── */
window.addEventListener('load', () => {
document.getElementById('heroLeft').classList.add('loaded');
document.getElementById('heroRight').classList.add('loaded');
setTimeout(() => {
document.querySelectorAll('.dash-mini-fill').forEach(bar => {
const target = bar.style.width || '0';
bar.style.width = '0';
requestAnimationFrame(() => {
requestAnimationFrame(() => {
bar.style.width = target;
});
});
});
}, 800);
});
/* ── SCROLL REVEAL ── */
const revealObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
revealObserver.unobserve(entry.target);
}
});
}, { threshold: 0.08, rootMargin: '0px 0px -40px 0px' });
document.querySelectorAll('.reveal').forEach(el => revealObserver.observe(el));
/* ── DASHBOARD SEGMENT TOGGLE ── */
const SEGMENTS = {
ecom: {
revenue: '12.4М', revenueTrend: '+12%',
margin: '23.4%', marginNote: '↑ 2.1% к прошлому месяцу',
cash: '4.8М ₽', cashNote: 'Дебиторка: 1.2М',
mini: [
{ label: 'Конверсия', value: '2.8%', pct: 28, color: 'var(--blue)' },
{ label: 'CAC', value: '890₽', pct: 45, color: 'var(--amber)' },
{ label: 'ROI рекл.', value: '91%', pct: 91, color: 'var(--accent)' }
]
},
services: {
revenue: '3.8М', revenueTrend: '+8%',
margin: '31.2%', marginNote: '↑ 1.4%',
cash: '2.1М ₽', cashNote: 'Пайплайн: 8.5М',
mini: [
{ label: 'Загрузка', value: '78%', pct: 78, color: 'var(--blue)' },
{ label: 'Марж. проект', value: '34%', pct: 68, color: 'var(--amber)' },
{ label: 'LTV', value: '185К', pct: 82, color: 'var(--accent)' }
]
},
production: {
revenue: '28.7М', revenueTrend: '+5%',
margin: '18.7%', marginNote: '↓ 0.8%',
cash: '6.2М ₽', cashNote: 'OEE: 72%',
mini: [
{ label: 'План/факт', value: '94%', pct: 94, color: 'var(--blue)' },
{ label: 'OEE', value: '72%', pct: 72, color: 'var(--amber)' },
{ label: 'Качество', value: '99.1%', pct: 99, color: 'var(--accent)' }
]
}
};
const toggleBtns = document.querySelectorAll('.dash-toggle-btn');
toggleBtns.forEach(btn => {
btn.addEventListener('click', () => {
const key = btn.textContent.toLowerCase().includes('e-com') ? 'ecom' :
btn.textContent.toLowerCase().includes('услуг') ? 'services' : 'production';
const seg = SEGMENTS[key];
toggleBtns.forEach(b => b.classList.remove('active'));
btn.classList.add('active');
const bigValue = document.getElementById('bigValue');
bigValue.style.opacity = '0';
bigValue.style.transform = 'translateY(-8px)';
bigValue.style.transition = 'opacity 0.3s, transform 0.3s';
setTimeout(() => {
bigValue.innerHTML = `${seg.revenue} <span class="accent">₽</span><span class="dash-big-trend"><svg class="trend-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M8 12V4M8 4l-3 3M8 4l3 3"/></svg>${seg.revenueTrend}</span>`;
bigValue.style.opacity = '1';
bigValue.style.transform = 'translateY(0)';
}, 300);
const marginValue = document.getElementById('marginValue');
const marginNote = document.getElementById('marginNote');
const cashValue = document.getElementById('cashValue');
const cashNote = document.getElementById('cashNote');
[marginValue, marginNote, cashValue, cashNote].forEach(el => {
el.style.transition = 'opacity 0.25s';
el.style.opacity = '0';
});
setTimeout(() => {
marginValue.textContent = seg.margin;
marginNote.textContent = seg.marginNote;
cashValue.textContent = seg.cash;
cashNote.textContent = seg.cashNote;
[marginValue, marginNote, cashValue, cashNote].forEach(el => { el.style.opacity = '1'; });
}, 280);
seg.mini.forEach((m, i) => {
const miniVal = document.getElementById(`mini${i+1}Val`);
const miniBar = document.getElementById(`mini${i+1}Bar`);
miniVal.style.opacity = '0';
miniVal.style.transform = 'translateY(-4px)';
setTimeout(() => {
miniVal.textContent = m.value;
miniVal.style.color = m.color;
miniVal.style.opacity = '1';
miniVal.style.transform = 'translateY(0)';
miniVal.style.transition = 'opacity 0.3s var(--ease-out), transform 0.3s var(--ease-out)';
miniBar.style.width = m.pct + '%';
miniBar.style.background = m.color;
}, 200 + i * 80);
});
});
});
/* ── FAQ ACCORDION ── */
document.querySelectorAll('.faq-q').forEach(q => {
q.addEventListener('click', () => {
const item = q.parentElement;
const wasOpen = item.classList.contains('open');
document.querySelectorAll('.faq-item').forEach(i => i.classList.remove('open'));
if (!wasOpen) item.classList.add('open');
});
});
/* ── HERO PARALLAX ── */
const hero = document.getElementById('hero');
const heroRight = document.getElementById('heroRight');
hero.addEventListener('mousemove', (e) => {
const rect = hero.getBoundingClientRect();
const x = (e.clientX - rect.left) / rect.width - 0.5;
const y = (e.clientY - rect.top) / rect.height - 0.5;
heroRight.style.transform = `translateY(${-6 + y * -4}px) perspective(800px) rotateY(${x * 1.5}deg) rotateX(${y * 1.5}deg)`;
});
hero.addEventListener('mouseleave', () => {
heroRight.style.transform = 'translateY(0) perspective(800px) rotateY(0) rotateX(0)';
heroRight.style.transition = 'transform 0.6s var(--ease-out)';
setTimeout(() => {
heroRight.style.transition = 'transform 0.1s, opacity 0.8s var(--ease-out) 0.3s, box-shadow 0.5s var(--ease-out), background 0.5s var(--ease-out)';
}, 600);
});
</script>
</body>
</html>