DxrkMonteva commited on
Commit
209f324
·
verified ·
1 Parent(s): 1705f2d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +543 -321
app.py CHANGED
@@ -8,7 +8,7 @@ HTML_PAGE = """<!DOCTYPE html>
8
  <head>
9
  <meta charset="UTF-8">
10
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
11
- <title>LiquidUI — Жидкие интерфейсы</title>
12
  <link href="https://fonts.googleapis.com/css2?family=Syne:wght@400;700;800&family=DM+Sans:ital,wght@0,300;0,400;1,300&display=swap" rel="stylesheet">
13
  <style>
14
  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
@@ -16,7 +16,8 @@ HTML_PAGE = """<!DOCTYPE html>
16
  --bg: #060811; --bg2: #0c1020; --surface: rgba(255,255,255,0.04);
17
  --border: rgba(255,255,255,0.08); --text: #e8e8f0;
18
  --muted: rgba(232,232,240,0.45); --accent: #7c6dff;
19
- --accent2: #00d4ff; --accent3: #ff5fa0;
 
20
  }
21
  html { scroll-behavior: smooth; }
22
  body {
@@ -46,7 +47,7 @@ header {
46
  }
47
  .hero-sub {
48
  font-size: clamp(1rem, 2.5vw, 1.35rem); color: var(--muted);
49
- max-width: 500px; position: relative; z-index: 1;
50
  margin-bottom: 2.5rem; font-style: italic;
51
  }
52
  .hero-badge {
@@ -56,23 +57,14 @@ header {
56
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent);
57
  margin-bottom: 2rem; position: relative; z-index: 1;
58
  }
59
- .hero-badge::before {
60
- content: ''; width: 6px; height: 6px; border-radius: 50%;
61
- background: var(--accent); box-shadow: 0 0 8px var(--accent);
62
- animation: pulse-glow 2s ease-in-out infinite;
63
- }
64
  .scroll-hint {
65
  position: absolute; bottom: 40px; left: 50%; transform: translateX(-50%);
66
  display: flex; flex-direction: column; align-items: center; gap: 8px;
67
  color: var(--muted); font-size: 0.75rem; letter-spacing: 0.15em;
68
- text-transform: uppercase; animation: float-char 2s ease-in-out infinite;
69
  z-index: 1;
70
  }
71
- .scroll-hint::after {
72
- content: ''; width: 1px; height: 40px;
73
- background: linear-gradient(to bottom, var(--muted), transparent);
74
- }
75
- main { max-width: 1100px; margin: 0 auto; padding: 0 24px 120px; }
76
  .section { margin-bottom: 100px; }
77
  .section-label {
78
  font-size: 0.7rem; letter-spacing: 0.2em; text-transform: uppercase;
@@ -103,371 +95,579 @@ main { max-width: 1100px; margin: 0 auto; padding: 0 24px 120px; }
103
  }
104
  .btn-secondary { background: transparent; border: 1.5px solid var(--border); color: var(--text); }
105
  .btn-glow { background: var(--accent3); color: #fff; box-shadow: 0 0 20px rgba(255,95,160,0.4); }
106
- .glass-panel {
107
- background: rgba(255,255,255,0.04);
108
- backdrop-filter: blur(24px) saturate(1.5);
109
- -webkit-backdrop-filter: blur(24px) saturate(1.5);
110
- border: 1px solid rgba(255,255,255,0.12);
111
- border-radius: 24px; padding: 40px; position: relative; overflow: hidden;
112
- }
113
- .glass-title { font-family: 'Syne', sans-serif; font-size: 1.5rem; font-weight: 800; margin-bottom: 10px; }
114
- .glass-body { color: var(--muted); font-size: 0.9rem; max-width: 340px; line-height: 1.7; }
115
- .morph-showcase {
116
- display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 24px;
117
- }
118
- .morph-item {
119
- aspect-ratio: 1; display: flex; align-items: center; justify-content: center;
120
- font-size: 1.8rem; border: none; cursor: default;
121
- }
122
- .mercury-row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; justify-content: center; }
123
- .merc-blob {
124
- width: 72px; height: 72px; border-radius: 50%;
125
- display: flex; align-items: center; justify-content: center;
126
- font-size: 1.5rem; color: #fff; cursor: pointer; position: relative;
127
- }
128
- .aurora-box {
129
- border-radius: 24px; padding: 50px 40px;
130
- background: rgba(5, 5, 15, 0.95); border: 1px solid rgba(255,255,255,0.08);
131
- text-align: center; position: relative; overflow: hidden;
132
- }
133
- .aurora-box h3 {
134
- font-family: 'Syne', sans-serif; font-size: 1.6rem; font-weight: 800;
135
- margin-bottom: 10px; position: relative; z-index: 1;
136
- }
137
- .aurora-box p { color: var(--muted); font-size: 0.9rem; position: relative; z-index: 1; }
138
- .ripple-card {
139
- padding: 40px;
140
- background: linear-gradient(135deg, rgba(0,212,255,0.1), rgba(124,109,255,0.12));
141
- border: 1px solid rgba(0,212,255,0.2); border-radius: 20px;
142
- text-align: center; cursor: pointer; overflow: hidden; position: relative;
143
- }
144
- .ripple-card h3 { font-family: 'Syne', sans-serif; font-size: 1.3rem; font-weight: 700; margin-bottom: 8px; }
145
- .ripple-card p { color: var(--muted); font-size: 0.88rem; }
146
- .tilt-card {
147
- background: linear-gradient(135deg, rgba(255,95,160,0.08), rgba(124,109,255,0.1));
148
- border: 1px solid rgba(255,95,160,0.15); border-radius: 24px;
149
- padding: 36px; position: relative; overflow: hidden;
150
- transition: transform 0.15s ease, box-shadow 0.15s ease;
151
- transform-style: preserve-3d;
152
- }
153
- .tilt-card h3 { font-family: 'Syne', sans-serif; font-size: 1.2rem; font-weight: 700; margin-bottom: 8px; }
154
- .warp-text-demo {
155
- font-family: 'Syne', sans-serif; font-size: clamp(2rem, 5vw, 3.5rem);
156
- font-weight: 800; text-align: center; padding: 40px;
157
- background: var(--surface); border-radius: 20px; border: 1px solid var(--border);
158
- background: linear-gradient(135deg, rgba(124,109,255,0.1), rgba(0,212,255,0.08));
159
- }
160
- .warp-text-demo span { display: inline-block; animation: float-char 2s ease-in-out infinite; }
161
- .lava-box {
162
- height: 200px; border-radius: 24px;
163
- background: rgba(10,10,20,0.9); border: 1px solid var(--border);
164
- display: flex; align-items: center; justify-content: center;
165
- position: relative; overflow: hidden;
166
- }
167
- .lava-box span {
168
- font-family: 'Syne', sans-serif; font-weight: 800; font-size: 1.4rem;
169
- position: relative; z-index: 10; color: rgba(255,255,255,0.8);
170
- letter-spacing: 0.1em; text-transform: uppercase;
171
- }
172
- .ink-box {
173
- height: 220px; background: #f5f0e8; border-radius: 20px;
174
- display: flex; align-items: center; justify-content: center;
175
- cursor: crosshair; overflow: hidden; position: relative;
176
- }
177
- .ink-box span {
178
- font-family: 'Syne', sans-serif; font-weight: 800; font-size: 1.1rem;
179
- color: #1a1a2e; letter-spacing: 0.15em; text-transform: uppercase;
180
- pointer-events: none; position: relative; z-index: 10;
181
- }
182
- .demo-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 20px; }
183
  .demo-card {
184
  background: var(--surface); border: 1px solid var(--border); border-radius: 20px;
185
  padding: 32px 24px; display: flex; flex-direction: column; align-items: center;
186
- gap: 14px; text-align: center;
187
  }
188
  .demo-card .tag {
189
  font-size: 0.68rem; letter-spacing: 0.15em; text-transform: uppercase;
190
  color: var(--muted); margin-top: auto; font-family: 'Syne', sans-serif;
191
  }
 
 
 
 
 
 
192
  .code-block {
193
  background: rgba(0,0,0,0.5); border: 1px solid rgba(255,255,255,0.07);
194
  border-radius: 14px; padding: 24px 28px; font-family: 'Courier New', monospace;
195
- font-size: 0.82rem; color: #a8c8ff; line-height: 1.8; overflow-x: auto; margin-top: 20px;
196
  }
197
- footer {
198
- border-top: 1px solid var(--border); padding: 40px 24px;
199
- text-align: center; color: var(--muted); font-size: 0.82rem; letter-spacing: 0.05em;
200
- }
201
- footer strong { color: var(--text); font-family: 'Syne', sans-serif; }
202
 
