work-license-server 0.0.0-stage → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,33 @@
1
- # Temporary Holding Version
1
+ # ODANT-WORK License Server (`work.odant.org`)
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Лицензионный сервер, платёжный шлюз ЮKassa, боты техподдержки (`MAX`, `Telegram`, `VK`), собственный ИИ-агент и витрина программно-аппаратного комплекса **ODANT-WORK** (`https://work.odant.org`).
4
+
5
+ ## Назначение
6
+
7
+ 1. **Витрина `/`** — вкладки «Платформа», «ИИ-агенты», «Тарифы», «Комплекс», «Докупка лицензий» (только после входа), «Франшиза», «Поддержка»; светлая и тёмная темы, мягкий анимированный фон (графики роста и сеть связей).
8
+ - Комплекс: **AMD Ryzen™ AI Max+ PRO 495 · Radeon™ 8065S · 192 ГБ LPDDR5x-8533 · SSD 4 ТБ**.
9
+ - Внутри: встроенная система учёта, документооборот, управление процессами, ИИ-консультант в каждой форме, мультиагентная система (13 ролевых агентов, 26+ навыков) и 4 типа локальных моделей (языковая, голосовая, генерация изображений, векторный поиск).
10
+ - Базовый комплект — `5 000 000 ₽`: **вечная лицензия на 5 одновременных сессий** и **1-й год поддержки**.
11
+ 2. **Годовые лицензии на дополнительных пользователей** со скидкой за количество (5+ мест −5% … 100+ мест −25%):
12
+ - **Start** — `10 000 ₽ / год` (до 12 обращений в год на место, реакция до 8 рабочих часов);
13
+ - **Business** — `15 000 ₽ / год` (до 48 обращений, реакция до 2 часов);
14
+ - **Enterprise** — `20 000 ₽ / год` (безлимит, реакция до 15 минут 24/7).
15
+ 3. **Региональная франшиза** — интерактивная карта всех субъектов РФ (`assets/russia-regions.json`, границы © участники OpenStreetMap), квота франшиз пропорциональна населению, стоимость — `5 000 000 ₽ ×` индекс субъекта, резерв — невозвратный залог `100 000 ₽` (`POST /api/partners/reserve`).
16
+ 4. **ЮKassa** (`/api/orders/checkout`, `/api/payments/yookassa/webhook`) — чеки 54-ФЗ, выпуск и продление сертификатов `Ed25519` (`WORK-LIC-v1`) с привязкой к `HWID` и ключу узла `#system/node-key.json`.
17
+ 5. **Боты поддержки** — `/api/bots/max/webhook`, `/api/bots/telegram/webhook`, `/api/bots/vk/webhook`.
18
+ 6. **ИИ-агент** — `POST /api/agent/chat`: консультации, расчёт лицензий, вакантные франшизы по субъекту, контакты.
19
+
20
+ ## Запуск
21
+
22
+ ```bash
23
+ npx work-license-server # http://localhost:8020/
24
+ PORT=8080 npx work-license-server
25
+ ```
26
+
27
+ ## Карта субъектов
28
+
29
+ `assets/russia-regions.json` собирается скриптом `scripts/build-russia-map.mjs` из OSM-границ (топологическое упрощение, равновеликая коническая проекция, подписи в полюсе недоступности).
30
+
31
+ ## Разработчик
32
+
33
+ Бизнес Интер Софт · 390000, г. Рязань, ул. Ленина, 47 · +7 (4912) 77-70-21, 77-70-22 · [odant.ru](https://www.odant.ru)
@@ -0,0 +1,609 @@
1
+ /* ODANT-WORK · work.odant.org — стили витрины */
2
+
3
+ :root, html[data-theme="dark"] {
4
+ --bg: #04060b;
5
+ --bg-2: #080c16;
6
+ --panel: rgba(12, 18, 31, 0.64);
7
+ --panel-strong: rgba(12, 18, 31, 0.88);
8
+ --panel-solid: #0c1220;
9
+ --field: rgba(4, 8, 16, 0.72);
10
+ --line: rgba(148, 170, 200, 0.12);
11
+ --line-strong: rgba(148, 170, 200, 0.24);
12
+ --text: #eef4fb;
13
+ --text-2: #b4c2d4;
14
+ --muted: #7b8aa1;
15
+ --brand: #00a3e0;
16
+ --brand-2: #4cc3f0;
17
+ --brand-3: #a9dcf4;
18
+ --brand-ink: #ffffff;
19
+ --ok: #22c55e;
20
+ --warn: #f5b000;
21
+ --danger: #f43f5e;
22
+ --glow: rgba(0, 163, 224, 0.38);
23
+ --shadow: 0 30px 80px -20px rgba(0, 0, 0, 0.65);
24
+ --grid-line: rgba(120, 160, 210, 0.05);
25
+ --m0: rgba(244, 63, 94, 0.22);
26
+ --m1: #0b3b55;
27
+ --m2: #0a5478;
28
+ --m3: #066f9d;
29
+ --m4: #0390c8;
30
+ --m5: #28b6ec;
31
+ --map-stroke: rgba(4, 6, 11, 0.9);
32
+ --map-empty: rgba(120, 140, 170, 0.14);
33
+ color-scheme: dark;
34
+ }
35
+
36
+ html[data-theme="light"] {
37
+ --bg: #f3f6fb;
38
+ --bg-2: #e9eef6;
39
+ --panel: rgba(255, 255, 255, 0.72);
40
+ --panel-strong: rgba(255, 255, 255, 0.92);
41
+ --panel-solid: #ffffff;
42
+ --field: #ffffff;
43
+ --line: rgba(15, 23, 42, 0.08);
44
+ --line-strong: rgba(15, 23, 42, 0.16);
45
+ --text: #0a1220;
46
+ --text-2: #334155;
47
+ --muted: #64748b;
48
+ --brand: #0284c7;
49
+ --brand-2: #0ea5e9;
50
+ --brand-3: #0369a1;
51
+ --glow: rgba(2, 132, 199, 0.22);
52
+ --shadow: 0 24px 60px -24px rgba(15, 23, 42, 0.22);
53
+ --grid-line: rgba(15, 23, 42, 0.035);
54
+ --m0: rgba(244, 63, 94, 0.2);
55
+ --m1: #cfe9f7;
56
+ --m2: #a3d6f1;
57
+ --m3: #6ec0ea;
58
+ --m4: #31a3dd;
59
+ --m5: #0284c7;
60
+ --map-stroke: #ffffff;
61
+ --map-empty: rgba(100, 116, 139, 0.14);
62
+ color-scheme: light;
63
+ }
64
+
65
+ * { box-sizing: border-box; }
66
+ html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
67
+ body {
68
+ margin: 0;
69
+ min-height: 100vh;
70
+ font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
71
+ font-size: 15px;
72
+ line-height: 1.55;
73
+ background: var(--bg);
74
+ color: var(--text);
75
+ overflow-x: hidden;
76
+ -webkit-font-smoothing: antialiased;
77
+ transition: background-color .35s ease, color .35s ease;
78
+ }
79
+ h1, h2, h3, h4, .display { font-family: "Manrope", "Inter", sans-serif; letter-spacing: -0.025em; }
80
+ a { color: var(--brand-2); text-decoration: none; }
81
+ a:hover { text-decoration: underline; }
82
+ button { font: inherit; color: inherit; }
83
+ ::selection { background: var(--brand); color: #fff; }
84
+
85
+ /* ---------- Фон ---------- */
86
+ #bgCanvas { position: fixed; inset: 0; width: 100vw; height: 100vh; z-index: 0; pointer-events: none; }
87
+ .bg-grid {
88
+ position: fixed; inset: 0; z-index: 0; pointer-events: none;
89
+ background-image:
90
+ linear-gradient(var(--grid-line) 1px, transparent 1px),
91
+ linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
92
+ background-size: 56px 56px;
93
+ mask-image: radial-gradient(ellipse 80% 60% at 50% 30%, #000 30%, transparent 85%);
94
+ }
95
+ .bg-aurora { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
96
+ .bg-aurora i {
97
+ position: absolute; width: 62vmax; height: 62vmax; border-radius: 50%;
98
+ filter: blur(80px); opacity: .5; will-change: transform;
99
+ animation: auroraDrift 38s ease-in-out infinite alternate;
100
+ }
101
+ .bg-aurora i:nth-child(1) { top: -24vmax; right: -14vmax; background: radial-gradient(circle, rgba(0, 163, 224, .34), transparent 65%); }
102
+ .bg-aurora i:nth-child(2) { bottom: -30vmax; left: -18vmax; background: radial-gradient(circle, rgba(99, 102, 241, .22), transparent 65%); animation-duration: 46s; animation-delay: -12s; }
103
+ .bg-aurora i:nth-child(3) { top: 30%; left: 35%; width: 44vmax; height: 44vmax; background: radial-gradient(circle, rgba(34, 197, 94, .1), transparent 65%); animation-duration: 54s; animation-delay: -24s; }
104
+ @keyframes auroraDrift {
105
+ 0% { transform: translate3d(0, 0, 0) scale(1); }
106
+ 50% { transform: translate3d(-6vmax, 4vmax, 0) scale(1.12); }
107
+ 100% { transform: translate3d(5vmax, -3vmax, 0) scale(.94); }
108
+ }
109
+ html[data-theme="light"] .bg-aurora i { opacity: .55; }
110
+ .bg-vignette {
111
+ position: fixed; inset: 0; z-index: 1; pointer-events: none;
112
+ background: radial-gradient(ellipse at 60% 35%, transparent 35%, color-mix(in srgb, var(--bg) 82%, transparent) 100%);
113
+ }
114
+
115
+ .shell { position: relative; z-index: 2; max-width: 1320px; margin: 0 auto; padding: 0 28px 48px; }
116
+
117
+ /* ---------- Шапка ---------- */
118
+ .topbar {
119
+ position: sticky; top: 0; z-index: 30;
120
+ margin: 0 -28px; padding: 12px 28px;
121
+ display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 12px;
122
+ background: color-mix(in srgb, var(--bg) 72%, transparent);
123
+ backdrop-filter: blur(18px) saturate(140%);
124
+ -webkit-backdrop-filter: blur(18px) saturate(140%);
125
+ border-bottom: 1px solid var(--line);
126
+ }
127
+ .brand { display: flex; align-items: center; gap: 12px; cursor: pointer; background: none; border: 0; padding: 0; text-align: left; }
128
+ .brand img { width: 38px; height: 38px; filter: drop-shadow(0 4px 14px var(--glow)); transition: transform .5s cubic-bezier(.2,.8,.2,1); }
129
+ .brand:hover img { transform: rotate(-12deg) scale(1.06); }
130
+ .brand-name { font-family: "Manrope", sans-serif; font-weight: 800; font-size: 18px; letter-spacing: .01em; line-height: 1.1; }
131
+ .brand-name b { color: var(--brand-2); font-weight: 800; }
132
+ .brand-sub { font-size: 11px; color: var(--muted); letter-spacing: .02em; }
133
+
134
+ .tabs {
135
+ position: relative; justify-self: center;
136
+ display: flex; gap: 2px; padding: 4px;
137
+ border-radius: 999px; border: 1px solid var(--line);
138
+ background: color-mix(in srgb, var(--panel-solid) 55%, transparent);
139
+ overflow-x: auto; scrollbar-width: none; max-width: 100%;
140
+ }
141
+ .tabs::-webkit-scrollbar { display: none; }
142
+ .tab {
143
+ position: relative; z-index: 1; flex: none;
144
+ padding: 7px 11px; border: 0; border-radius: 999px; background: none; cursor: pointer;
145
+ font-size: 13px; font-weight: 600; color: var(--muted); white-space: nowrap;
146
+ transition: color .25s ease;
147
+ }
148
+ .tab:hover { color: var(--text); }
149
+ .tab.active { color: var(--brand-ink); }
150
+ html[data-theme="light"] .tab.active { color: #fff; }
151
+ .tab .lock { font-size: 10px; margin-left: 4px; opacity: .8; }
152
+ .tab-ind {
153
+ position: absolute; z-index: 0; top: 4px; bottom: 4px; left: 0; width: 0; border-radius: 999px;
154
+ background: linear-gradient(135deg, var(--brand), #2563eb);
155
+ box-shadow: 0 6px 20px -4px var(--glow), inset 0 1px 0 rgba(255,255,255,.25);
156
+ transition: left .45s cubic-bezier(.2,.9,.2,1), width .45s cubic-bezier(.2,.9,.2,1);
157
+ }
158
+ .top-actions { display: flex; align-items: center; gap: 8px; }
159
+
160
+ /* ---------- Кнопки ---------- */
161
+ .btn {
162
+ display: inline-flex; align-items: center; justify-content: center; gap: 8px;
163
+ padding: 11px 20px; border-radius: 12px; border: 1px solid transparent; cursor: pointer;
164
+ font-weight: 650; font-size: 14px; line-height: 1; white-space: nowrap;
165
+ transition: transform .18s ease, box-shadow .25s ease, background .25s ease, border-color .25s ease, opacity .2s;
166
+ }
167
+ .btn:active { transform: translateY(1px) scale(.99); }
168
+ .btn:disabled { opacity: .45; cursor: not-allowed; }
169
+ .btn svg { width: 17px; height: 17px; }
170
+ .btn-primary {
171
+ color: #fff;
172
+ background: linear-gradient(135deg, #00a3e0 0%, #1d6ff2 100%);
173
+ box-shadow: 0 10px 30px -10px var(--glow), inset 0 1px 0 rgba(255,255,255,.28);
174
+ }
175
+ .btn-primary:hover:not(:disabled) { box-shadow: 0 16px 40px -10px var(--glow), inset 0 1px 0 rgba(255,255,255,.35); transform: translateY(-1px); }
176
+ .btn-ghost { background: color-mix(in srgb, var(--panel-solid) 60%, transparent); border-color: var(--line-strong); color: var(--text); }
177
+ .btn-ghost:hover:not(:disabled) { border-color: var(--brand); background: color-mix(in srgb, var(--brand) 10%, transparent); }
178
+ .btn-ok { color: #fff; background: linear-gradient(135deg, #16a34a, #059669); box-shadow: 0 10px 30px -12px rgba(34,197,94,.5); }
179
+ .btn-sm { padding: 8px 13px; font-size: 12.5px; border-radius: 10px; }
180
+ .btn-lg { padding: 15px 26px; font-size: 15px; border-radius: 14px; }
181
+ .icon-btn {
182
+ width: 38px; height: 38px; padding: 0; border-radius: 11px;
183
+ display: inline-grid; place-items: center; cursor: pointer;
184
+ background: color-mix(in srgb, var(--panel-solid) 60%, transparent);
185
+ border: 1px solid var(--line-strong); color: var(--text);
186
+ transition: border-color .2s, transform .2s;
187
+ }
188
+ .icon-btn:hover { border-color: var(--brand); }
189
+ .icon-btn svg { width: 18px; height: 18px; }
190
+
191
+ /* ---------- Сцены (вкладки) ---------- */
192
+ .stage { display: none; padding-top: 34px; }
193
+ .stage.active { display: block; animation: stageIn .55s cubic-bezier(.2,.8,.2,1); }
194
+ @keyframes stageIn { from { opacity: 0; transform: translateY(14px); filter: blur(4px); } to { opacity: 1; transform: none; filter: none; } }
195
+ .stage > * + * { margin-top: 26px; }
196
+ .reveal { opacity: 0; transform: translateY(18px); transition: opacity .7s ease, transform .7s cubic-bezier(.2,.8,.2,1); }
197
+ .reveal.in { opacity: 1; transform: none; }
198
+
199
+ /* ---------- Типографика ---------- */
200
+ .kicker {
201
+ display: inline-flex; align-items: center; gap: 10px;
202
+ font-size: 12px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--brand-2);
203
+ }
204
+ .kicker::before { content: ""; width: 22px; height: 1.5px; background: currentColor; border-radius: 2px; }
205
+ .pill {
206
+ display: inline-flex; align-items: center; gap: 8px;
207
+ padding: 6px 12px 6px 8px; border-radius: 999px;
208
+ border: 1px solid color-mix(in srgb, var(--brand) 38%, transparent);
209
+ background: color-mix(in srgb, var(--brand) 10%, transparent);
210
+ font-size: 12.5px; font-weight: 600; color: var(--text-2);
211
+ }
212
+ .pill .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 4px color-mix(in srgb, var(--ok) 22%, transparent); animation: pulseDot 2.2s infinite; }
213
+ @keyframes pulseDot { 50% { box-shadow: 0 0 0 7px transparent; } }
214
+ .h1 { margin: 18px 0 18px; font-size: clamp(2.2rem, 3.7vw, 3.55rem); line-height: 1.06; font-weight: 800; }
215
+ .grad { background: linear-gradient(100deg, var(--brand-2) 0%, #7aa7ff 50%, var(--brand-3) 100%); -webkit-background-clip: text; background-clip: text; color: transparent; }
216
+ .h2 { margin: 10px 0 8px; font-size: clamp(1.7rem, 2.8vw, 2.45rem); line-height: 1.12; font-weight: 800; }
217
+ .h3 { margin: 0 0 6px; font-size: 18px; font-weight: 750; }
218
+ .lead { font-size: 17px; line-height: 1.65; color: var(--text-2); max-width: 640px; margin: 0; }
219
+ .muted { color: var(--muted); }
220
+ .small { font-size: 12.5px; }
221
+ .sec-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 20px; flex-wrap: wrap; }
222
+ .sec-head p { margin: 0; max-width: 620px; color: var(--text-2); }
223
+
224
+ /* ---------- Карточки ---------- */
225
+ .card {
226
+ position: relative; isolation: isolate;
227
+ background: var(--panel);
228
+ border: 1px solid var(--line);
229
+ border-radius: 22px;
230
+ padding: 26px;
231
+ backdrop-filter: blur(22px) saturate(130%);
232
+ -webkit-backdrop-filter: blur(22px) saturate(130%);
233
+ box-shadow: var(--shadow);
234
+ }
235
+ .spot::after {
236
+ content: ""; position: absolute; inset: 0; border-radius: inherit; z-index: -1; pointer-events: none;
237
+ background: radial-gradient(420px circle at var(--mx, -999px) var(--my, -999px), color-mix(in srgb, var(--brand) 13%, transparent), transparent 60%);
238
+ opacity: 0; transition: opacity .3s;
239
+ }
240
+ .spot:hover::after { opacity: 1; }
241
+ .spot:hover { border-color: var(--line-strong); }
242
+ .card-glow { border: 1px solid transparent; background: linear-gradient(var(--panel-strong), var(--panel-strong)) padding-box, conic-gradient(from var(--ang, 0deg), transparent 0deg, var(--brand) 60deg, transparent 140deg, #6d8dff 220deg, transparent 300deg) border-box; animation: spin 8s linear infinite; }
243
+ @property --ang { syntax: "<angle>"; initial-value: 0deg; inherits: false; }
244
+ @keyframes spin { to { --ang: 360deg; } }
245
+
246
+ .grid { display: grid; gap: 18px; }
247
+ .g2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
248
+ .g3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
249
+ .g4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
250
+ @media (max-width: 1080px) { .g4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } .g3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
251
+ @media (max-width: 680px) { .g2, .g3, .g4 { grid-template-columns: 1fr; } }
252
+
253
+ .ico {
254
+ width: 44px; height: 44px; border-radius: 13px; display: grid; place-items: center; margin-bottom: 16px;
255
+ color: var(--brand-2);
256
+ background: linear-gradient(145deg, color-mix(in srgb, var(--brand) 22%, transparent), color-mix(in srgb, var(--brand) 4%, transparent));
257
+ border: 1px solid color-mix(in srgb, var(--brand) 30%, transparent);
258
+ }
259
+ .ico svg { width: 22px; height: 22px; }
260
+ .tag {
261
+ display: inline-block; padding: 3px 9px; border-radius: 999px; font-size: 11px; font-weight: 700; letter-spacing: .02em;
262
+ background: color-mix(in srgb, var(--brand) 14%, transparent); color: var(--brand-2);
263
+ }
264
+ .tag.ok { background: color-mix(in srgb, var(--ok) 15%, transparent); color: var(--ok); }
265
+ .tag.bad { background: color-mix(in srgb, var(--danger) 15%, transparent); color: var(--danger); }
266
+ .list { list-style: none; margin: 14px 0 0; padding: 0; display: grid; gap: 9px; }
267
+ .list li { position: relative; padding-left: 26px; color: var(--text-2); font-size: 14px; }
268
+ .list li::before {
269
+ content: ""; position: absolute; left: 0; top: 3px; width: 16px; height: 16px; border-radius: 50%;
270
+ background: color-mix(in srgb, var(--brand) 18%, transparent) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234cc3f0' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12l5 5L20 7'/%3E%3C/svg%3E") center / 10px no-repeat;
271
+ }
272
+
273
+ /* ---------- Герой ---------- */
274
+ .hero { display: grid; grid-template-columns: 1.12fr .88fr; gap: 40px; align-items: center; min-height: calc(100vh - 220px); }
275
+ @media (max-width: 1000px) { .hero { grid-template-columns: 1fr; min-height: 0; } }
276
+ .hero-cta { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 30px; }
277
+ .trust { display: flex; gap: 22px; flex-wrap: wrap; margin-top: 30px; color: var(--muted); font-size: 13px; }
278
+ .trust span { display: inline-flex; align-items: center; gap: 8px; }
279
+ .trust svg { width: 16px; height: 16px; color: var(--ok); }
280
+
281
+ .showcase { position: relative; aspect-ratio: 1 / 1; max-width: 520px; width: 100%; justify-self: center; }
282
+ .showcase-ring { position: absolute; inset: 8%; border-radius: 50%; border: 1px dashed color-mix(in srgb, var(--brand) 30%, transparent); animation: rot 60s linear infinite; }
283
+ .showcase-ring.r2 { inset: 20%; border-style: solid; border-color: var(--line); animation-duration: 40s; animation-direction: reverse; }
284
+ @keyframes rot { to { transform: rotate(360deg); } }
285
+ .showcase-logo {
286
+ position: absolute; inset: 27%;
287
+ display: grid; place-items: center;
288
+ filter: drop-shadow(0 30px 60px var(--glow));
289
+ animation: floaty 7s ease-in-out infinite;
290
+ }
291
+ .showcase-logo img { width: 100%; height: 100%; object-fit: contain; }
292
+ @keyframes floaty { 50% { transform: translateY(-12px) rotate(1.5deg); } }
293
+ .chipf {
294
+ position: absolute; padding: 10px 14px; border-radius: 14px;
295
+ background: var(--panel-strong); border: 1px solid var(--line-strong);
296
+ backdrop-filter: blur(16px); box-shadow: var(--shadow);
297
+ font-size: 12px; color: var(--muted); line-height: 1.25;
298
+ animation: floaty 6s ease-in-out infinite;
299
+ }
300
+ .chipf b { display: block; font-family: "Manrope", sans-serif; font-size: 20px; color: var(--text); letter-spacing: -.02em; }
301
+ .chipf.c1 { top: 6%; left: 0; animation-delay: -1s; }
302
+ .chipf.c2 { top: 16%; right: -2%; animation-delay: -2.5s; }
303
+ .chipf.c3 { bottom: 14%; left: -4%; animation-delay: -3.5s; }
304
+ .chipf.c4 { bottom: 4%; right: 6%; animation-delay: -4.5s; }
305
+
306
+ .kpis { display: grid; grid-template-columns: repeat(4, 1fr); border: 1px solid var(--line); border-radius: 22px; overflow: hidden; background: var(--panel); backdrop-filter: blur(20px); }
307
+ .kpi { padding: 24px 26px; border-right: 1px solid var(--line); }
308
+ .kpi:last-child { border-right: 0; }
309
+ .kpi b { display: block; font-family: "Manrope", sans-serif; font-size: clamp(1.8rem, 3vw, 2.6rem); font-weight: 800; letter-spacing: -.03em; line-height: 1.05; }
310
+ .kpi b small { font-size: .5em; color: var(--brand-2); margin-left: 4px; letter-spacing: 0; }
311
+ .kpi span { color: var(--muted); font-size: 13px; }
312
+ @media (max-width: 860px) { .kpis { grid-template-columns: repeat(2, 1fr); } .kpi:nth-child(2) { border-right: 0; } .kpi:nth-child(-n+2) { border-bottom: 1px solid var(--line); } }
313
+
314
+ .bento { display: grid; grid-template-columns: repeat(6, 1fr); gap: 18px; }
315
+ .bento > .card { grid-column: span 2; }
316
+ .bento > .card.wide { grid-column: span 3; }
317
+ @media (max-width: 1000px) { .bento > .card, .bento > .card.wide { grid-column: span 3; } }
318
+ @media (max-width: 680px) { .bento > .card, .bento > .card.wide { grid-column: span 6; } }
319
+
320
+ .spec-wrap { display: grid; grid-template-columns: .9fr 1.1fr; gap: 30px; align-items: center; }
321
+ @media (max-width: 900px) { .spec-wrap { grid-template-columns: 1fr; } }
322
+ .price-big { font-family: "Manrope", sans-serif; font-size: clamp(2.4rem, 4vw, 3.4rem); font-weight: 800; letter-spacing: -.035em; line-height: 1; margin: 12px 0 6px; }
323
+ .spec { display: grid; gap: 0; margin: 0; }
324
+ .spec div { display: grid; grid-template-columns: 170px 1fr; gap: 16px; padding: 12px 0; border-bottom: 1px solid var(--line); font-size: 14px; }
325
+ .spec div:last-child { border-bottom: 0; }
326
+ .spec dt { color: var(--muted); }
327
+ .spec dd { margin: 0; font-weight: 600; }
328
+ @media (max-width: 560px) { .spec div { grid-template-columns: 1fr; gap: 2px; } }
329
+
330
+ /* ---------- ИИ-агенты ---------- */
331
+ .agents-hero { display: grid; grid-template-columns: 1fr 1fr; gap: 30px; align-items: center; }
332
+ @media (max-width: 1000px) { .agents-hero { grid-template-columns: 1fr; } }
333
+ .mock {
334
+ border-radius: 20px; overflow: hidden; border: 1px solid var(--line-strong);
335
+ background: var(--panel-strong); box-shadow: var(--shadow); backdrop-filter: blur(20px);
336
+ }
337
+ .mock-bar { display: flex; align-items: center; gap: 10px; padding: 12px 16px; border-bottom: 1px solid var(--line); font-size: 13px; font-weight: 600; }
338
+ .mock-bar .dots { display: flex; gap: 6px; }
339
+ .mock-bar .dots i { width: 10px; height: 10px; border-radius: 50%; background: var(--line-strong); }
340
+ .mock-bar .help {
341
+ margin-left: auto; width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center;
342
+ background: linear-gradient(135deg, var(--brand), #2563eb); color: #fff; font-weight: 800; font-size: 14px;
343
+ box-shadow: 0 0 0 0 var(--glow); animation: helpPulse 2.4s infinite;
344
+ }
345
+ @keyframes helpPulse { 0% { box-shadow: 0 0 0 0 var(--glow); } 70% { box-shadow: 0 0 0 12px transparent; } 100% { box-shadow: 0 0 0 0 transparent; } }
346
+ .mock-body { padding: 18px; display: grid; gap: 12px; min-height: 330px; align-content: start; }
347
+ .bubble { max-width: 86%; padding: 11px 14px; border-radius: 16px; font-size: 13.5px; line-height: 1.5; opacity: 0; transform: translateY(8px); animation: bubbleIn .5s forwards; }
348
+ .bubble.u { justify-self: end; color: #fff; background: linear-gradient(135deg, var(--brand), #2563eb); border-bottom-right-radius: 5px; }
349
+ .bubble.a { background: color-mix(in srgb, var(--panel-solid) 80%, transparent); border: 1px solid var(--line); border-bottom-left-radius: 5px; }
350
+ .bubble .tools { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
351
+ .bubble .tools span { font-size: 11px; padding: 3px 8px; border-radius: 999px; border: 1px solid var(--line-strong); color: var(--muted); }
352
+ @keyframes bubbleIn { to { opacity: 1; transform: none; } }
353
+ .wave { display: flex; align-items: center; gap: 3px; height: 26px; }
354
+ .wave i { width: 3px; border-radius: 3px; background: var(--brand-2); animation: wave 1.1s ease-in-out infinite; }
355
+ @keyframes wave { 0%, 100% { height: 5px; } 50% { height: 24px; } }
356
+
357
+ .orbit-wrap { display: grid; grid-template-columns: 1.1fr .9fr; gap: 26px; align-items: center; }
358
+ @media (max-width: 1000px) { .orbit-wrap { grid-template-columns: 1fr; } }
359
+ .orbit { width: 100%; max-width: 600px; justify-self: center; aspect-ratio: 1; }
360
+ .orbit .link { stroke: color-mix(in srgb, var(--brand) 35%, transparent); stroke-width: 1.2; stroke-dasharray: 3 6; animation: dash 1.8s linear infinite; }
361
+ .orbit .link.on { stroke: var(--brand-2); stroke-width: 2; stroke-dasharray: none; }
362
+ @keyframes dash { to { stroke-dashoffset: -18; } }
363
+ .orbit .node { cursor: pointer; }
364
+ .orbit .node circle { fill: var(--panel-solid); stroke: var(--line-strong); stroke-width: 1.5; transition: stroke .2s, fill .2s; }
365
+ .orbit .node:hover circle, .orbit .node.on circle { stroke: var(--brand-2); fill: color-mix(in srgb, var(--brand) 22%, var(--panel-solid)); }
366
+ .orbit .node text { fill: var(--text-2); font-size: 12px; font-weight: 600; font-family: "Inter", sans-serif; }
367
+ .orbit .node .num { fill: var(--brand-2); font-size: 13px; font-weight: 800; }
368
+ .orbit .core-ring { fill: none; stroke: color-mix(in srgb, var(--brand) 40%, transparent); stroke-width: 1; }
369
+ .orbit .pulse { fill: var(--brand-2); }
370
+ .agent-detail h3 { font-size: 24px; margin: 8px 0; }
371
+
372
+ .skills { display: flex; flex-wrap: wrap; gap: 8px; }
373
+ .skills span {
374
+ padding: 8px 14px; border-radius: 999px; font-size: 13px; font-weight: 550;
375
+ border: 1px solid var(--line-strong); background: color-mix(in srgb, var(--panel-solid) 50%, transparent);
376
+ transition: border-color .2s, color .2s, transform .2s;
377
+ }
378
+ .skills span:hover { border-color: var(--brand); color: var(--brand-2); transform: translateY(-2px); }
379
+
380
+ /* ---------- Тарифы ---------- */
381
+ .tiers { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; align-items: stretch; }
382
+ @media (max-width: 980px) { .tiers { grid-template-columns: 1fr; } }
383
+ .tier { display: flex; flex-direction: column; }
384
+ .tier.featured { transform: translateY(-8px); }
385
+ .tier-price { font-family: "Manrope", sans-serif; font-size: 40px; font-weight: 800; letter-spacing: -.03em; margin: 14px 0 2px; }
386
+ .tier-price small { font-family: "Inter", sans-serif; font-size: 14px; font-weight: 500; color: var(--muted); letter-spacing: 0; }
387
+ .tier .react { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; color: var(--ok); }
388
+ .tier .react svg { width: 16px; height: 16px; flex: none; }
389
+ .tier .list { flex: 1; margin-bottom: 22px; }
390
+ .ladder { display: grid; grid-template-columns: repeat(6, 1fr); gap: 6px; align-items: end; }
391
+ .ladder div { border-radius: 12px; padding: 12px 10px; text-align: center; border: 1px solid var(--line); background: color-mix(in srgb, var(--panel-solid) 55%, transparent); transition: all .3s; }
392
+ .ladder div b { display: block; font-family: "Manrope", sans-serif; font-size: 20px; }
393
+ .ladder div span { font-size: 11.5px; color: var(--muted); }
394
+ .ladder div.on { border-color: var(--brand); background: color-mix(in srgb, var(--brand) 16%, transparent); box-shadow: 0 10px 30px -12px var(--glow); }
395
+ .ladder div.on b { color: var(--brand-2); }
396
+ @media (max-width: 680px) { .ladder { grid-template-columns: repeat(3, 1fr); } }
397
+
398
+ /* ---------- Формы ---------- */
399
+ .split { display: grid; grid-template-columns: 1.15fr .85fr; gap: 22px; align-items: start; }
400
+ @media (max-width: 960px) { .split { grid-template-columns: 1fr; } }
401
+ .field { display: grid; gap: 6px; margin-bottom: 14px; }
402
+ .field label { font-size: 12.5px; font-weight: 600; color: var(--muted); }
403
+ .row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
404
+ @media (max-width: 560px) { .row2 { grid-template-columns: 1fr; } }
405
+ input[type="text"], input[type="email"], input[type="number"], select {
406
+ width: 100%; padding: 12px 14px; border-radius: 12px; border: 1px solid var(--line-strong);
407
+ background: var(--field); color: var(--text); font: inherit; font-size: 14px; outline: none;
408
+ transition: border-color .2s, box-shadow .2s;
409
+ }
410
+ input:focus, select:focus { border-color: var(--brand); box-shadow: 0 0 0 4px color-mix(in srgb, var(--brand) 18%, transparent); }
411
+ input[type="range"] { width: 100%; accent-color: var(--brand); height: 28px; }
412
+ .seg { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; padding: 5px; border-radius: 14px; border: 1px solid var(--line); background: var(--field); }
413
+ .seg button { padding: 10px 8px; border: 0; border-radius: 10px; background: none; cursor: pointer; font-weight: 650; font-size: 13px; color: var(--muted); transition: all .2s; }
414
+ .seg button small { display: block; font-weight: 500; font-size: 11.5px; }
415
+ .seg button.on { background: linear-gradient(135deg, var(--brand), #2563eb); color: #fff; box-shadow: 0 8px 20px -10px var(--glow); }
416
+ .summary { position: sticky; top: 92px; }
417
+ .sum-total { font-family: "Manrope", sans-serif; font-size: clamp(2rem, 3.4vw, 2.8rem); font-weight: 800; letter-spacing: -.03em; line-height: 1.05; margin: 6px 0 2px; }
418
+ .sum-lines { display: grid; gap: 10px; margin: 18px 0; padding: 16px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); font-size: 13.5px; }
419
+ .sum-lines div { display: flex; justify-content: space-between; gap: 16px; }
420
+ .sum-lines span { color: var(--muted); }
421
+ .sum-lines b { text-align: right; }
422
+ .note { font-size: 13px; color: var(--text-2); line-height: 1.55; }
423
+ .status { margin-top: 12px; font-size: 13px; color: var(--text-2); }
424
+ .status a { font-weight: 700; }
425
+ .lock-card { display: grid; place-items: center; text-align: center; padding: 50px 26px; }
426
+
427
+ /* ---------- Франшиза и карта ---------- */
428
+ .stats { display: grid; grid-template-columns: repeat(5, 1fr); gap: 14px; }
429
+ @media (max-width: 1080px) { .stats { grid-template-columns: repeat(3, 1fr); } }
430
+ @media (max-width: 640px) { .stats { grid-template-columns: repeat(2, 1fr); } }
431
+ .stat { padding: 18px 20px; border-radius: 18px; border: 1px solid var(--line); background: var(--panel); backdrop-filter: blur(18px); }
432
+ .stat b { display: block; font-family: "Manrope", sans-serif; font-size: 26px; font-weight: 800; letter-spacing: -.02em; }
433
+ .stat span { font-size: 12.5px; color: var(--muted); }
434
+
435
+ .map-layout { display: grid; grid-template-columns: minmax(0, 1fr) 380px; gap: 18px; align-items: start; }
436
+ @media (max-width: 1100px) { .map-layout { grid-template-columns: 1fr; } }
437
+ .map-card { padding: 16px; }
438
+ .map-tools { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
439
+ .chips { display: flex; gap: 6px; flex-wrap: wrap; }
440
+ .chip {
441
+ padding: 7px 12px; border-radius: 999px; border: 1px solid var(--line-strong); cursor: pointer;
442
+ background: color-mix(in srgb, var(--panel-solid) 50%, transparent); font-size: 12.5px; font-weight: 600; color: var(--text-2);
443
+ transition: all .2s;
444
+ }
445
+ .chip:hover { border-color: var(--brand); color: var(--text); }
446
+ .chip.on { background: var(--brand); border-color: var(--brand); color: #fff; }
447
+ .map-box {
448
+ position: relative; border-radius: 16px; overflow: hidden; touch-action: none;
449
+ background:
450
+ radial-gradient(ellipse at 50% 40%, color-mix(in srgb, var(--brand) 7%, transparent), transparent 70%),
451
+ color-mix(in srgb, var(--bg-2) 70%, transparent);
452
+ border: 1px solid var(--line);
453
+ }
454
+ #russiaMapSvg { display: block; width: 100%; height: auto; aspect-ratio: 1000 / 551; cursor: grab; user-select: none; }
455
+ #russiaMapSvg.dragging { cursor: grabbing; }
456
+ .rg { fill: var(--map-empty); stroke: var(--map-stroke); stroke-width: .7; vector-effect: non-scaling-stroke; stroke-linejoin: round; cursor: pointer; transition: fill .35s ease, opacity .35s ease; }
457
+ .rg.l0 { fill: var(--m0); }
458
+ .rg.l1 { fill: var(--m1); }
459
+ .rg.l2 { fill: var(--m2); }
460
+ .rg.l3 { fill: var(--m3); }
461
+ .rg.l4 { fill: var(--m4); }
462
+ .rg.l5 { fill: var(--m5); }
463
+ .rg.dim { opacity: .22; }
464
+ .rg-hover { fill: color-mix(in srgb, #ffffff 22%, transparent); stroke: #fff; stroke-width: 1.6; vector-effect: non-scaling-stroke; pointer-events: none; }
465
+ html[data-theme="light"] .rg-hover { fill: color-mix(in srgb, var(--brand) 25%, transparent); stroke: #0a1220; }
466
+ .rg-sel { fill: color-mix(in srgb, var(--warn) 40%, transparent); stroke: var(--warn); stroke-width: 2.2; vector-effect: non-scaling-stroke; pointer-events: none; filter: drop-shadow(0 0 6px color-mix(in srgb, var(--warn) 70%, transparent)); }
467
+ .map-dot { fill: var(--m5); stroke: var(--map-stroke); stroke-width: 1; vector-effect: non-scaling-stroke; cursor: pointer; }
468
+ .map-dot.l0 { fill: var(--danger); }
469
+ .map-label { fill: var(--text); font-family: "Inter", sans-serif; font-weight: 600; text-anchor: middle; pointer-events: none; paint-order: stroke; stroke: var(--bg); stroke-width: 3px; stroke-linejoin: round; transition: opacity .3s; }
470
+ .map-labels { opacity: 0; transition: opacity .35s; }
471
+ .map-labels.show { opacity: 1; }
472
+ .hq-pin { pointer-events: none; }
473
+ .hq-pin .halo { fill: var(--warn); opacity: .25; animation: halo 2.4s ease-out infinite; transform-box: fill-box; transform-origin: center; }
474
+ @keyframes halo { from { transform: scale(.6); opacity: .5; } to { transform: scale(2.4); opacity: 0; } }
475
+ .sel-pin .halo { fill: var(--warn); animation: halo 1.8s ease-out infinite; transform-box: fill-box; transform-origin: center; }
476
+ .map-zoom { position: absolute; right: 12px; top: 12px; display: grid; gap: 6px; }
477
+ .map-zoom .icon-btn { width: 34px; height: 34px; background: var(--panel-strong); backdrop-filter: blur(10px); }
478
+ .map-legend { position: absolute; left: 14px; bottom: 12px; padding: 10px 12px; border-radius: 12px; background: var(--panel-strong); border: 1px solid var(--line); backdrop-filter: blur(10px); font-size: 11.5px; color: var(--muted); }
479
+ .legend-bar { display: flex; gap: 2px; margin: 6px 0 4px; }
480
+ .legend-bar i { width: 26px; height: 8px; border-radius: 2px; }
481
+ .legend-scale { display: flex; justify-content: space-between; gap: 8px; }
482
+ .map-tip {
483
+ position: absolute; z-index: 5; pointer-events: none; min-width: 190px;
484
+ padding: 11px 13px; border-radius: 12px; background: var(--panel-solid); border: 1px solid var(--line-strong);
485
+ box-shadow: var(--shadow); font-size: 12.5px; opacity: 0; transform: translateY(4px); transition: opacity .15s, transform .15s;
486
+ }
487
+ .map-tip.show { opacity: 1; transform: none; }
488
+ .map-tip b { display: block; font-size: 13.5px; margin-bottom: 4px; }
489
+ .map-tip .r { display: flex; justify-content: space-between; gap: 12px; color: var(--muted); }
490
+ .map-tip .r em { font-style: normal; color: var(--text); font-weight: 600; }
491
+ .map-hint { font-size: 12px; color: var(--muted); margin-top: 10px; display: flex; gap: 16px; flex-wrap: wrap; }
492
+
493
+ .reg-panel { position: sticky; top: 92px; }
494
+ .reg-name { font-size: 24px; margin: 8px 0 2px; line-height: 1.15; }
495
+ .vacancy { display: flex; align-items: center; gap: 18px; margin: 18px 0; padding: 16px; border-radius: 16px; background: color-mix(in srgb, var(--panel-solid) 60%, transparent); border: 1px solid var(--line); }
496
+ .ringp { width: 76px; height: 76px; flex: none; }
497
+ .ringp circle { fill: none; stroke-width: 8; }
498
+ .ringp .bg { stroke: var(--line-strong); }
499
+ .ringp .fg { stroke: var(--ok); stroke-linecap: round; transition: stroke-dashoffset .6s cubic-bezier(.2,.8,.2,1); transform: rotate(-90deg); transform-origin: center; }
500
+ .ringp text { fill: var(--text); font-family: "Manrope", sans-serif; font-weight: 800; font-size: 20px; text-anchor: middle; dominant-baseline: central; }
501
+ .kv { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 16px; }
502
+ .kv div { padding: 11px 13px; border-radius: 13px; border: 1px solid var(--line); }
503
+ .kv span { display: block; font-size: 11.5px; color: var(--muted); }
504
+ .kv b { font-size: 15px; }
505
+
506
+ .table-wrap { max-height: 520px; overflow: auto; border-radius: 16px; border: 1px solid var(--line); }
507
+ table.t { width: 100%; border-collapse: collapse; font-size: 13.5px; }
508
+ .t th, .t td { padding: 12px 14px; text-align: left; border-bottom: 1px solid var(--line); white-space: nowrap; }
509
+ .t th { position: sticky; top: 0; z-index: 1; background: var(--panel-solid); color: var(--muted); font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; cursor: pointer; user-select: none; }
510
+ .t th.num, .t td.num { text-align: right; }
511
+ .t th .arr { opacity: .4; margin-left: 4px; }
512
+ .t th.sorted .arr { opacity: 1; color: var(--brand-2); }
513
+ .t tbody tr { cursor: pointer; transition: background .15s; }
514
+ .t tbody tr:hover { background: color-mix(in srgb, var(--brand) 7%, transparent); }
515
+ .t tbody tr.on { background: color-mix(in srgb, var(--warn) 12%, transparent); }
516
+ .bar { display: inline-flex; align-items: center; gap: 10px; }
517
+ .bar i { display: block; width: 80px; height: 6px; border-radius: 6px; background: var(--line-strong); overflow: hidden; }
518
+ .bar i::after { content: ""; display: block; height: 100%; width: var(--p, 0%); background: linear-gradient(90deg, var(--ok), #86efac); border-radius: 6px; }
519
+ .bar.zero i::after { background: var(--danger); width: 100%; opacity: .5; }
520
+
521
+ .calc-out { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-top: 14px; }
522
+ .calc-out div { padding: 14px; border-radius: 14px; border: 1px solid var(--line); background: color-mix(in srgb, var(--panel-solid) 50%, transparent); }
523
+ .calc-out b { display: block; font-family: "Manrope", sans-serif; font-size: 22px; }
524
+ .calc-out span { font-size: 12px; color: var(--muted); }
525
+ @media (max-width: 640px) { .calc-out { grid-template-columns: 1fr; } }
526
+
527
+ /* ---------- Поддержка ---------- */
528
+ .console { font-family: ui-monospace, "JetBrains Mono", Consolas, monospace; font-size: 12.5px; white-space: pre-wrap; background: var(--field); border: 1px solid var(--line); border-radius: 14px; padding: 14px; min-height: 180px; max-height: 300px; overflow: auto; color: var(--text-2); }
529
+ .channels { display: flex; gap: 8px; }
530
+ .contact-row { display: flex; gap: 14px; align-items: flex-start; padding: 12px 0; border-bottom: 1px solid var(--line); }
531
+ .contact-row:last-child { border-bottom: 0; }
532
+ .contact-row svg { width: 20px; height: 20px; color: var(--brand-2); flex: none; margin-top: 2px; }
533
+
534
+ /* ---------- ИИ-агент сервера (виджет) ---------- */
535
+ .ai-fab {
536
+ position: fixed; right: 24px; bottom: 24px; z-index: 50;
537
+ display: flex; align-items: center; gap: 10px; padding: 8px 18px 8px 8px; border-radius: 999px; cursor: pointer;
538
+ border: 1px solid color-mix(in srgb, var(--brand) 50%, transparent);
539
+ background: var(--panel-strong); backdrop-filter: blur(16px);
540
+ box-shadow: 0 18px 50px -14px var(--glow); font-weight: 700; font-size: 14px;
541
+ transition: transform .2s;
542
+ }
543
+ .ai-fab:hover { transform: translateY(-2px); }
544
+ .ai-fab img { width: 36px; height: 36px; }
545
+ .ai-fab .live { width: 8px; height: 8px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 10px var(--ok); }
546
+ .ai-drawer {
547
+ position: fixed; right: 24px; bottom: 88px; z-index: 50; width: 410px; max-width: calc(100vw - 32px);
548
+ height: 580px; max-height: calc(100vh - 120px);
549
+ display: flex; flex-direction: column; overflow: hidden;
550
+ border-radius: 22px; border: 1px solid var(--line-strong); background: var(--panel-strong);
551
+ backdrop-filter: blur(24px) saturate(140%); box-shadow: 0 40px 100px -20px rgba(0,0,0,.6);
552
+ opacity: 0; transform: translateY(16px) scale(.98); pointer-events: none; transition: opacity .25s, transform .3s cubic-bezier(.2,.8,.2,1);
553
+ }
554
+ .ai-drawer.open { opacity: 1; transform: none; pointer-events: auto; }
555
+ .ai-head { display: flex; align-items: center; gap: 12px; padding: 14px 16px; border-bottom: 1px solid var(--line); }
556
+ .ai-head img { width: 34px; height: 34px; }
557
+ .ai-head b { display: block; font-size: 14px; }
558
+ .ai-head span { font-size: 12px; color: var(--ok); }
559
+ .ai-head .icon-btn { margin-left: auto; width: 32px; height: 32px; }
560
+ .ai-msgs { flex: 1; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 10px; }
561
+ .msg { max-width: 88%; padding: 11px 14px; border-radius: 16px; font-size: 13.5px; line-height: 1.55; white-space: pre-wrap; word-wrap: break-word; }
562
+ .msg.bot { align-self: flex-start; background: color-mix(in srgb, var(--panel-solid) 85%, transparent); border: 1px solid var(--line); border-bottom-left-radius: 5px; }
563
+ .msg.me { align-self: flex-end; color: #fff; background: linear-gradient(135deg, var(--brand), #2563eb); border-bottom-right-radius: 5px; }
564
+ .typing { display: inline-flex; gap: 4px; }
565
+ .typing i { width: 6px; height: 6px; border-radius: 50%; background: var(--muted); animation: typ 1.2s infinite; }
566
+ .typing i:nth-child(2) { animation-delay: .15s; }
567
+ .typing i:nth-child(3) { animation-delay: .3s; }
568
+ @keyframes typ { 0%, 60%, 100% { opacity: .3; transform: none; } 30% { opacity: 1; transform: translateY(-3px); } }
569
+ .ai-sugg { display: flex; gap: 6px; padding: 8px 12px; overflow-x: auto; border-top: 1px solid var(--line); scrollbar-width: none; }
570
+ .ai-sugg button { flex: none; padding: 6px 11px; border-radius: 999px; border: 1px solid var(--line-strong); background: none; cursor: pointer; font-size: 12px; color: var(--text-2); }
571
+ .ai-sugg button:hover { border-color: var(--brand); color: var(--text); }
572
+ .ai-input { display: flex; gap: 8px; padding: 12px; border-top: 1px solid var(--line); }
573
+ .ai-input input { border-radius: 999px; }
574
+ .ai-input .btn { border-radius: 999px; width: 44px; padding: 0; }
575
+
576
+ /* ---------- Модальное окно ---------- */
577
+ .modal { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center; padding: 16px; background: rgba(2, 4, 10, .6); backdrop-filter: blur(10px); opacity: 0; pointer-events: none; transition: opacity .25s; }
578
+ .modal.open { opacity: 1; pointer-events: auto; }
579
+ .modal .card { width: 100%; max-width: 460px; transform: translateY(10px) scale(.98); transition: transform .3s cubic-bezier(.2,.8,.2,1); }
580
+ .modal.open .card { transform: none; }
581
+ .modal-head { display: flex; align-items: center; gap: 14px; margin-bottom: 14px; }
582
+ .modal-head img { width: 46px; height: 46px; }
583
+
584
+ /* ---------- Подвал ---------- */
585
+ .footer { margin-top: 70px; padding-top: 34px; border-top: 1px solid var(--line); display: grid; grid-template-columns: 1.3fr 1fr 1fr; gap: 30px; font-size: 13px; color: var(--muted); }
586
+ .footer h4 { margin: 0 0 10px; color: var(--text); font-size: 14px; }
587
+ .footer p { margin: 4px 0; }
588
+ .footer .brand-name { color: var(--text); }
589
+ .footer-bottom { margin-top: 26px; display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; font-size: 12px; color: var(--muted); }
590
+ @media (max-width: 860px) { .footer { grid-template-columns: 1fr; } }
591
+
592
+ @media (max-width: 1400px) {
593
+ .brand-sub { display: none; }
594
+ }
595
+ @media (max-width: 1180px) {
596
+ .topbar { grid-template-columns: auto 1fr; }
597
+ .tabs { grid-column: 1 / -1; grid-row: 2; justify-self: stretch; }
598
+ .brand-sub { display: none; }
599
+ }
600
+ @media (max-width: 640px) {
601
+ .shell { padding: 0 16px 40px; }
602
+ .topbar { margin: 0 -16px; padding: 10px 16px; }
603
+ .top-actions .btn-primary { display: none; }
604
+ .ai-fab span.t { display: none; }
605
+ .ai-fab { padding: 6px; }
606
+ }
607
+ @media (prefers-reduced-motion: reduce) {
608
+ *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
609
+ }