525 lines
36 KiB
HTML
525 lines
36 KiB
HTML
{% extends "_base.html" %}{% load static %}
|
||
|
||
|
||
{% block CONTENT %}
|
||
<div class="grid grid-cols-1 lg:grid-cols-[400px_1fr] gap-8 items-start"
|
||
x-data="{
|
||
activeTab: 'style',
|
||
colors: ['#a855ff'],
|
||
cols: 80,
|
||
radius: 8,
|
||
blink: 6,
|
||
rotation: 0,
|
||
scale: 980,
|
||
angle: 0,
|
||
isLoading: false,
|
||
hasChanges: true,
|
||
hasImage: false,
|
||
timer: null,
|
||
startThinking() {
|
||
this.isLoading = true;
|
||
if (this.timer) clearTimeout(this.timer);
|
||
this.timer = setTimeout(() => {
|
||
this.isLoading = false;
|
||
this.hasChanges = false;
|
||
}, 8000);
|
||
}
|
||
}">
|
||
|
||
<!-- ЛЕВАЯ ПАНЕЛЬ: НАСТРОЙКИ -->
|
||
<aside class="space-y-6">
|
||
<form hx-post="/generate"
|
||
hx-target="#preview"
|
||
hx-trigger="submit"
|
||
hx-encoding="multipart/form-data"
|
||
@submit="startThinking()"
|
||
@change="hasChanges = true"
|
||
@input="hasChanges = true"
|
||
@htmx:before-request="startThinking()"
|
||
class="relative bg-white dark:bg-zinc-900 p-6 rounded-2xl shadow-sm border border-stone-200 dark:border-zinc-800 overflow-hidden">
|
||
|
||
<!-- Фоновая спираль размышления при генерации (прижата снизу на всю левую панель) -->
|
||
<div x-show="isLoading"
|
||
x-transition:enter="transition ease-out duration-300"
|
||
x-transition:enter-start="opacity-0 scale-95"
|
||
x-transition:enter-end="opacity-100 scale-100"
|
||
x-transition:leave="transition ease-in duration-200"
|
||
x-transition:leave-start="opacity-100 scale-100"
|
||
x-transition:leave-end="opacity-0 scale-95"
|
||
class="absolute inset-0 z-20 pointer-events-none flex items-end justify-center overflow-hidden rounded-2xl bg-white/70 dark:bg-zinc-900/75 backdrop-blur-[2px]">
|
||
<img src="{% static 'img/thinking.svg' %}" alt="thinking"
|
||
class="w-96 h-96 -mb-24 opacity-25 animate-spin [animation-duration:10s]">
|
||
</div>
|
||
|
||
<!-- Загрузка файла -->
|
||
<div class="mb-8">
|
||
<label class="block text-sm font-bold mb-2 uppercase tracking-wider text-stone-500 dark:text-zinc-400">Источник</label>
|
||
<div class="relative group">
|
||
<input type="file" name="image" accept="image/*"
|
||
class="absolute inset-0 w-full h-full opacity-0 cursor-pointer z-10">
|
||
<div
|
||
class="border-2 border-dashed border-stone-300 dark:border-zinc-700 group-hover:border-emerald-500 rounded-xl p-8 text-center transition-colors">
|
||
<span class="text-stone-400 group-hover:text-emerald-500">Покорми Гипнoжабу,<br />притащи сюда img или кликни</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Табы настроек -->
|
||
<nav class="flex border-b border-stone-200 dark:border-zinc-800 mb-6 overflow-x-auto no-scrollbar">
|
||
<button type="button" @click="activeTab = 'style'"
|
||
:class="activeTab === 'style' ? 'border-emerald-500 text-emerald-600' : 'border-transparent text-stone-400'"
|
||
class="pb-2 px-4 border-b-2 font-bold text-sm uppercase transition-all whitespace-nowrap">Гюко-элемент
|
||
</button>
|
||
<button type="button" @click="activeTab = 'params'"
|
||
:class="activeTab === 'params' ? 'border-emerald-500 text-emerald-600' : 'border-transparent text-stone-400'"
|
||
class="pb-2 px-4 border-b-2 font-bold text-sm uppercase transition-all whitespace-nowrap">Параметры
|
||
</button>
|
||
<button type="button" @click="activeTab = 'color'"
|
||
:class="activeTab === 'color' ? 'border-emerald-500 text-emerald-600' : 'border-transparent text-stone-400'"
|
||
class="pb-2 px-4 border-b-2 font-bold text-sm uppercase transition-all whitespace-nowrap">Цвета
|
||
</button>
|
||
</nav>
|
||
|
||
<!-- Контент табов -->
|
||
<div class="space-y-6 min-h-[460px]">
|
||
<!-- Таб: Стиль (Фигуры) -->
|
||
<div x-show="activeTab === 'style'" class="grid grid-cols-4 gap-2">
|
||
<!-- 1. Круг -->
|
||
<label class="cursor-pointer group" title="Круг">
|
||
<input type="radio" name="shape" value="circle" class="hidden peer" checked>
|
||
<div class="aspect-square flex flex-col items-center justify-center p-2 border-2 border-stone-100 dark:border-zinc-800 rounded-xl text-stone-400 group-hover:text-emerald-500 peer-checked:text-emerald-500 peer-checked:border-emerald-500 peer-checked:bg-emerald-50/10 transition-all hover:border-stone-300 dark:hover:border-zinc-700">
|
||
<div class="w-6 h-6 rounded-full bg-current transition-colors"></div>
|
||
</div>
|
||
</label>
|
||
|
||
<!-- 2. Кольцо (Бублик) -->
|
||
<label class="cursor-pointer group" title="Кольцо">
|
||
<input type="radio" name="shape" value="ring" class="hidden peer">
|
||
<div class="aspect-square flex flex-col items-center justify-center p-2 border-2 border-stone-100 dark:border-zinc-800 rounded-xl text-stone-400 group-hover:text-emerald-500 peer-checked:text-emerald-500 peer-checked:border-emerald-500 peer-checked:bg-emerald-50/10 transition-all hover:border-stone-300 dark:hover:border-zinc-700">
|
||
<div class="w-6 h-6 rounded-full border-[6px] border-current transition-colors"></div>
|
||
</div>
|
||
</label>
|
||
|
||
<!-- 3. Треугольник -->
|
||
<label class="cursor-pointer group" title="Треугольник">
|
||
<input type="radio" name="shape" value="triangle" class="hidden peer">
|
||
<div class="aspect-square flex flex-col items-center justify-center p-2 border-2 border-stone-100 dark:border-zinc-800 rounded-xl text-stone-400 group-hover:text-emerald-500 peer-checked:text-emerald-500 peer-checked:border-emerald-500 peer-checked:bg-emerald-50/10 transition-all hover:border-stone-300 dark:hover:border-zinc-700">
|
||
<svg class="w-6 h-6 fill-current transition-colors" viewBox="0 0 24 24">
|
||
<path d="M12 4L2 20h20L12 4z"/>
|
||
</svg>
|
||
</div>
|
||
</label>
|
||
|
||
<!-- 4. Квадрат -->
|
||
<label class="cursor-pointer group" title="Квадрат">
|
||
<input type="radio" name="shape" value="square" class="hidden peer">
|
||
<div class="aspect-square flex flex-col items-center justify-center p-2 border-2 border-stone-100 dark:border-zinc-800 rounded-xl text-stone-400 group-hover:text-emerald-500 peer-checked:text-emerald-500 peer-checked:border-emerald-500 peer-checked:bg-emerald-50/10 transition-all hover:border-stone-300 dark:hover:border-zinc-700">
|
||
<div class="w-5 h-5 rounded-xs bg-current transition-colors"></div>
|
||
</div>
|
||
</label>
|
||
|
||
<!-- 5. Ромб (Бриллиант) -->
|
||
<label class="cursor-pointer group" title="Ромб">
|
||
<input type="radio" name="shape" value="diamond" class="hidden peer">
|
||
<div class="aspect-square flex flex-col items-center justify-center p-2 border-2 border-stone-100 dark:border-zinc-800 rounded-xl text-stone-400 group-hover:text-emerald-500 peer-checked:text-emerald-500 peer-checked:border-emerald-500 peer-checked:bg-emerald-50/10 transition-all hover:border-stone-300 dark:hover:border-zinc-700">
|
||
<div class="w-5 h-5 rotate-45 rounded-xs bg-current transition-colors"></div>
|
||
</div>
|
||
</label>
|
||
|
||
<!-- 6. Шестиугольник (Гексагон) -->
|
||
<label class="cursor-pointer group" title="Гексагон">
|
||
<input type="radio" name="shape" value="hexagon" class="hidden peer">
|
||
<div class="aspect-square flex flex-col items-center justify-center p-2 border-2 border-stone-100 dark:border-zinc-800 rounded-xl text-stone-400 group-hover:text-emerald-500 peer-checked:text-emerald-500 peer-checked:border-emerald-500 peer-checked:bg-emerald-50/10 transition-all hover:border-stone-300 dark:hover:border-zinc-700">
|
||
<svg class="w-6 h-6 fill-current transition-colors" viewBox="0 0 24 24">
|
||
<path d="M12 2l8.66 5v10L12 22l-8.66-5V7L12 2z"/>
|
||
</svg>
|
||
</div>
|
||
</label>
|
||
|
||
<!-- 7. Звездочка -->
|
||
<label class="cursor-pointer group" title="Звезда">
|
||
<input type="radio" name="shape" value="star" class="hidden peer">
|
||
<div class="aspect-square flex flex-col items-center justify-center p-2 border-2 border-stone-100 dark:border-zinc-800 rounded-xl text-stone-400 group-hover:text-emerald-500 peer-checked:text-emerald-500 peer-checked:border-emerald-500 peer-checked:bg-emerald-50/10 transition-all hover:border-stone-300 dark:hover:border-zinc-700">
|
||
<svg class="w-6 h-6 fill-current transition-colors" viewBox="0 0 24 24">
|
||
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
|
||
</svg>
|
||
</div>
|
||
</label>
|
||
|
||
<!-- 8. Сердечко -->
|
||
<label class="cursor-pointer group" title="Сердечко">
|
||
<input type="radio" name="shape" value="heart" class="hidden peer">
|
||
<div class="aspect-square flex flex-col items-center justify-center p-2 border-2 border-stone-100 dark:border-zinc-800 rounded-xl text-stone-400 group-hover:text-emerald-500 peer-checked:text-emerald-500 peer-checked:border-emerald-500 peer-checked:bg-emerald-50/10 transition-all hover:border-stone-300 dark:hover:border-zinc-700">
|
||
<svg class="w-6 h-6 fill-current transition-colors" viewBox="0 0 24 24">
|
||
<path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/>
|
||
</svg>
|
||
</div>
|
||
</label>
|
||
|
||
<!-- 9. Крестик / Плюс -->
|
||
<label class="cursor-pointer group" title="Крестик">
|
||
<input type="radio" name="shape" value="cross" class="hidden peer">
|
||
<div class="aspect-square flex flex-col items-center justify-center p-2 border-2 border-stone-100 dark:border-zinc-800 rounded-xl text-stone-400 group-hover:text-emerald-500 peer-checked:text-emerald-500 peer-checked:border-emerald-500 peer-checked:bg-emerald-50/10 transition-all hover:border-stone-300 dark:hover:border-zinc-700">
|
||
<svg class="w-6 h-6 fill-current transition-colors" viewBox="0 0 24 24">
|
||
<path d="M19 10.5h-5.5V5a1.5 1.5 0 00-3 0v5.5H5a1.5 1.5 0 000 3h5.5V19a1.5 1.5 0 003 0v-5.5H19a1.5 1.5 0 000-3z"/>
|
||
</svg>
|
||
</div>
|
||
</label>
|
||
|
||
<!-- 10. Черточка / Линия -->
|
||
<label class="cursor-pointer group" title="Линия">
|
||
<input type="radio" name="shape" value="line" class="hidden peer">
|
||
<div class="aspect-square flex flex-col items-center justify-center p-2 border-2 border-stone-100 dark:border-zinc-800 rounded-xl text-stone-400 group-hover:text-emerald-500 peer-checked:text-emerald-500 peer-checked:border-emerald-500 peer-checked:bg-emerald-50/10 transition-all hover:border-stone-300 dark:hover:border-zinc-700">
|
||
<div class="w-5 h-1 rounded-full bg-current transition-colors"></div>
|
||
</div>
|
||
</label>
|
||
|
||
|
||
<!-- 11. Волна / Синусоида -->
|
||
<label class="cursor-pointer group" title="Волна">
|
||
<input type="radio" name="shape" value="wave" class="hidden peer">
|
||
<div class="aspect-square flex flex-col items-center justify-center p-2 border-2 border-stone-100 dark:border-zinc-800 rounded-xl text-stone-400 group-hover:text-emerald-500 peer-checked:text-emerald-500 peer-checked:border-emerald-500 peer-checked:bg-emerald-50/10 transition-all hover:border-stone-300 dark:hover:border-zinc-700">
|
||
<svg class="w-6 h-6 stroke-current transition-colors" fill="none" stroke-width="2.5" stroke-linecap="round" viewBox="0 0 24 24">
|
||
<path d="M2 12c2.5-4 5.5-4 8 0s5.5 4 8 0 3.5-4 4-4"/>
|
||
</svg>
|
||
</div>
|
||
</label>
|
||
|
||
<!-- 12. Двоичный блок 3x3 -->
|
||
<label class="cursor-pointer group" title="Матрица 3x3 (0/1)">
|
||
<input type="radio" name="shape" value="binary" class="hidden peer">
|
||
<div class="aspect-square flex flex-col items-center justify-center p-1 border-2 border-stone-100 dark:border-zinc-800 rounded-xl text-stone-400 group-hover:text-emerald-500 peer-checked:text-emerald-500 peer-checked:border-emerald-500 peer-checked:bg-emerald-50/10 transition-all hover:border-stone-300 dark:hover:border-zinc-700">
|
||
<div class="grid grid-cols-2 gap-0.5 font-mono text-[14px] leading-[12px] font-black transition-colors select-none">
|
||
<span>1</span><span>0</span>
|
||
<span>0</span><span>1</span>
|
||
</div>
|
||
</div>
|
||
</label>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<!-- Таб: Цвет -->
|
||
<div x-show="activeTab === 'color'" class="space-y-4">
|
||
<div class="flex items-center justify-between pb-1 border-b border-stone-100 dark:border-zinc-800">
|
||
<span class="text-xs font-bold text-stone-400 uppercase">Цветовая схема</span>
|
||
<span class="text-xs font-semibold px-2.5 py-0.5 rounded-full bg-emerald-100 text-emerald-800 dark:bg-emerald-950/60 dark:text-emerald-400"
|
||
x-text="colors.length === 1 ? 'Монотон (1 цвет)' : (colors.length === 2 ? 'Дуотон (2 цвета)' : 'Триатон (3 цвета)')"></span>
|
||
</div>
|
||
|
||
<div class="space-y-3">
|
||
<template x-for="(color, index) in colors" :key="index">
|
||
<div class="flex items-center gap-2">
|
||
<div class="flex-1">
|
||
<div class="flex justify-between mb-1">
|
||
<label class="text-xs font-bold text-stone-400 uppercase"
|
||
x-text="colors.length === 1 ? 'Основной цвет' : ('Цвет ' + (index + 1))"></label>
|
||
<span class="text-xs font-mono uppercase text-stone-500 dark:text-stone-400" x-text="colors[index]"></span>
|
||
</div>
|
||
<input type="color" name="colors" x-model="colors[index]"
|
||
class="w-full h-10 border-none rounded-lg cursor-pointer bg-stone-50 dark:bg-zinc-800">
|
||
</div>
|
||
<template x-if="colors.length > 1">
|
||
<button type="button"
|
||
@click="colors.splice(index, 1); $nextTick(() => $el.closest('form').dispatchEvent(new Event('change')))"
|
||
class="self-end mb-1 p-2 text-stone-400 hover:text-red-500 rounded-lg hover:bg-stone-100 dark:hover:bg-zinc-800 transition-colors"
|
||
title="Удалить цвет">
|
||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
|
||
</svg>
|
||
</button>
|
||
</template>
|
||
</div>
|
||
</template>
|
||
</div>
|
||
|
||
<div x-show="colors.length < 3" class="pt-2">
|
||
<button type="button"
|
||
@click="colors.push(colors.length === 1 ? '#f97316' : '#06b6d4'); $nextTick(() => $el.closest('form').dispatchEvent(new Event('change')))"
|
||
class="w-full flex items-center justify-center gap-2 py-2.5 px-3 text-xs font-bold uppercase rounded-xl border-2 border-dashed border-stone-300 dark:border-zinc-700 text-stone-500 dark:text-stone-400 hover:border-emerald-500 hover:text-emerald-500 transition-colors cursor-pointer">
|
||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/>
|
||
</svg>
|
||
<span x-text="colors.length === 1 ? 'Добавить второй цвет (Дуотон)' : 'Добавить третий цвет (Триатон)'"></span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Таб: Параметры -->
|
||
<div x-show="activeTab === 'params'" class="space-y-4">
|
||
{# ПЛОТНОСТЬ СЕТКИ (ЧИСЛО КОЛОНОК) #}<div>
|
||
<div class="flex justify-between mb-1">
|
||
<label class="text-xs font-bold text-stone-400 uppercase">Плотность галлюцинации</label>
|
||
<span class="text-xs transition-colors duration-300"
|
||
:class="cols >= 140 ? 'text-red-600' : (cols > 80 ? 'text-yellow-500' : 'text-emerald-600')"
|
||
x-text="cols"></span>
|
||
</div>
|
||
<input type="range" name="cols" min="20" max="200" x-model="cols"
|
||
@input="$el.dispatchEvent(new CustomEvent('input-change'))"
|
||
:class="cols >= 140 ? 'accent-red-600' : (cols > 80 ? 'accent-yellow-500' : 'accent-emerald-500')"
|
||
class="w-full transition-all duration-300">
|
||
</div>
|
||
{# РАЗМЕР ЭЛЕМЕНТА #}<div>
|
||
<div class="flex justify-between mb-1">
|
||
<label class="text-xs font-bold text-stone-400 uppercase">Размер гипно-точки</label>
|
||
<span class="text-xs transition-colors duration-300"
|
||
:class="radius < 4 ? 'text-red-600' : (radius < 5 ? 'text-yellow-600' : (radius > 15 ? 'text-red-600' : (radius > 12 ? 'text-yellow-600' : 'text-emerald-600')))"
|
||
x-text="radius"></span>
|
||
</div>
|
||
<input type="range" name="max_radius" min="3" max="20" x-model="radius"
|
||
@input="$el.dispatchEvent(new CustomEvent('input-change'))"
|
||
:class="radius < 4 ? 'accent-red-600' : (radius < 5 ? 'accent-yellow-500' : (radius > 15 ? 'accent-red-600' : (radius > 12 ? 'accent-yellow-500' : 'accent-emerald-500')))"
|
||
class="w-full accent-emerald-500">
|
||
</div>
|
||
{# МЕРЦАНИЕ #}<div>
|
||
<div class="flex justify-between mb-1">
|
||
<label class="text-xs font-bold text-stone-400 uppercase">Мерцание</label>
|
||
<span class="text-xs transition-colors duration-300"
|
||
:class="blink < 1 ? 'text-emerald-600' : (blink < 2 ? 'text-red-600' : (blink < 4 ? 'text-yellow-600' : 'text-emerald-600'))"
|
||
x-text="blink"></span>
|
||
</div>
|
||
<input type="range" name="blink" min="0" max="10" x-model="blink"
|
||
@input="$el.dispatchEvent(new CustomEvent('input-change'))"
|
||
:class="blink < 1 ? 'accent-emerald-600' : (blink < 2 ? 'accent-red-600' : (blink < 4 ? 'accent-yellow-500' : 'accent-emerald-500'))"
|
||
class="w-full accent-emerald-500">
|
||
</div>
|
||
{# ПОВОРОТЫ #}<div>
|
||
<div class="flex justify-between mb-1">
|
||
<label class="text-xs font-bold text-stone-400 uppercase">Укачивание</label>
|
||
<span class="text-xs transition-colors duration-300"
|
||
:class="rotation < -7 ? 'text-red-600' : (rotation < -4 ? 'text-yellow-600' : (rotation > 7 ? 'text-red-600' : (rotation > 4 ? 'text-yellow-600' : 'text-emerald-600')))"
|
||
x-text="rotation + '°'"></span>
|
||
</div>
|
||
<input type="range" name="rotation" min="-15" max="15" x-model="rotation"
|
||
@input="$el.dispatchEvent(new CustomEvent('input-change'))"
|
||
:class="rotation < -7 ? 'accent-red-600' : (rotation < -4 ? 'accent-yellow-500' : (rotation > 7 ? 'accent-red-600' : (rotation > 4 ? 'accent-yellow-500' : 'accent-emerald-500')))"
|
||
class="w-full accent-emerald-500">
|
||
</div>
|
||
{# МАСШТАБ #}<div>
|
||
<div class="flex justify-between mb-1">
|
||
<label class="text-xs font-bold text-stone-400">Взз-з-з-з…</label>
|
||
<span class="text-xs transition-colors duration-300"
|
||
:class="scale < 900 ? 'text-red-600' : (scale < 950 ? 'text-yellow-600' : (scale > 1030 ? 'text-red-600' : (scale > 1010 ? 'text-yellow-600' : 'text-emerald-600')))"
|
||
x-text="(scale / 10).toFixed(1) + '%'"></span>
|
||
</div>
|
||
<input type="range" name="scale" min="800" max="1040" x-model="scale"
|
||
@input="$el.dispatchEvent(new CustomEvent('input-change'))"
|
||
:class="scale < 900 ? 'accent-red-600' : (scale < 950 ? 'accent-yellow-500' : (scale > 1030 ? 'accent-red-600' : (scale > 1010 ? 'accent-yellow-500' : 'accent-emerald-500')))"
|
||
class="w-full accent-emerald-500">
|
||
</div>
|
||
{# НАКЛОН СЕТКИ #}<div>
|
||
<div class="flex justify-between mb-1">
|
||
<label class="text-xs font-bold text-stone-400 uppercase">Перекос</label>
|
||
<span class="text-xs transition-colors duration-300 text-emerald-600" x-text="angle + '°'"></span>
|
||
</div>
|
||
<input type="range" name="angle" min="-44" max="45" step="1" x-model="angle"
|
||
class="w-full accent-emerald-500">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Индикатор размышления / статус активности -->
|
||
<div class="h-8 mt-2 flex items-center justify-center">
|
||
<div x-show="isLoading"
|
||
x-transition
|
||
class="flex items-center gap-2 px-3.5 py-1 rounded-full bg-emerald-500/10 border border-emerald-500/30 text-emerald-600 dark:text-emerald-400 text-xs font-bold font-mono tracking-wide animate-pulse">
|
||
<img src="{% static 'img/thinking.svg' %}" class="w-4 h-4 animate-spin [animation-duration:3s]">
|
||
<span>Глюкало думает...</span>
|
||
</div>
|
||
<div x-show="!isLoading && !hasChanges"
|
||
class="text-[11px] font-mono text-stone-400 dark:text-zinc-500 tracking-wider">
|
||
Параметры зафиксированы
|
||
</div>
|
||
<div x-show="!isLoading && hasChanges"
|
||
class="text-[11px] font-mono text-emerald-600 dark:text-emerald-500 font-semibold tracking-wider flex items-center gap-1.5">
|
||
<span class="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-ping"></span>
|
||
<span>Готово к запуску транса</span>
|
||
</div>
|
||
</div>
|
||
|
||
<button type="submit"
|
||
:disabled="isLoading || !hasChanges"
|
||
:class="(!hasChanges || isLoading)
|
||
? 'bg-stone-200 dark:bg-zinc-800 text-stone-400 dark:text-zinc-600 cursor-not-allowed shadow-none'
|
||
: 'bg-emerald-600 hover:bg-emerald-500 text-white shadow-lg shadow-emerald-900/20 active:scale-95 cursor-pointer'"
|
||
class="w-full mt-2 font-bold py-3.5 px-6 rounded-xl transition-all flex items-center justify-center gap-2">
|
||
<template x-if="isLoading">
|
||
<span class="flex items-center gap-2">
|
||
<img src="{% static 'img/thinking.svg' %}" class="w-5 h-5 animate-spin [animation-duration:2s]">
|
||
<span>ГЛЮКОТРОН В ТРАНСЕ...</span>
|
||
</span>
|
||
</template>
|
||
<template x-if="!isLoading">
|
||
<span>ЗАПУСТИТЬ ГЛЮКОТРОН</span>
|
||
</template>
|
||
</button>
|
||
</form>
|
||
</aside>
|
||
|
||
<!-- ПРАВАЯ ПАНЕЛЬ: ПРЕВЬЮ -->
|
||
<section class="flex flex-col gap-6">
|
||
<div id="preview"
|
||
class="w-full h-[744px] bg-stone-200 dark:bg-zinc-900 rounded-3xl flex items-center justify-center border border-stone-300 dark:border-zinc-800 overflow-hidden relative group">
|
||
|
||
<div class="text-stone-400 flex flex-col items-center gap-4 text-center px-6">
|
||
<svg xmlns="http://www.w3.org/2000/svg" class="w-16 h-16 opacity-50" fill="none" viewBox="0 0 24 24" stroke="currentColor"
|
||
:class="isLoading ? 'animate-pulse text-emerald-500 opacity-80' : 'opacity-50'">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/>
|
||
</svg>
|
||
<p class="transition-all duration-300"
|
||
:class="isLoading ? 'text-emerald-600 dark:text-emerald-400 font-mono text-xs font-bold uppercase tracking-wider animate-pulse' : 'font-medium opacity-50'"
|
||
x-text="isLoading ? 'Гипножаба переваривает пиксели…' : 'Ваше искусство появится здесь'"></p>
|
||
</div>
|
||
|
||
<!-- Заглушка для кнопок действий (появятся при генерации) -->
|
||
<div
|
||
class="absolute bottom-6 right-6 flex items-center gap-3 translate-y-20 group-hover:translate-y-0 transition-transform duration-300 pointer-events-none">
|
||
<button id="like-to-gallery" type="button" title="Нравится!"
|
||
class="pointer-events-auto flex items-center gap-2 bg-emerald-600/85 hover:bg-emerald-600 text-white text-xs font-bold uppercase tracking-wide backdrop-blur-md px-4 py-2.5 rounded-full shadow-xl transition-all hover:scale-105 active:scale-95 cursor-pointer">
|
||
<span>Кандидат в галерею транса</span>
|
||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||
d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"/>
|
||
</svg>
|
||
|
||
</button>
|
||
<button id="dislike-from-gallery" type="button" title="Не нравится!"
|
||
class="pointer-events-auto flex items-center gap-2 bg-rose-900/90 hover:bg-rose-500 text-white text-xs font-bold uppercase tracking-wide backdrop-blur-md px-4 py-2.5 rounded-full shadow-xl transition-all hover:scale-105 active:scale-95 cursor-pointer">
|
||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||
d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636"/>
|
||
<span>Гипнoжаба такое не одобрит</span>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="grid grid-cols-2 gap-4">
|
||
<button
|
||
class="bg-stone-800 text-white dark:bg-zinc-800 py-3.5 rounded-xl font-bold flex items-center justify-center gap-2 hover:bg-stone-700 transition-colors">
|
||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/></svg>
|
||
КОПИРОВАТЬ SVG
|
||
</button>
|
||
<button
|
||
class="bg-emerald-600 text-white py-3.5 rounded-xl font-bold flex items-center justify-center gap-2 hover:bg-emerald-500 transition-colors shadow-lg shadow-emerald-900/20">
|
||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M4 16v1a2 2 0 002 2h12a2 2 0 002-2v-1m-4-4l-4 4m0 0l-4-4m4 4V4"/></svg>
|
||
СКАЧАТЬ
|
||
</button>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<!-- СЕКЦИЯ: ТРЕХЭТАЖНАЯ ГАЛЕРЕЯ -->
|
||
<section class="mt-20 space-y-12">
|
||
<div class="flex flex-col sm:flex-row sm:items-center justify-between gap-4 pb-6 border-b border-stone-200 dark:border-zinc-800">
|
||
<div>
|
||
<h2 class="text-3xl font-black uppercase tracking-tighter">Галерея транса</h2>
|
||
<p class="text-sm text-stone-500 dark:text-zinc-400 mt-1">Многоуровневое хранилище зрительного подчинения</p>
|
||
</div>
|
||
<a href="#" class="text-emerald-600 dark:text-emerald-400 font-bold hover:underline self-start sm:self-auto">Смотреть весь архив →</a>
|
||
</div>
|
||
|
||
<!-- 1-й ЭТАЖ: ПЛЕСК БЕССОЗНАТЕЛЬНОГО (Свежий поток)... Сюда попадет только что созданный шедевр (нужно чтобы это было интерактивно... лаккнул и сразу через HTMX на первом уровне галереи -->
|
||
<div class="space-y-4">
|
||
<div class="flex items-center justify-between">
|
||
<div class="flex items-center gap-3">
|
||
<div class="w-5 h-5 rounded-full bg-amber-500"></div>
|
||
<div>
|
||
<h3 class="text-xl font-black uppercase tracking-tight flex items-center gap-2">
|
||
Плеск бессознательного
|
||
<span class="text-xs font-bold font-mono px-2 py-0.5 rounded-full bg-amber-100 dark:bg-amber-950/70 text-amber-700 dark:text-amber-400 border border-amber-300 dark:border-amber-800/50">FRESH STREAM</span>
|
||
</h3>
|
||
<p class="text-xs text-stone-400 dark:text-zinc-500">Свежие галлюцинации из инкубатора • Первичная оценка сообщества</p>
|
||
</div>
|
||
</div>
|
||
<span class="text-xs font-semibold text-stone-400">Свежее • до 100 лайков</span>
|
||
</div>
|
||
|
||
<div class="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-4">
|
||
<template x-for="i in 6">
|
||
<div class="aspect-square bg-stone-200 dark:bg-zinc-900 rounded-xl border border-stone-300 dark:border-zinc-800 overflow-hidden relative group cursor-pointer hover:border-amber-500/50 transition-all hover:scale-[1.02]">
|
||
<div class="absolute inset-0 flex items-center justify-center text-stone-400 group-hover:scale-110 transition-transform">
|
||
<svg class="w-8 h-8 opacity-20" fill="currentColor" viewBox="0 0 24 24">
|
||
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/>
|
||
</svg>
|
||
</div>
|
||
<div class="absolute bottom-2 left-2 flex items-center gap-1 text-[11px] font-bold text-amber-600 dark:text-amber-400 bg-white/90 dark:bg-zinc-900/90 px-2 py-0.5 rounded-full opacity-0 group-hover:opacity-100 transition-opacity">
|
||
♥ <span x-text="Math.floor(Math.random()*99) + 1"></span>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 2-й ЭТАЖ: ОДОБРЕНО МОЗГОВЫМ СЛИЗНЕМ (Кураторский отбор) -->
|
||
<div class="space-y-4">
|
||
<div class="flex items-center justify-between">
|
||
<div class="flex items-center gap-3">
|
||
<div class="w-5 h-5 rounded-full bg-cyan-500"></div>
|
||
<div>
|
||
<h3 class="text-xl font-black uppercase tracking-tight flex items-center gap-2">
|
||
Одобрено Мозговым Слизнем
|
||
<span class="text-xs font-bold font-mono px-2 py-0.5 rounded-full bg-cyan-100 dark:bg-cyan-950/70 text-cyan-700 dark:text-cyan-400 border border-cyan-300 dark:border-cyan-800/50">CURATED</span>
|
||
</h3>
|
||
<p class="text-xs text-stone-400 dark:text-zinc-500">Проверено контролем качества • Высокий психоделический резонанс</p>
|
||
</div>
|
||
</div>
|
||
<span class="text-xs font-semibold text-stone-400">100–999 лайков</span>
|
||
</div>
|
||
|
||
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4">
|
||
<template x-for="i in 6">
|
||
<div class="aspect-square bg-stone-200 dark:bg-zinc-900 rounded-xl border border-stone-300 dark:border-zinc-800 overflow-hidden relative group cursor-pointer hover:border-cyan-500/50 transition-all hover:scale-[1.02]">
|
||
<div class="absolute inset-0 flex items-center justify-center text-stone-400 group-hover:scale-110 transition-transform">
|
||
<svg class="w-8 h-8 opacity-20" fill="currentColor" viewBox="0 0 24 24">
|
||
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/>
|
||
</svg>
|
||
</div>
|
||
<div class="absolute bottom-2 left-2 flex items-center gap-1 text-[11px] font-bold text-cyan-600 dark:text-cyan-400 bg-white/90 dark:bg-zinc-900/90 px-2 py-0.5 rounded-full opacity-0 group-hover:opacity-100 transition-opacity">
|
||
♥ <span x-text="100 + Math.floor(Math.random()*400)"></span>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 3-й ЭТАЖ: ГЛУБОКИЙ ТРАНС (Высшая лига) -->
|
||
<div class="space-y-4">
|
||
<div class="flex items-center justify-between">
|
||
<div class="flex items-center gap-3">
|
||
<div class="w-5 h-5"><img src="{% static 'img/favicon.svg' %}" alt="Favicon" class="w-full h-full object-cover"></div>
|
||
<div>
|
||
<h3 class="text-xl font-black uppercase tracking-tight flex items-center gap-2">
|
||
Глубокий транс
|
||
<span class="text-xs font-bold font-mono px-2 py-0.5 rounded-full bg-emerald-100 dark:bg-emerald-950/70 text-emerald-700 dark:text-emerald-400 border border-emerald-300 dark:border-emerald-800/50">TOP TIER</span>
|
||
</h3>
|
||
<p class="text-xs text-stone-400 dark:text-zinc-500">Золотой фонд гипноза • Абсолютное подчинение воли</p>
|
||
</div>
|
||
</div>
|
||
<span class="text-xs font-semibold text-stone-400">1000+ лайков</span>
|
||
</div>
|
||
|
||
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4">
|
||
<template x-for="i in 6">
|
||
<div class="aspect-square bg-stone-200 dark:bg-zinc-900 rounded-2xl border-2 border-emerald-500/30 dark:border-emerald-500/20 overflow-hidden relative group cursor-pointer shadow-lg shadow-emerald-950/5 hover:border-emerald-500 transition-all hover:scale-[1.02]">
|
||
<div class="absolute inset-0 flex items-center justify-center text-emerald-600/40 group-hover:scale-110 transition-transform">
|
||
<svg class="w-10 h-10 opacity-30" fill="currentColor" viewBox="0 0 24 24">
|
||
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/>
|
||
</svg>
|
||
</div>
|
||
<div class="absolute top-2 right-2 text-[10px] font-black tracking-widest text-emerald-600 dark:text-emerald-400 bg-emerald-500/10 backdrop-blur-md px-1.5 py-0.5 rounded border border-emerald-500/20">
|
||
★ 99%
|
||
</div>
|
||
<div class="absolute bottom-2.5 left-2.5 flex items-center gap-1.5 text-xs font-bold text-white bg-emerald-600/90 backdrop-blur-md px-2.5 py-1 rounded-full shadow">
|
||
<span>♥</span> <span x-text="500 + Math.floor(Math.random()*500)"></span>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
</section>
|
||
{% endblock CONTENT %} |