203
- @keyframes pulse-glow {
204
- 0%, 100% { box-shadow: 0 0 8px 2px currentColor; }
205
- 50% { box-shadow: 0 0 24px 8px currentColor; }
206
- }
207
- @keyframes float-char {
208
- 0%, 100% { transform: translateY(0px) rotate(0deg); }
209
- 50% { transform: translateY(-6px) rotate(2deg); }
210
- }
211
- @keyframes ripple-anim {
212
- to { transform: scale(4); opacity: 0; }
213
- }
214
- @keyframes ink-spread {
215
- 0% { transform: scale(0); opacity: 0.85; }
216
- 100% { transform: scale(20); opacity: 0; }
217
- }
218
- @keyframes aurora {
219
- 0% { transform: rotate(0deg) scale(1); }
220
- 50% { transform: rotate(180deg) scale(1.1); }
221
- 100% { transform: rotate(360deg) scale(1); }
222
- }
223
- @keyframes morph {
224
- 0%, 100% { border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%; }
225
- 50% { border-radius: 30% 60% 70% 40% / 50% 60% 30% 60%; }
226
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  </style>
228
  </head>
229
  <body>
230
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
  <header>
232
  <div class="hero-bg"></div>
233
- <div class="hero-badge">v1.0 · Zero Dependencies</div>
234
  <h1 class="hero-title">LiquidUI</h1>
235
- <p class="hero-sub">Библиотека жидких интерфейсов — просто добавь data-liquid</p>
236
  <div class="btn-row" style="justify-content:center; position:relative; z-index:1;">
237
- <button class="btn btn-primary" onclick="document.getElementById('effects').scrollIntoView()">Смотреть эффекты</button>
238
- <button class="btn btn-secondary" onclick="document.getElementById('usage').scrollIntoView()">Как использовать</button>
 
239
  </div>
240
  <div class="scroll-hint">scroll</div>
241
  </header>
242
 
243
  <main>
244
 
 
245
  <section class="section" id="effects">
246
- <span class="section-label">01 — Jelly</span>
247
- <h2 class="section-title">Желеобразные кнопки</h2>
248
- <p class="section-desc">Элементы деформируются как мягкий желатин — тянутся, сжимаются, пружинят.</p>
249
  <div class="divider"></div>
250
- <div class="btn-row">
251
- <button class="btn btn-primary jelly-btn">Нажми меня 🫧</button>
252
- <button class="btn btn-secondary jelly-btn">Потяни сюда</button>
253
- <button class="btn btn-glow jelly-btn">Упругий!</button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
  </div>
255
  </section>
256
 
 
257
  <section class="section">
258
- <span class="section-label">02Liquid Glass</span>
259
- <h2 class="section-title">Жидкое стекло</h2>
260
- <p class="section-desc">Панели с эффектом преломления света и frosted-glass бликом.</p>
261
  <div class="divider"></div>
262
- <div style="background: linear-gradient(135deg, #0a0520, #0d1832); border-radius: 24px; padding: 40px; position:relative; overflow:hidden;">
263
- <div style="position:absolute;inset:0;background:radial-gradient(ellipse 60% 60% at 20% 30%, rgba(124,109,255,0.25),transparent),radial-gradient(ellipse 50% 50% at 80% 70%,rgba(0,212,255,0.2),transparent);pointer-events:none;"></div>
264
- <div class="glass-panel glass-effect">
265
- <div class="glass-title">Жидкое стекло ✦</div>
266
- <div class="glass-body">Наведи мышь — увидишь бегущий световой блик и кольцо преломления.</div>
267
- <div style="margin-top:24px;">
268
- <button class="btn btn-primary jelly-btn" style="background:rgba(255,255,255,0.15); backdrop-filter:blur(10px); border:1px solid rgba(255,255,255,0.2);">Действие</button>
269
- </div>
 
 
 
 
 
 
 
 
 
270
  </div>
271
  </div>
272
  </section>
273
 
 
274
  <section class="section">
275
- <span class="section-label">03Morph Blob</span>
276
- <h2 class="section-title">Органичные формы</h2>
277
- <p class="section-desc">Непрерывная морфинг-анимация border-radius создаёт живые формы.</p>
278
  <div class="divider"></div>
279
- <div class="morph-showcase">
280
- <div class="morph-item morph-blob" style="background:linear-gradient(135deg,rgba(124,109,255,0.6),rgba(0,212,255,0.4));">🫧</div>
281
- <div class="morph-item morph-blob" style="background:linear-gradient(135deg,rgba(255,95,160,0.6),rgba(255,180,50,0.4));animation-delay:-0.5s;">🌊</div>
282
- <div class="morph-item morph-blob" style="background:linear-gradient(135deg,rgba(0,255,150,0.5),rgba(0,180,255,0.4));animation-delay:-1s;">💧</div>
283
- <div class="morph-item morph-blob" style="background:linear-gradient(135deg,rgba(255,200,50,0.6),rgba(255,95,60,0.5));animation-delay:-1.5s;">🔥</div>
284
- <div class="morph-item morph-blob" style="background:linear-gradient(135deg,rgba(180,80,255,0.6),rgba(80,80,255,0.4));animation-delay:-2s;"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
285
  </div>
286
  </section>
287
 
 
288
  <section class="section">
289
- <span class="section-label">04Mercury</span>
290
- <h2 class="section-title">Ртутные капли</h2>
291
- <p class="section-desc">Элементы с эффектом слияния как капли ртути.</p>
292
  <div class="divider"></div>
293
- <div class="mercury-row">
294
- <div class="merc-blob mercury-item" style="background:radial-gradient(circle at 35% 35%, #b0c4ff, #5060ff);">🌕</div>
295
- <div class="merc-blob mercury-item" style="background:radial-gradient(circle at 35% 35%, #ffb0d0, #ff50a0);">🌑</div>
296
- <div class="merc-blob mercury-item" style="background:radial-gradient(circle at 35% 35%, #b0ffda, #40d080);"></div>
297
- <div class="merc-blob mercury-item" style="background:radial-gradient(circle at 35% 35%, #ffe0a0, #ff9020);">🟡</div>
 
 
298
  </div>
 
299
  </section>
300
 
 
301
  <section class="section">
302
- <span class="section-label">05Aurora</span>
303
- <h2 class="section-title">Северное сияние</h2>
304
- <p class="section-desc">Живые переливающиеся фоны — плазменная аура.</p>
305
  <div class="divider"></div>
306
- <div class="aurora-box aurora-effect">
307
- <div class="aurora-bg"></div>
308
- <h3>Северное сияние</h3>
309
- <p>Радиальные градиенты вращаются и пульсируют</p>
310
- <div style="margin-top: 24px; position:relative; z-index:1;">
311
- <button class="btn jelly-btn" style="background:rgba(255,255,255,0.1); border:1px solid rgba(255,255,255,0.2); color:#fff;">Атмосферно ✦</button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
312
  </div>
313
  </div>
314
  </section>
315
 
 
316
  <section class="section">
317
- <span class="section-label">06Ripple</span>
318
- <h2 class="section-title">Рябь на воде</h2>
319
- <p class="section-desc">Кликни — и из точки прикосновения расходится волна.</p>
320
  <div class="divider"></div>
321
- <div class="ripple-card ripple-effect" onclick="createRipple(event, this)">
322
- <h3>👆 Кликни в любом месте</h3>
323
- <p>Отсюда расходятся водяные кольца</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
324
  </div>
325
  </section>
326
 
 
327
  <section class="section">
328
- <span class="section-label">07Surface Tension</span>
329
- <h2 class="section-title">Поверхностное натяжение</h2>
330
- <p class="section-desc">3D-наклон карточки следует за курсором.</p>
331
  <div class="divider"></div>
332
- <div style="display:grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap:20px;">
333
- <div class="tilt-card tilt-effect" data-intensity="18">
334
- <h3>Карточка продукта</h3>
335
- <p style="color:var(--muted); font-size:0.88rem; margin-top:8px;">Наведи мышь — она живёт в 3D</p>
336
- <div style="font-size:3rem; margin-top:16px;">💎</div>
 
 
 
 
337
  </div>
338
- <div class="tilt-card tilt-effect" data-intensity="12" style="background:linear-gradient(135deg, rgba(0,212,255,0.08), rgba(124,109,255,0.1)); border-color:rgba(0,212,255,0.15);">
339
- <h3>Статистика</h3>
340
- <div style="font-family:'Syne',sans-serif; font-size:3rem; font-weight:800; margin:16px 0; background:linear-gradient(135deg,#00d4ff,#7c6dff);-webkit-background-clip:text;-webkit-text-fill-color:transparent;">98%</div>
 
 
 
 
 
 
 
 
341
  </div>
342
  </div>
343
  </section>
344
 
 
345
  <section class="section">
346
- <span class="section-label">08Warp Text</span>
347
- <h2 class="section-title">Плавающий текст</h2>
348
- <p class="section-desc">Каждая буква качается независимо.</p>
349
  <div class="divider"></div>
350
- <div class="warp-text-demo" id="warpText">LIQUID</div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
351
  </section>
352
 
 
353
  <section class="section">
354
- <span class="section-label">09Magnetic</span>
355
- <h2 class="section-title">Магнитное притяжение</h2>
356
- <p class="section-desc">Элемент тянется к курсору как намагниченный.</p>
357
  <div class="divider"></div>
358
- <div class="btn-row" style="justify-content:center; padding:60px 0;">
359
- <button class="btn btn-primary magnetic-btn" data-strength="0.4" style="font-size:1.1rem; padding:18px 48px; background:linear-gradient(135deg,var(--accent),var(--accent3));">🧲 Притянись</button>
360
- <button class="btn btn-secondary magnetic-btn" data-strength="0.25">Слабый магнит</button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
361
  </div>
362
  </section>
363
 
 
364
  <section class="section">
365
- <span class="section-label">10Lava Lamp</span>
366
- <h2 class="section-title">Лавовая лампа</h2>
367
- <p class="section-desc">Медленные пузыри дрейфуют и переливаются.</p>
368
  <div class="divider"></div>
369
- <div class="lava-box lava-effect" id="lavaLamp">
370
- <span>Lava Lamp 🌋</span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
371
  </div>
372
  </section>
373
 
 
374
  <section class="section">
375
- <span class="section-label">11Ink Drop</span>
376
- <h2 class="section-title">Капля чернил</h2>
377
- <p class="section-desc">Кликни — чернильная капля разливается и тает.</p>
378
  <div class="divider"></div>
379
- <div class="ink-box ink-effect" id="inkBox" onclick="createInk(event, this)">
380
- <span>👆 Капни чернилами</span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
381
  </div>
382
  </section>
383
 
384
- <section class="section" id="usage">
 
385
  <span class="section-label">API</span>
386
  <h2 class="section-title">Как использовать</h2>
387
- <p class="section-desc">Просто добавь класс — никаких зависимостей.</p>
388
  <div class="divider"></div>
 
389
  <div class="code-block">
390
- &lt;!-- Добавь класс к любому элементу --&gt;
391
- &lt;button class="jelly-btn"&gt;Кнопка&lt;/button&gt;
392
- &lt;div class="morph-blob"&gt;...&lt;/div&gt;
393
- &lt;div class="glass-effect"&gt;...&lt;/div&gt;
394
- &lt;div class="tilt-effect"&gt;...&lt;/div&gt;
395
-
396
- &lt;!-- Доступные эффекты --&gt;
397
- jelly-btn · morph-blob · glass-effect · mercury-item
398
- ripple-effect · tilt-effect · magnetic-btn · aurora-effect
399
- lava-effect · ink-effect · warp-text
 
 
 
 
 
 
 
 
 
400
  </div>
401
  </section>
402
 
403
  </main>
404
 
405
  <footer>
406
- <strong>LiquidUI</strong> · 11 эффектов · Нет зависимостей · MIT License<br>
407
- <span style="margin-top:8px;display:block;">Подключи · Добавь класс · Готово</span>
408
  </footer>
409
 
410
  <script>
411
- // Jelly effect
412
- document.querySelectorAll('.jelly-btn').forEach(btn => {
413
- btn.style.transition = 'transform 0.08s cubic-bezier(0.34,1.56,0.64,1)';
414
- btn.style.transformOrigin = 'center';
415
-
416
- let scaleX = 1, scaleY = 1, targetX = 1, targetY = 1;
417
- let animId = null;
418
-
419
- function tick() {
420
- scaleX += (targetX - scaleX) * 0.18;
421
- scaleY += (targetY - scaleY) * 0.18;
422
- btn.style.transform = `scaleX(${scaleX.toFixed(4)}) scaleY(${scaleY.toFixed(4)})`;
423
- if (Math.abs(scaleX - targetX) > 0.001 || Math.abs(scaleY - targetY) > 0.001) {
424
- animId = requestAnimationFrame(tick);
425
- } else animId = null;
426
- }
427
-
428
- btn.addEventListener('mouseenter', () => { targetX = 1.08; targetY = 0.94; if (!animId) animId = requestAnimationFrame(tick); });
429
- btn.addEventListener('mouseleave', () => { targetX = 1; targetY = 1; if (!animId) animId = requestAnimationFrame(tick); });
430
- btn.addEventListener('mousedown', () => { targetX = 0.92; targetY = 1.1; if (!animId) animId = requestAnimationFrame(tick); });
431
- btn.addEventListener('mouseup', () => { targetX = 1.12; targetY = 0.88; if (!animId) animId = requestAnimationFrame(tick); setTimeout(() => { targetX = 1; targetY = 1; if (!animId) animId = requestAnimationFrame(tick); }, 150); });
432
- });
433
-
434
- // Morph blob
435
- document.querySelectorAll('.morph-blob').forEach((blob, i) => {
436
- blob.style.animation = `morph 4s ease-in-out infinite`;
437
- blob.style.animationDelay = `${-i * 0.5}s`;
438
- });
439
-
440
- // Mercury
441
- document.querySelectorAll('.mercury-item').forEach(item => {
442
- item.style.transition = 'transform 0.3s cubic-bezier(0.34,1.56,0.64,1)';
443
- item.addEventListener('mouseenter', () => item.style.transform = 'scale(1.18)');
444
- item.addEventListener('mouseleave', () => item.style.transform = 'scale(1)');
445
- });
446
-
447
- // Aurora
448
- document.querySelectorAll('.aurora-effect').forEach(box => {
449
- const bg = document.createElement('div');
450
- bg.style.cssText = 'position:absolute;inset:-50%;pointer-events:none;background:radial-gradient(ellipse at 20% 50%,rgba(120,80,255,0.5) 0%,transparent 60%),radial-gradient(ellipse at 80% 20%,rgba(0,220,255,0.4) 0%,transparent 55%),radial-gradient(ellipse at 60% 80%,rgba(255,80,180,0.35) 0%,transparent 50%),radial-gradient(ellipse at 40% 30%,rgba(80,255,180,0.3) 0%,transparent 50%);animation:aurora 8s ease-in-out infinite;filter:blur(30px);z-index:0;';
451
- box.insertBefore(bg, box.firstChild);
452
  });
453
 
454
- // Ripple
455
- function createRipple(e, el) {
456
- const r = el.getBoundingClientRect();
457
- const x = e.clientX - r.left, y = e.clientY - r.top;
458
- const ripple = document.createElement('span');
459
- ripple.style.cssText = `position:absolute;border-radius:50%;pointer-events:none;width:100px;height:100px;left:${x-50}px;top:${y-50}px;background:radial-gradient(circle,rgba(255,255,255,0.6) 0%,transparent 70%);transform:scale(0);opacity:1;animation:ripple-anim 0.6s ease-out forwards;`;
460
- el.appendChild(ripple);
461
- setTimeout(() => ripple.remove(), 600);
462
- }
463
-
464
- // Tilt
465
- document.querySelectorAll('.tilt-effect').forEach(card => {
466
- const intensity = parseFloat(card.dataset.intensity) || 15;
467
  card.addEventListener('mousemove', e => {
468
  const r = card.getBoundingClientRect();
469
  const x = (e.clientX - r.left) / r.width - 0.5;
470
  const y = (e.clientY - r.top) / r.height - 0.5;
 
471
  card.style.transform = `perspective(600px) rotateX(${-y * intensity}deg) rotateY(${x * intensity}deg) scale(1.02)`;
472
  });
473
  card.addEventListener('mouseleave', () => {
@@ -475,62 +675,84 @@ document.querySelectorAll('.tilt-effect').forEach(card => {
475
  });
476
  });
477
 
478
- // Warp text
479
- const warpText = document.getElementById('warpText');
480
- if (warpText) {
481
- const text = warpText.textContent;
482
- warpText.innerHTML = '';
483
- text.split('').forEach((ch, i) => {
484
- const span = document.createElement('span');
485
- span.textContent = ch;
486
- span.style.animationDelay = `${i * 0.1}s`;
487
- warpText.appendChild(span);
 
 
 
 
 
488
  });
489
  }
490
 
491
- // Magnetic
492
- document.querySelectorAll('.magnetic-btn').forEach(btn => {
493
- const strength = parseFloat(btn.dataset.strength) || 0.35;
494
- btn.style.transition = 'transform 0.2s cubic-bezier(0.22,1,0.36,1)';
495
- btn.addEventListener('mousemove', e => {
496
- const r = btn.getBoundingClientRect();
497
- const cx = r.left + r.width/2, cy = r.top + r.height/2;
498
- btn.style.transform = `translate(${(e.clientX-cx)*strength}px,${(e.clientY-cy)*strength}px)`;
 
499
  });
500
- btn.addEventListener('mouseleave', () => btn.style.transform = 'translate(0,0)');
501
- });
502
 
503
- // Lava lamp
504
- const lavaLamp = document.getElementById('lavaLamp');
505
- if (lavaLamp) {
506
- const colors = ['rgba(255,80,120,0.6)', 'rgba(80,180,255,0.5)', 'rgba(180,80,255,0.5)'];
507
- for (let i = 0; i < 3; i++) {
508
- const blob = document.createElement('div');
509
- const size = 60 + Math.random() * 60;
510
- blob.style.cssText = `position:absolute;border-radius:50%;width:${size}px;height:${size}px;background:${colors[i]};filter:blur(${size*0.4}px);animation:float-char ${6+Math.random()*4}s ease-in-out infinite;animation-delay:${-Math.random()*5}s;left:${Math.random()*80}%;top:${Math.random()*80}%;`;
511
- lavaLamp.appendChild(blob);
512
  }
513
  }
514
 
515
- // Ink
516
- function createInk(e, el) {
517
- const r = el.getBoundingClientRect();
518
- const x = e.clientX - r.left, y = e.clientY - r.top;
519
- const colors = ['#1a1a2e', '#16213e', '#0f3460', '#533483'];
520
- const ink = document.createElement('div');
521
- ink.style.cssText = `position:absolute;border-radius:50%;width:30px;height:30px;left:${x-15}px;top:${y-15}px;background:${colors[Math.floor(Math.random()*colors.length)]};transform:scale(0);opacity:0.8;animation:ink-spread 1.5s ease-out forwards;filter:blur(4px);pointer-events:none;`;
522
- el.appendChild(ink);
523
- setTimeout(() => ink.remove(), 1500);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
524
  }
525
 
526
- // Glass shimmer
527
- document.querySelectorAll('.glass-effect').forEach(el => {
528
- const shimmer = document.createElement('div');
529
- shimmer.style.cssText = 'position:absolute;inset:0;pointer-events:none;background:linear-gradient(135deg,transparent 40%,rgba(255,255,255,0.2) 50%,transparent 60%);opacity:0;transition:opacity 0.5s,transform 0.6s;transform:translateX(-100%) skewX(-15deg);';
530
- el.appendChild(shimmer);
531
- el.addEventListener('mouseenter', () => { shimmer.style.opacity = '1'; shimmer.style.transform = 'translateX(120%) skewX(-15deg)'; });
532
- el.addEventListener('mouseleave', () => { shimmer.style.opacity = '0'; shimmer.style.transform = 'translateX(-100%) skewX(-15deg)'; });
533
- });
534
  </script>
535
 
536
  </body>
 
8
  <head>
9
  <meta charset="UTF-8">
10
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
11
+ <title>LiquidUI v2.0 40+ Жидких Эффектов</title>
12
  <link href="https://fonts.googleapis.com/css2?family=Syne:wght@400;700;800&family=DM+Sans:ital,wght@0,300;0,400;1,300&display=swap" rel="stylesheet">
13
  <style>
14
  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
 
16
  --bg: #060811; --bg2: #0c1020; --surface: rgba(255,255,255,0.04);
17
  --border: rgba(255,255,255,0.08); --text: #e8e8f0;
18
  --muted: rgba(232,232,240,0.45); --accent: #7c6dff;
19
+ --accent2: #00d4ff; --accent3: #ff5fa0; --accent4: #ffaa00;
20
+ --accent5: #00ff88; --accent6: #ff0044;
21
  }
22
  html { scroll-behavior: smooth; }
23
  body {
 
47
  }
48
  .hero-sub {
49
  font-size: clamp(1rem, 2.5vw, 1.35rem); color: var(--muted);
50
+ max-width: 600px; position: relative; z-index: 1;
51
  margin-bottom: 2.5rem; font-style: italic;
52
  }
53
  .hero-badge {
 
57
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent);
58
  margin-bottom: 2rem; position: relative; z-index: 1;
59
  }
 
 
 
 
 
60
  .scroll-hint {
61
  position: absolute; bottom: 40px; left: 50%; transform: translateX(-50%);
62
  display: flex; flex-direction: column; align-items: center; gap: 8px;
63
  color: var(--muted); font-size: 0.75rem; letter-spacing: 0.15em;
64
+ text-transform: uppercase; animation: float 2s ease-in-out infinite;
65
  z-index: 1;
66
  }
67
+ main { max-width: 1200px; margin: 0 auto; padding: 0 24px 120px; }
 
 
 
 
68
  .section { margin-bottom: 100px; }
69
  .section-label {
70
  font-size: 0.7rem; letter-spacing: 0.2em; text-transform: uppercase;
 
95
  }
96
  .btn-secondary { background: transparent; border: 1.5px solid var(--border); color: var(--text); }
97
  .btn-glow { background: var(--accent3); color: #fff; box-shadow: 0 0 20px rgba(255,95,160,0.4); }
98
+ .btn-gold { background: linear-gradient(135deg, #ffaa00, #ff6600); color: #fff; }
99
+ .btn-cyber { background: linear-gradient(135deg, #00ff88, #0088ff); color: #000; }
100
+ .btn-dark { background: #1a1a2e; border: 2px solid #333; color: #fff; }
101
+
102
+ /* Grid layouts */
103
+ .effects-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 24px; }
104
+ .mini-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 16px; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  .demo-card {
106
  background: var(--surface); border: 1px solid var(--border); border-radius: 20px;
107
  padding: 32px 24px; display: flex; flex-direction: column; align-items: center;
108
+ gap: 14px; text-align: center; position: relative; overflow: hidden;
109
  }
110
  .demo-card .tag {
111
  font-size: 0.68rem; letter-spacing: 0.15em; text-transform: uppercase;
112
  color: var(--muted); margin-top: auto; font-family: 'Syne', sans-serif;
113
  }
114
+ .glass-panel {
115
+ background: rgba(255,255,255,0.04);
116
+ backdrop-filter: blur(24px) saturate(1.5);
117
+ border: 1px solid rgba(255,255,255,0.12);
118
+ border-radius: 24px; padding: 40px; position: relative; overflow: hidden;
119
+ }
120
  .code-block {
121
  background: rgba(0,0,0,0.5); border: 1px solid rgba(255,255,255,0.07);
122
  border-radius: 14px; padding: 24px 28px; font-family: 'Courier New', monospace;
123
+ font-size: 0.82rem; color: #a8c8ff; line-height: 1.8; overflow-x: auto;
124
  }
 
 
 
 
 
125
 
126
+ /* ========== 40+ EFFECTS ========== */
127
+
128
+ /* 1-5: ELASTIC */
129
+ .elastic-btn { transition: transform 0.1s cubic-bezier(0.34,1.56,0.64,1); transform-origin: center; }
130
+ .elastic-btn:hover { transform: scale(1.05, 0.95); }
131
+ .elastic-btn:active { transform: scale(0.95, 1.05); }
132
+
133
+ .bounce-btn { animation: bounce 2s infinite; }
134
+ @keyframes bounce { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }
135
+
136
+ .pulse-btn { animation: pulse-scale 2s ease-in-out infinite; }
137
+ @keyframes pulse-scale { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.05); } }
138
+
139
+ .wobble-btn:hover { animation: wobble 0.8s ease; }
140
+ @keyframes wobble { 0% { transform: rotate(0); } 25% { transform: rotate(-5deg) scale(1.1); } 75% { transform: rotate(5deg) scale(0.9); } 100% { transform: rotate(0); } }
141
+
142
+ .jelly-intense { filter: url('#goo'); transition: all 0.3s; }
143
+
144
+ /* 6-10: MORPH */
145
+ .morph-blob { animation: morph 4s ease-in-out infinite; border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%; }
146
+ @keyframes morph { 0%, 100% { border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%; } 50% { border-radius: 30% 60% 70% 40% / 50% 60% 30% 60%; } }
147
+
148
+ .morph-square { animation: morph-square 5s ease-in-out infinite; }
149
+ @keyframes morph-square { 0%, 100% { border-radius: 20px; } 50% { border-radius: 50% 20% 40% 60%; } }
150
+
151
+ .liquid-shape { animation: liquid-morph 6s ease-in-out infinite; }
152
+ @keyframes liquid-morph { 0%, 100% { clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); } 25% { clip-path: polygon(60% 10%, 90% 40%, 40% 90%, 10% 60%); } 50% { clip-path: polygon(40% 20%, 80% 30%, 60% 80%, 20% 70%); } 75% { clip-path: polygon(70% 0%, 100% 60%, 30% 100%, 0% 40%); } }
153
+
154
+ .amoeba { animation: amoeba 8s ease-in-out infinite; filter: url('#goo'); }
155
+ @keyframes amoeba { 0%, 100% { border-radius: 40% 60% 70% 30% / 40% 50% 60% 50%; transform: rotate(0deg); } 33% { border-radius: 60% 40% 30% 70% / 60% 30% 40% 60%; transform: rotate(120deg); } 66% { border-radius: 30% 60% 70% 40% / 50% 60% 30% 60%; transform: rotate(240deg); } }
156
+
157
+ /* 11-15: GLASS */
158
+ .glass-frost { backdrop-filter: blur(20px) saturate(180%); background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.2); }
159
+ .glass-dark { backdrop-filter: blur(30px); background: rgba(0,0,0,0.3); border: 1px solid rgba(255,255,255,0.1); }
160
+ .glass-gradient { backdrop-filter: blur(25px); background: linear-gradient(135deg, rgba(255,255,255,0.1), rgba(255,255,255,0.05)); }
161
+ .glass-chrome { backdrop-filter: blur(15px) brightness(1.2); background: linear-gradient(135deg, rgba(255,255,255,0.2), rgba(255,255,255,0.05), rgba(255,255,255,0.15)); border: 2px solid rgba(255,255,255,0.3); }
162
+ .glass-neon { backdrop-filter: blur(20px); background: rgba(124,109,255,0.15); border: 2px solid var(--accent); box-shadow: 0 0 30px rgba(124,109,255,0.3), inset 0 0 20px rgba(124,109,255,0.1); }
163
+
164
+ /* 16-20: MAGNETIC */
165
+ .magnetic { transition: transform 0.2s cubic-bezier(0.22,1,0.36,1); }
166
+ .magnetic-strong { transition: transform 0.15s cubic-bezier(0.22,1,0.36,1); }
167
+ .magnetic-elastic { transition: transform 0.4s cubic-bezier(0.68,-0.55,0.265,1.55); }
168
+ .magnetic-smooth { transition: transform 0.6s cubic-bezier(0.16,1,0.3,1); }
169
+ .magnetic-snap { transition: transform 0.1s; }
170
+
171
+ /* 21-25: RIPPLE */
172
+ .ripple { position: relative; overflow: hidden; }
173
+ .ripple-dark { position: relative; overflow: hidden; }
174
+ .ripple-color { position: relative; overflow: hidden; }
175
+ .ripple-glow { position: relative; overflow: hidden; }
176
+ .ripple-multi { position: relative; overflow: hidden; }
177
+
178
+ /* 26-30: TILT */
179
+ .tilt-3d { transform-style: preserve-3d; transition: transform 0.15s; }
180
+ .tilt-glare { transform-style: preserve-3d; transition: transform 0.15s; position: relative; }
181
+ .tilt-glare::after { content: ''; position: absolute; inset: 0; background: linear-gradient(135deg, rgba(255,255,255,0.4) 0%, transparent 50%, transparent 100%); opacity: 0; transition: opacity 0.3s; pointer-events: none; }
182
+ .tilt-glare:hover::after { opacity: 1; }
183
+ .tilt-parallax { transform-style: preserve-3d; transition: transform 0.2s; }
184
+ .tilt-parallax .parallax-layer { transform: translateZ(20px); }
185
+ .tilt-mirror { transform-style: preserve-3d; transition: transform 0.15s; }
186
+
187
+ /* 31-35: PARTICLES */
188
+ .particle-float { position: relative; }
189
+ .particle-float::before { content: ''; position: absolute; width: 4px; height: 4px; background: var(--accent); border-radius: 50%; animation: particle-rise 3s infinite; }
190
+ @keyframes particle-rise { 0% { transform: translateY(100px) scale(0); opacity: 0; } 50% { opacity: 1; } 100% { transform: translateY(-100px) scale(0); opacity: 0; } }
191
+
192
+ .particle-orbit { position: relative; }
193
+ .particle-orbit::before, .particle-orbit::after { content: ''; position: absolute; width: 6px; height: 6px; background: var(--accent2); border-radius: 50%; animation: orbit 4s linear infinite; }
194
+ @keyframes orbit { 0% { transform: rotate(0deg) translateX(30px) rotate(0deg); } 100% { transform: rotate(360deg) translateX(30px) rotate(-360deg); } }
195
+
196
+ .particle-trail { position: relative; overflow: hidden; }
197
+ .particle-sparkle { position: relative; }
198
+ .particle-sparkle::after { content: '✦'; position: absolute; color: var(--accent3); animation: sparkle 2s ease-in-out infinite; }
199
+ @keyframes sparkle { 0%, 100% { opacity: 0; transform: scale(0) rotate(0deg); } 50% { opacity: 1; transform: scale(1) rotate(180deg); } }
200
+
201
+ .particle-dust { position: relative; }
202
+
203
+ /* 36-40: SPECIAL */
204
+ .glitch-hover:hover { animation: glitch 0.3s infinite; }
205
+ @keyframes glitch { 0% { transform: translate(0); } 20% { transform: translate(-2px, 2px); } 40% { transform: translate(-2px, -2px); } 60% { transform: translate(2px, 2px); } 80% { transform: translate(2px, -2px); } 100% { transform: translate(0); } }
206
+
207
+ .scanline { position: relative; }
208
+ .scanline::after { content: ''; position: absolute; inset: 0; background: repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(0,0,0,0.1) 2px, rgba(0,0,0,0.1) 4px); pointer-events: none; }
209
+
210
+ .crt { position: relative; animation: flicker 0.15s infinite; }
211
+ @keyframes flicker { 0%, 100% { opacity: 1; } 50% { opacity: 0.98; } }
212
+ .crt::before { content: ''; position: absolute; inset: 0; background: radial-gradient(ellipse at center, transparent 60%, rgba(0,0,0,0.4) 100%); pointer-events: none; }
213
+
214
+ .hologram { position: relative; background: linear-gradient(135deg, rgba(0,255,255,0.1), rgba(255,0,255,0.1)); border: 2px solid rgba(0,255,255,0.5); animation: hologram-flicker 4s infinite; }
215
+ @keyframes hologram-flicker { 0%, 100% { opacity: 1; } 50% { opacity: 0.8; } 75% { opacity: 0.95; } }
216
+
217
+ .neon-pulse { animation: neon-glow 2s ease-in-out infinite alternate; }
218
+ @keyframes neon-glow { 0% { box-shadow: 0 0 5px var(--accent), 0 0 10px var(--accent), 0 0 20px var(--accent); } 100% { box-shadow: 0 0 10px var(--accent), 0 0 20px var(--accent), 0 0 40px var(--accent), 0 0 80px var(--accent); } }
219
+
220
+ /* 41-45: TEXT EFFECTS */
221
+ .text-wave span { display: inline-block; animation: wave 2s ease-in-out infinite; }
222
+ @keyframes wave { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }
223
+
224
+ .text-shake:hover { animation: shake 0.5s; }
225
+ @keyframes shake { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-5px); } 75% { transform: translateX(5px); } }
226
+
227
+ .text-gradient { background: linear-gradient(90deg, var(--accent), var(--accent2), var(--accent3), var(--accent)); background-size: 300% 100%; -webkit-background-clip: text; -webkit-text-fill-color: transparent; animation: gradient-shift 3s ease infinite; }
228
+ @keyframes gradient-shift { 0%, 100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } }
229
+
230
+ .text-glow { text-shadow: 0 0 10px currentColor, 0 0 20px currentColor, 0 0 40px currentColor; }
231
+ .text-3d { text-shadow: 1px 1px 0 #000, 2px 2px 0 #000, 3px 3px 0 #000, 4px 4px 0 #000, 5px 5px 0 #000; }
232
+
233
+ /* 46-50: INTERACTIVE */
234
+ .drag-elastic { cursor: grab; user-select: none; }
235
+ .drag-elastic:active { cursor: grabbing; }
236
+
237
+ .squeeze-hover:hover { animation: squeeze 0.4s; }
238
+ @keyframes squeeze { 0%, 100% { transform: scale(1, 1); } 50% { transform: scale(1.1, 0.9); } }
239
+
240
+ .flip-hover { transition: transform 0.6s; transform-style: preserve-3d; }
241
+ .flip-hover:hover { transform: rotateY(180deg); }
242
+
243
+ .rotate-hover:hover { animation: rotate-once 0.6s ease; }
244
+ @keyframes rotate-once { 0% { transform: rotate(0); } 100% { transform: rotate(360deg); } }
245
+
246
+ .skew-hover:hover { transform: skew(-10deg, 5deg); transition: transform 0.3s; }
247
+
248
+ /* SVG Filters */
249
+ svg.filters { position: absolute; width: 0; height: 0; }
250
  </style>
251
  </head>
252
  <body>
253
 
254
+ <svg class="filters">
255
+ <defs>
256
+ <filter id="goo">
257
+ <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur"/>
258
+ <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9" result="goo"/>
259
+ <feComposite in="SourceGraphic" in2="goo" operator="atop"/>
260
+ </filter>
261
+ <filter id="noise">
262
+ <feTurbulence type="fractalNoise" baseFrequency="0.65" numOctaves="3" stitchTiles="stitch"/>
263
+ </filter>
264
+ </defs>
265
+ </svg>
266
+
267
  <header>
268
  <div class="hero-bg"></div>
269
+ <div class="hero-badge">v2.0 · 40+ Effects · Zero Dependencies</div>
270
  <h1 class="hero-title">LiquidUI</h1>
271
+ <p class="hero-sub">Первая в мире библиотека жидких интерфейсов. От эластичных кнопок до голограмм — просто добавь класс.</p>
272
  <div class="btn-row" style="justify-content:center; position:relative; z-index:1;">
273
+ <button class="btn btn-primary elastic-btn" onclick="document.getElementById('effects').scrollIntoView()">Исследовать эффекты</button>
274
+ <button class="btn btn-secondary bounce-btn">Прыгающая кнопка</button>
275
+ <button class="btn btn-glow neon-pulse">Неоновый пульс</button>
276
  </div>
277
  <div class="scroll-hint">scroll</div>
278
  </header>
279
 
280
  <main>
281
 
282
+ <!-- ========== ELASTIC & BOUNCE ========== -->
283
  <section class="section" id="effects">
284
+ <span class="section-label">01-05Elastic Family</span>
285
+ <h2 class="section-title">Эластичные элементы</h2>
286
+ <p class="section-desc">Физика упругости: сжатие, растяжение, пружинный отскок.</p>
287
  <div class="divider"></div>
288
+
289
+ <div class="effects-grid">
290
+ <div class="demo-card">
291
+ <button class="btn btn-primary elastic-btn">Elastic Press</button>
292
+ <div class="tag">elastic-btn</div>
293
+ </div>
294
+ <div class="demo-card">
295
+ <button class="btn btn-secondary bounce-btn">Bounce</button>
296
+ <div class="tag">bounce-btn</div>
297
+ </div>
298
+ <div class="demo-card">
299
+ <button class="btn btn-glow pulse-btn">Pulse Scale</button>
300
+ <div class="tag">pulse-btn</div>
301
+ </div>
302
+ <div class="demo-card">
303
+ <button class="btn btn-gold wobble-btn">Wobble</button>
304
+ <div class="tag">wobble-btn</div>
305
+ </div>
306
+ <div class="demo-card" style="filter: url('#goo');">
307
+ <button class="btn btn-cyber jelly-intense">Intense Jelly</button>
308
+ <div class="tag">jelly-intense + goo</div>
309
+ </div>
310
  </div>
311
  </section>
312
 
313
+ <!-- ========== MORPH SHAPES ========== -->
314
  <section class="section">
315
+ <span class="section-label">06-10Morphing Shapes</span>
316
+ <h2 class="section-title">Живые формы</h2>
317
+ <p class="section-desc">Органичная трансформация границ через CSS и clip-path.</p>
318
  <div class="divider"></div>
319
+
320
+ <div class="effects-grid">
321
+ <div class="demo-card morph-blob" style="background: linear-gradient(135deg, var(--accent), var(--accent2)); min-height: 150px;">
322
+ <span style="font-size: 2rem;">🫧</span>
323
+ <div class="tag">morph-blob</div>
324
+ </div>
325
+ <div class="demo-card morph-square" style="background: linear-gradient(135deg, var(--accent3), var(--accent4)); min-height: 150px;">
326
+ <span style="font-size: 2rem;">🔷</span>
327
+ <div class="tag">morph-square</div>
328
+ </div>
329
+ <div class="demo-card liquid-shape" style="background: linear-gradient(135deg, var(--accent5), var(--accent)); min-height: 150px; width: 150px; margin: 0 auto;">
330
+ <span style="font-size: 2rem;">💧</span>
331
+ <div class="tag">liquid-shape</div>
332
+ </div>
333
+ <div class="demo-card amoeba" style="background: linear-gradient(135deg, var(--accent6), var(--accent3)); min-height: 150px; filter: url('#goo');">
334
+ <span style="font-size: 2rem;">🦠</span>
335
+ <div class="tag">amoeba + goo</div>
336
  </div>
337
  </div>
338
  </section>
339
 
340
+ <!-- ========== GLASS FAMILY ========== -->
341
  <section class="section">
342
+ <span class="section-label">11-15Glass Effects</span>
343
+ <h2 class="section-title">Стеклянные панели</h2>
344
+ <p class="section-desc">Backdrop-filter магия: frosted, chrome, neon glass.</p>
345
  <div class="divider"></div>
346
+
347
+ <div style="background: linear-gradient(135deg, #1a0b2e, #0d1832); border-radius: 24px; padding: 40px;">
348
+ <div class="effects-grid">
349
+ <div class="demo-card glass-frost">
350
+ <h3 style="font-family: 'Syne', sans-serif;">Frosted</h3>
351
+ <p style="font-size: 0.8rem; color: var(--muted);">Размытие + насыщенность</p>
352
+ <div class="tag">glass-frost</div>
353
+ </div>
354
+ <div class="demo-card glass-dark">
355
+ <h3 style="font-family: 'Syne', sans-serif;">Dark Glass</h3>
356
+ <p style="font-size: 0.8rem; color: var(--muted);">Тёмное стекло</p>
357
+ <div class="tag">glass-dark</div>
358
+ </div>
359
+ <div class="demo-card glass-gradient">
360
+ <h3 style="font-family: 'Syne', sans-serif;">Gradient</h3>
361
+ <p style="font-size: 0.8rem; color: var(--muted);">Градиентное стекло</p>
362
+ <div class="tag">glass-gradient</div>
363
+ </div>
364
+ <div class="demo-card glass-chrome">
365
+ <h3 style="font-family: 'Syne', sans-serif;">Chrome</h3>
366
+ <p style="font-size: 0.8rem; color: var(--muted);">Хромированное</p>
367
+ <div class="tag">glass-chrome</div>
368
+ </div>
369
+ <div class="demo-card glass-neon">
370
+ <h3 style="font-family: 'Syne', sans-serif;">Neon Glass</h3>
371
+ <p style="font-size: 0.8rem; color: var(--muted);">Неоновое свечение</p>
372
+ <div class="tag">glass-neon</div>
373
+ </div>
374
+ </div>
375
  </div>
376
  </section>
377
 
378
+ <!-- ========== MAGNETIC ========== -->
379
  <section class="section">
380
+ <span class="section-label">16-20Magnetic Attraction</span>
381
+ <h2 class="section-title">Магнитное притяжение</h2>
382
+ <p class="section-desc">Элементы тянутся к курсору с разной силой и физикой.</p>
383
  <div class="divider"></div>
384
+
385
+ <div class="btn-row" style="justify-content: center; gap: 40px; padding: 60px 0;">
386
+ <button class="btn btn-primary magnetic" data-strength="0.3">Soft</button>
387
+ <button class="btn btn-glow magnetic-strong" data-strength="0.6">Strong</button>
388
+ <button class="btn btn-gold magnetic-elastic" data-strength="0.4">Elastic</button>
389
+ <button class="btn btn-cyber magnetic-smooth" data-strength="0.5">Smooth</button>
390
+ <button class="btn btn-dark magnetic-snap" data-strength="0.8">Snap</button>
391
  </div>
392
+ <div style="text-align: center; color: var(--muted); font-size: 0.8rem;">Наведи на кнопки — они притянутся к мыши</div>
393
  </section>
394
 
395
+ <!-- ========== RIPPLE EFFECTS ========== -->
396
  <section class="section">
397
+ <span class="section-label">21-25Ripple & Waves</span>
398
+ <h2 class="section-title">Волны и рябь</h2>
399
+ <p class="section-desc">Кликай — создавай волны разных цветов и интенсивности.</p>
400
  <div class="divider"></div>
401
+
402
+ <div class="effects-grid">
403
+ <div class="demo-card ripple" onclick="createRipple(event, this, '#fff')" style="background: var(--surface);">
404
+ <h3>White Ripple</h3>
405
+ <div class="tag">ripple</div>
406
+ </div>
407
+ <div class="demo-card ripple-dark" onclick="createRipple(event, this, '#000')" style="background: #fff; color: #000;">
408
+ <h3>Dark Ripple</h3>
409
+ <div class="tag">ripple-dark</div>
410
+ </div>
411
+ <div class="demo-card ripple-color" onclick="createRipple(event, this, 'var(--accent)')" style="background: var(--surface);">
412
+ <h3>Color Ripple</h3>
413
+ <div class="tag">ripple-color</div>
414
+ </div>
415
+ <div class="demo-card ripple-glow" onclick="createRipple(event, this, 'var(--accent3)')" style="background: var(--surface);">
416
+ <h3>Glow Ripple</h3>
417
+ <div class="tag">ripple-glow</div>
418
+ </div>
419
+ <div class="demo-card ripple-multi" onclick="createMultiRipple(event, this)" style="background: var(--surface);">
420
+ <h3>Multi Ripple</h3>
421
+ <div class="tag">ripple-multi</div>
422
  </div>
423
  </div>
424
  </section>
425
 
426
+ <!-- ========== 3D TILT ========== -->
427
  <section class="section">
428
+ <span class="section-label">26-303D Tilt</span>
429
+ <h2 class="section-title">3D наклон и блики</h2>
430
+ <p class="section-desc">Карточки реагируют на мышь с параллаксом и бликами.</p>
431
  <div class="divider"></div>
432
+
433
+ <div class="effects-grid">
434
+ <div class="demo-card tilt-3d" style="background: linear-gradient(135deg, rgba(124,109,255,0.2), rgba(0,212,255,0.1));">
435
+ <h3>Basic 3D</h3>
436
+ <div class="tag">tilt-3d</div>
437
+ </div>
438
+ <div class="demo-card tilt-glare" style="background: linear-gradient(135deg, rgba(255,95,160,0.2), rgba(124,109,255,0.1));">
439
+ <h3>With Glare</h3>
440
+ <div class="tag">tilt-glare</div>
441
+ </div>
442
+ <div class="demo-card tilt-parallax" style="background: linear-gradient(135deg, rgba(0,255,136,0.2), rgba(0,136,255,0.1));">
443
+ <div class="parallax-layer">
444
+ <h3>Parallax</h3>
445
+ <p style="font-size: 0.8rem;">Layer 1</p>
446
+ </div>
447
+ <div class="tag">tilt-parallax</div>
448
+ </div>
449
+ <div class="demo-card tilt-mirror" style="background: linear-gradient(135deg, rgba(255,170,0,0.2), rgba(255,0,68,0.1));">
450
+ <h3>Mirror</h3>
451
+ <div class="tag">tilt-mirror</div>
452
+ </div>
453
  </div>
454
  </section>
455
 
456
+ <!-- ========== PARTICLES ========== -->
457
  <section class="section">
458
+ <span class="section-label">31-35Particle Effects</span>
459
+ <h2 class="section-title">Частицы и свечение</h2>
460
+ <p class="section-desc">Микронимации: всплывающие частицы, орбиты, искры.</p>
461
  <div class="divider"></div>
462
+
463
+ <div class="effects-grid">
464
+ <div class="demo-card particle-float" style="overflow: hidden;">
465
+ <h3>Float Up</h3>
466
+ <div class="tag">particle-float</div>
467
+ </div>
468
+ <div class="demo-card particle-orbit">
469
+ <h3>Orbit</h3>
470
+ <div class="tag">particle-orbit</div>
471
  </div>
472
+ <div class="demo-card particle-trail" id="trailCard">
473
+ <h3>Mouse Trail</h3>
474
+ <div class="tag">particle-trail (hover)</div>
475
+ </div>
476
+ <div class="demo-card particle-sparkle">
477
+ <h3>Sparkle</h3>
478
+ <div class="tag">particle-sparkle</div>
479
+ </div>
480
+ <div class="demo-card particle-dust" id="dustCard">
481
+ <h3>Dust Field</h3>
482
+ <div class="tag">particle-dust</div>
483
  </div>
484
  </div>
485
  </section>
486
 
487
+ <!-- ========== GLITCH & RETRO ========== -->
488
  <section class="section">
489
+ <span class="section-label">36-40Glitch & Retro</span>
490
+ <h2 class="section-title">Глитч и ретро-эффекты</h2>
491
+ <p class="section-desc">Цифровые артефакты: глитч, сканлайны, CRT, голограммы.</p>
492
  <div class="divider"></div>
493
+
494
+ <div class="effects-grid">
495
+ <div class="demo-card glitch-hover" style="background: #1a1a2e;">
496
+ <h3>Glitch</h3>
497
+ <div class="tag">glitch-hover</div>
498
+ </div>
499
+ <div class="demo-card scanline" style="background: linear-gradient(135deg, #0a0a1a, #1a0a2e);">
500
+ <h3>Scanlines</h3>
501
+ <div class="tag">scanline</div>
502
+ </div>
503
+ <div class="demo-card crt" style="background: #0a0a0a; color: #0f0;">
504
+ <h3>CRT Monitor</h3>
505
+ <div class="tag">crt</div>
506
+ </div>
507
+ <div class="demo-card hologram">
508
+ <h3>Hologram</h3>
509
+ <div class="tag">hologram</div>
510
+ </div>
511
+ <div class="demo-card neon-pulse" style="background: var(--surface); border: 2px solid var(--accent);">
512
+ <h3>Neon Pulse</h3>
513
+ <div class="tag">neon-pulse</div>
514
+ </div>
515
+ </div>
516
  </section>
517
 
518
+ <!-- ========== TEXT EFFECTS ========== -->
519
  <section class="section">
520
+ <span class="section-label">41-45Text Effects</span>
521
+ <h2 class="section-title">Анимированный текст</h2>
522
+ <p class="section-desc">Буквы танцуют: волны, градиенты, тени, свечение.</p>
523
  <div class="divider"></div>
524
+
525
+ <div class="effects-grid">
526
+ <div class="demo-card">
527
+ <h2 class="text-wave" style="font-family: 'Syne', sans-serif; font-size: 2rem;">
528
+ <span style="animation-delay: 0s;">W</span><span style="animation-delay: 0.1s;">A</span><span style="animation-delay: 0.2s;">V</span><span style="animation-delay: 0.3s;">E</span>
529
+ </h2>
530
+ <div class="tag">text-wave</div>
531
+ </div>
532
+ <div class="demo-card">
533
+ <h2 class="text-shake" style="font-family: 'Syne', sans-serif; font-size: 2rem; cursor: pointer;">SHAKE</h2>
534
+ <div class="tag">text-shake (hover)</div>
535
+ </div>
536
+ <div class="demo-card">
537
+ <h2 class="text-gradient" style="font-family: 'Syne', sans-serif; font-size: 2rem;">GRADIENT</h2>
538
+ <div class="tag">text-gradient</div>
539
+ </div>
540
+ <div class="demo-card" style="background: #000;">
541
+ <h2 class="text-glow" style="font-family: 'Syne', sans-serif; font-size: 2rem; color: var(--accent2);">GLOW</h2>
542
+ <div class="tag">text-glow</div>
543
+ </div>
544
+ <div class="demo-card">
545
+ <h2 class="text-3d" style="font-family: 'Syne', sans-serif; font-size: 2rem; color: var(--text);">3D TEXT</h2>
546
+ <div class="tag">text-3d</div>
547
+ </div>
548
  </div>
549
  </section>
550
 
551
+ <!-- ========== INTERACTIVE ========== -->
552
  <section class="section">
553
+ <span class="section-label">46-50Interactive</span>
554
+ <h2 class="section-title">Интерактивные жесты</h2>
555
+ <p class="section-desc">Перетаскивание, перевороты, сжатие, вращение.</p>
556
  <div class="divider"></div>
557
+
558
+ <div class="effects-grid">
559
+ <div class="demo-card drag-elastic" id="dragCard" style="cursor: grab; background: var(--surface);">
560
+ <h3>Drag Me</h3>
561
+ <p style="font-size: 0.8rem; color: var(--muted);">Elastic drag</p>
562
+ <div class="tag">drag-elastic</div>
563
+ </div>
564
+ <div class="demo-card squeeze-hover" style="background: var(--surface);">
565
+ <h3>Squeeze</h3>
566
+ <div class="tag">squeeze-hover</div>
567
+ </div>
568
+ <div class="demo-card flip-hover" style="background: linear-gradient(135deg, var(--accent), var(--accent2)); transform-style: preserve-3d;">
569
+ <div style="backface-visibility: hidden;">
570
+ <h3>Flip</h3>
571
+ <p>Hover to flip</p>
572
+ </div>
573
+ <div style="position: absolute; inset: 0; background: var(--accent3); border-radius: 20px; transform: rotateY(180deg); backface-visibility: hidden; display: flex; align-items: center; justify-content: center;">
574
+ <h3>Back!</h3>
575
+ </div>
576
+ <div class="tag">flip-hover</div>
577
+ </div>
578
+ <div class="demo-card rotate-hover" style="background: var(--surface);">
579
+ <h3>Rotate</h3>
580
+ <div class="tag">rotate-hover</div>
581
+ </div>
582
+ <div class="demo-card skew-hover" style="background: var(--surface);">
583
+ <h3>Skew</h3>
584
+ <div class="tag">skew-hover</div>
585
+ </div>
586
  </div>
587
  </section>
588
 
589
+ <!-- ========== BONUS: COMBOS ========== -->
590
  <section class="section">
591
+ <span class="section-label">BONUSCombos</span>
592
+ <h2 class="section-title">Комбинированные эффекты</h2>
593
+ <p class="section-desc">Сочетай классы для уникальных результатов.</p>
594
  <div class="divider"></div>
595
+
596
+ <div class="effects-grid">
597
+ <div class="demo-card glass-frost morph-blob" style="background: linear-gradient(135deg, rgba(124,109,255,0.3), rgba(0,212,255,0.2));">
598
+ <h3>Glass + Morph</h3>
599
+ <div class="tag">glass-frost morph-blob</div>
600
+ </div>
601
+ <div class="demo-card magnetic tilt-3d neon-pulse" style="background: var(--surface); border: 2px solid var(--accent3);">
602
+ <h3>Magnetic + Tilt + Neon</h3>
603
+ <div class="tag">magnetic tilt-3d neon-pulse</div>
604
+ </div>
605
+ <div class="demo-card ripple particle-sparkle hologram" onclick="createRipple(event, this, '#0ff')">
606
+ <h3>Ripple + Sparkle + Hologram</h3>
607
+ <div class="tag">ripple particle-sparkle hologram</div>
608
+ </div>
609
+ <div class="demo-card elastic-btn text-gradient bounce-btn">
610
+ <h3>Elastic + Gradient + Bounce</h3>
611
+ <div class="tag">elastic-btn text-gradient bounce-btn</div>
612
+ </div>
613
  </div>
614
  </section>
615
 
616
+ <!-- ========== API ========== -->
617
+ <section class="section">
618
  <span class="section-label">API</span>
619
  <h2 class="section-title">Как использовать</h2>
 
620
  <div class="divider"></div>
621
+
622
  <div class="code-block">
623
+ &lt;!-- Подключи CSS ли скопируй в свой) --&gt;
624
+ &lt;link rel="stylesheet" href="liquidx.css"&gt;
625
+
626
+ &lt;!-- Добавь классы к элементам --&gt;
627
+ &lt;button class="elastic-btn"&gt;Кнопка&lt;/button&gt;
628
+ &lt;div class="morph-blob glass-frost"&gt;...&lt;/div&gt;
629
+ &lt;div class="magnetic tilt-3d"&gt;...&lt;/div&gt;
630
+
631
+ &lt;!-- Доступные эффекты (40+) --&gt;
632
+ ELASTIC: elastic-btn, bounce-btn, pulse-btn, wobble-btn, jelly-intense
633
+ MORPH: morph-blob, morph-square, liquid-shape, amoeba
634
+ GLASS: glass-frost, glass-dark, glass-gradient, glass-chrome, glass-neon
635
+ MAGNETIC: magnetic, magnetic-strong, magnetic-elastic, magnetic-smooth, magnetic-snap
636
+ RIPPLE: ripple, ripple-dark, ripple-color, ripple-glow, ripple-multi
637
+ TILT: tilt-3d, tilt-glare, tilt-parallax, tilt-mirror
638
+ PARTICLES: particle-float, particle-orbit, particle-trail, particle-sparkle, particle-dust
639
+ GLITCH: glitch-hover, scanline, crt, hologram, neon-pulse
640
+ TEXT: text-wave, text-shake, text-gradient, text-glow, text-3d
641
+ INTERACTIVE: drag-elastic, squeeze-hover, flip-hover, rotate-hover, skew-hover
642
  </div>
643
  </section>
644
 
645
  </main>
646
 
647
  <footer>
648
+ <strong>LiquidUI v2.0</strong> · 40+ эффектов · Масштабируемо до 500+ · MIT License<br>
649
+ <span style="margin-top:8px;display:block;">Просто добавь класс · Комбинируй · Создавай жидкие интерфейсы</span>
650
  </footer>
651
 
652
  <script>
653
+ // ========== MAGNETIC EFFECTS ==========
654
+ document.querySelectorAll('.magnetic, .magnetic-strong, .magnetic-elastic, .magnetic-smooth, .magnetic-snap').forEach(el => {
655
+ const strength = parseFloat(el.dataset.strength) || 0.3;
656
+ el.addEventListener('mousemove', e => {
657
+ const r = el.getBoundingClientRect();
658
+ const cx = r.left + r.width/2, cy = r.top + r.height/2;
659
+ el.style.transform = `translate(${(e.clientX-cx)*strength}px,${(e.clientY-cy)*strength}px)`;
660
+ });
661
+ el.addEventListener('mouseleave', () => el.style.transform = 'translate(0,0)');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
662
  });
663
 
664
+ // ========== TILT EFFECTS ==========
665
+ document.querySelectorAll('.tilt-3d, .tilt-glare, .tilt-parallax, .tilt-mirror').forEach(card => {
 
 
 
 
 
 
 
 
 
 
 
666
  card.addEventListener('mousemove', e => {
667
  const r = card.getBoundingClientRect();
668
  const x = (e.clientX - r.left) / r.width - 0.5;
669
  const y = (e.clientY - r.top) / r.height - 0.5;
670
+ const intensity = 20;
671
  card.style.transform = `perspective(600px) rotateX(${-y * intensity}deg) rotateY(${x * intensity}deg) scale(1.02)`;
672
  });
673
  card.addEventListener('mouseleave', () => {
 
675
  });
676
  });
677
 
678
+ // ========== RIPPLE EFFECTS ==========
679
+ function createRipple(e, el, color = '#fff') {
680
+ const r = el.getBoundingClientRect();
681
+ const x = e.clientX - r.left, y = e.clientY - r.top;
682
+ const ripple = document.createElement('span');
683
+ const size = Math.max(r.width, r.height) * 2;
684
+ ripple.style.cssText = `position:absolute;border-radius:50%;pointer-events:none;width:${size}px;height:${size}px;left:${x-size/2}px;top:${y-size/2}px;background:radial-gradient(circle,${color} 0%,transparent 70%);transform:scale(0);opacity:0.6;animation:ripple-anim 0.8s ease-out forwards;`;
685
+ el.appendChild(ripple);
686
+ setTimeout(() => ripple.remove(), 800);
687
+ }
688
+
689
+ function createMultiRipple(e, el) {
690
+ const colors = ['#7c6dff', '#00d4ff', '#ff5fa0', '#ffaa00'];
691
+ colors.forEach((color, i) => {
692
+ setTimeout(() => createRipple(e, el, color), i * 100);
693
  });
694
  }
695
 
696
+ // ========== PARTICLE TRAIL ==========
697
+ const trailCard = document.getElementById('trailCard');
698
+ if (trailCard) {
699
+ trailCard.addEventListener('mousemove', e => {
700
+ const r = trailCard.getBoundingClientRect();
701
+ const dot = document.createElement('div');
702
+ dot.style.cssText = `position:absolute;width:6px;height:6px;background:var(--accent2);border-radius:50%;pointer-events:none;left:${e.clientX-r.left}px;top:${e.clientY-r.top}px;animation:fade-out 1s forwards;`;
703
+ trailCard.appendChild(dot);
704
+ setTimeout(() => dot.remove(), 1000);
705
  });
706
+ }
 
707
 
708
+ // ========== DUST FIELD ==========
709
+ const dustCard = document.getElementById('dustCard');
710
+ if (dustCard && !window.matchMedia('(pointer: coarse)').matches) {
711
+ for (let i = 0; i < 20; i++) {
712
+ const dust = document.createElement('div');
713
+ dust.style.cssText = `position:absolute;width:2px;height:2px;background:rgba(255,255,255,0.3);border-radius:50%;left:${Math.random()*100}%;top:${Math.random()*100}%;animation:float ${3+Math.random()*4}s ease-in-out infinite;animation-delay:${-Math.random()*5}s;pointer-events:none;`;
714
+ dustCard.appendChild(dust);
 
 
715
  }
716
  }
717
 
718
+ // ========== DRAG ELASTIC ==========
719
+ const dragCard = document.getElementById('dragCard');
720
+ if (dragCard) {
721
+ let isDragging = false, startX, startY, currentX = 0, currentY = 0;
722
+
723
+ dragCard.addEventListener('mousedown', e => {
724
+ isDragging = true;
725
+ startX = e.clientX - currentX;
726
+ startY = e.clientY - currentY;
727
+ dragCard.style.cursor = 'grabbing';
728
+ });
729
+
730
+ document.addEventListener('mousemove', e => {
731
+ if (!isDragging) return;
732
+ currentX = e.clientX - startX;
733
+ currentY = e.clientY - startY;
734
+ dragCard.style.transform = `translate(${currentX}px, ${currentY}px)`;
735
+ });
736
+
737
+ document.addEventListener('mouseup', () => {
738
+ if (!isDragging) return;
739
+ isDragging = false;
740
+ dragCard.style.cursor = 'grab';
741
+ // Elastic return
742
+ dragCard.style.transition = 'transform 0.5s cubic-bezier(0.68,-0.55,0.265,1.55)';
743
+ dragCard.style.transform = 'translate(0,0)';
744
+ currentX = currentY = 0;
745
+ setTimeout(() => dragCard.style.transition = '', 500);
746
+ });
747
  }
748
 
749
+ // Add fade-out animation
750
+ const style = document.createElement('style');
751
+ style.textContent = `
752
+ @keyframes fade-out { 0% { opacity: 1; transform: scale(1); } 100% { opacity: 0; transform: scale(0); } }
753
+ @keyframes float { 0%, 100% { transform: translateY(0) translateX(0); } 25% { transform: translateY(-20px) translateX(10px); } 50% { transform: translateY(-10px) translateX(-10px); } 75% { transform: translateY(-30px) translateX(5px); } }
754
+ `;
755
+ document.head.appendChild(style);
 
756
  </script>
757
 
758
  </body>