EvgenyKu commited on
Commit
37193e0
Β·
1 Parent(s): 54c38dc

initial commit

Browse files
Files changed (6) hide show
  1. README.md +1 -1
  2. app.py +259 -0
  3. prompt.txt +1 -0
  4. requirements.txt +21 -0
  5. space.yaml +8 -0
  6. style.css +187 -0
README.md CHANGED
@@ -1,5 +1,5 @@
1
  ---
2
- title: IconDDDzilla Bot Backend
3
  emoji: πŸš€
4
  colorFrom: blue
5
  colorTo: indigo
 
1
  ---
2
+ title: IconDDDzilla_Bot_Backend
3
  emoji: πŸš€
4
  colorFrom: blue
5
  colorTo: indigo
app.py ADDED
@@ -0,0 +1,259 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import time
3
+ from datetime import datetime
4
+ import pytz
5
+ import spaces
6
+ import torch
7
+ import gradio as gr
8
+ import traceback
9
+ import threading
10
+ from transformers import pipeline
11
+ from huggingface_hub import login
12
+ from diffusers import FluxPipeline
13
+ from aura_sr import AuraSR
14
+ from deep_translator import GoogleTranslator
15
+
16
+ def log(*args, **kwargs):
17
+ tid = threading.get_ident()
18
+ tz = pytz.timezone(kwargs.pop('timezone', 'Europe/Moscow'))
19
+ time_fmt = kwargs.pop('time_format', '%Y-%m-%d %H:%M:%S')
20
+ separator = kwargs.pop('sep', ' - ')
21
+ moscow_time = datetime.now(tz).strftime(time_fmt)
22
+ message = separator.join(str(arg) for arg in args)
23
+ print(f"[{moscow_time}]{separator}[tid={tid}]{separator}{message}", **kwargs)
24
+
25
+ log("Π‘Ρ‚Π°Ρ€Ρ‚ сСрвиса")
26
+
27
+ login(token=os.getenv('HF_TOKEN'))
28
+
29
+ log("=" * 50)
30
+ log(f"PyTorch version: {torch.__version__}")
31
+ log(f"CUDA available: {torch.cuda.is_available()}")
32
+ log(f"GPU count: {torch.cuda.device_count()}")
33
+ if torch.cuda.is_available():
34
+ log(f"Current device: {torch.cuda.current_device()}")
35
+ log(f"Device name: {torch.cuda.get_device_name(0)}")
36
+ log("=" * 50)
37
+
38
+ def clear_cuda():
39
+ if torch.cuda.is_available():
40
+ log(f"Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ VRAM: {torch.cuda.memory_allocated() / 1024 ** 3:.2f} GB")
41
+ log(f"Доступно VRAM: {torch.cuda.memory_reserved() / 1024 ** 3:.2f} GB")
42
+ log(f"ПиковоС использованиС VRAM: {torch.cuda.max_memory_allocated() / 1024 ** 3:.2f} GB")
43
+ log(f"ΠžΡ‡ΠΈΡΡ‚ΠΊΠ° кСша CUDA...")
44
+ torch.cuda.empty_cache()
45
+ torch.cuda.reset_peak_memory_stats()
46
+ log(f"ΠžΡ‡ΠΈΡΡ‚ΠΊΠ° кСша CUDA Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π°.")
47
+ log(f"Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ VRAM: {torch.cuda.memory_allocated() / 1024 ** 3:.2f} GB")
48
+ log(f"Доступно VRAM: {torch.cuda.memory_reserved() / 1024 ** 3:.2f} GB")
49
+ log(f"ПиковоС использованиС VRAM: {torch.cuda.max_memory_allocated() / 1024 ** 3:.2f} GB")
50
+
51
+ device = "cuda" if torch.cuda.is_available() else "cpu"
52
+
53
+ start_full_time = time.time()
54
+ start_time = time.time()
55
+ log(f"Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΌΠΎΠ΄Π΅Π»ΠΈ FLUX.1-dev")
56
+ pipe = FluxPipeline.from_pretrained(
57
+ # pretrained_model_name_or_path = local_path,
58
+ "black-forest-labs/FLUX.1-dev",
59
+ torch_dtype=torch.bfloat16, # Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ bfloat16 для A100
60
+ # low_cpu_mem_usage=True, # Экономия памяти
61
+ # device_map="balanced",
62
+ # local_files_only=True
63
+ # variant="fp16",
64
+ use_safetensors=True
65
+ )
66
+ log(f"Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΌΠΎΠ΄Π΅Π»ΠΈ FLUX.1-dev Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π° Π·Π° {time.time() - start_time:.2f} сСкунд")
67
+
68
+ start_time = time.time()
69
+ log(f"Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° LoRA")
70
+ pipe.load_lora_weights("Shakker-Labs/FLUX.1-dev-LoRA-add-details", weight_name="FLUX-dev-lora-add_details.safetensors")
71
+ log(f"Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° LoRA Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π° Π·Π° {time.time() - start_time:.2f} сСкунд")
72
+
73
+ pipe.fuse_lora(lora_scale=0.5)
74
+ pipe.to(device)
75
+
76
+ start_time = time.time()
77
+ log(f"Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΌΠΎΠ΄Π΅Π»ΠΈ fal/AuraSR-v2")
78
+ aura_sr = AuraSR.from_pretrained("fal/AuraSR-v2")
79
+ log(f"Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΌΠΎΠ΄Π΅Π»ΠΈ fal/AuraSR-v2 Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π° Π·Π° {time.time() - start_time:.2f} сСкунд")
80
+
81
+ start_time = time.time()
82
+ log(f"Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΌΠΎΠ΄Π΅Π»ΠΈ briaai/RMBG-1.4")
83
+ bg_remover = pipeline("image-segmentation", "briaai/RMBG-1.4", trust_remote_code=True)
84
+ log(f"Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΌΠΎΠ΄Π΅Π»ΠΈ briaai/RMBG-1.4 Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π° Π·Π° {time.time() - start_time:.2f} сСкунд")
85
+
86
+ log(f"Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° всСх ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π° Π·Π° {time.time() - start_full_time:.2f} сСкунд")
87
+
88
+ @spaces.GPU()
89
+ def generate_image(object_name, remove_bg=True, upscale=True):
90
+ try:
91
+ log("Π€ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠΌΠΏΡ‚Π°")
92
+ object_name = translate_ru_en(object_name)
93
+ prompt = create_template_prompt(object_name)
94
+
95
+ # Для ΠΈΠΌΠΈΡ‚Π°Ρ†ΠΈΠΈ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ (ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π½Π° Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹ΠΉ Π²Ρ‹Π·ΠΎΠ² ComfyUI API)
96
+ log(f"ГСнСрация ΠΈΠΊΠΎΠ½ΠΊΠΈ для ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°: {object_name}")
97
+ log(f"ΠŸΡ€ΠΎΠΌΠΏΡ‚: {prompt[:100]}...")
98
+ # print(f"ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹: seed={seed}, steps={steps}, Ρ€Π°Π·ΠΌΠ΅Ρ€={width}x{height}")
99
+ log(f"ΠžΠΏΡ†ΠΈΠΈ: remove_bg={remove_bg}")
100
+ steps = int(os.getenv('STEPS')) if os.getenv('STEPS') is not None else 10
101
+ log(f"Π¨Π°Π³ΠΈ: {steps}")
102
+
103
+ clear_cuda()
104
+
105
+ start_time = time.time()
106
+ log("Π‘Ρ‚Π°Ρ€Ρ‚ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ изобраТСния...")
107
+ image = generate_image_stable(prompt, steps)
108
+ log(f"ГСнСрация Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π° Π·Π° {time.time() - start_time:.2f} сСкунд")
109
+
110
+ if upscale:
111
+ clear_cuda()
112
+ start_time = time.time()
113
+ log(f"Π‘Ρ‚Π°Ρ€Ρ‚ апскСйлСра...")
114
+ image = aura_sr.upscale_4x_overlapped(image)
115
+ log(f"АпскСйлинг Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ Π·Π° {time.time() - start_time:.2f} сСкунд")
116
+
117
+ if remove_bg:
118
+ clear_cuda()
119
+ start_time = time.time()
120
+ log(f"Π‘Ρ‚Π°Ρ€Ρ‚ удалСния Ρ„ΠΎΠ½Π°...")
121
+ image = bg_remover(image)
122
+ log(f"Π€ΠΎΠ½ ΡƒΠ΄Π°Π»Π΅Π½ Π·Π° {time.time() - start_time:.2f} сСкунд")
123
+
124
+ log(f"ГСнСрация ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π° для запроса: {prompt}")
125
+ clear_cuda()
126
+ log(f"ΠžΡ‚Π΄Π°Π΅ΠΌ Π³ΠΎΡ‚ΠΎΠ²ΠΎΠ΅ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ для запроса: {prompt}")
127
+ return image
128
+
129
+ except Exception as e:
130
+ log(f"Ошибка ΠΏΡ€ΠΈ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ изобраТСния: {e}")
131
+ traceback.print_exc()
132
+ clear_cuda()
133
+ return None
134
+
135
+ def generate_image_stable(prompt, steps):
136
+ return pipe(
137
+ prompt,
138
+ height=1024,
139
+ width=1024,
140
+ guidance_scale=3.5,
141
+ num_inference_steps=steps,
142
+ generator=torch.Generator(device).manual_seed(0),
143
+ num_images_per_prompt=1
144
+ ).images[0]
145
+
146
+ def create_template_prompt(object_name):
147
+ template = load_text("prompt.txt")
148
+ return template.format(object_name=object_name)
149
+
150
+ def translate_ru_en(text: str):
151
+ try:
152
+ # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π½Π° ΠΊΠΈΡ€ΠΈΠ»Π»ΠΈΡ†Ρƒ (Ссли Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ)
153
+ if not any('\u0400' <= char <= '\u04FF' for char in text):
154
+ return text
155
+
156
+ # Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Ρ‡ΠΈΠΊ
157
+ translator = GoogleTranslator(source="ru", target="en")
158
+ # ВыполняСм ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄
159
+ return translator.translate(text)
160
+
161
+ except Exception as e:
162
+ log(f"Ошибка ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π°: {e}")
163
+ traceback.print_exc()
164
+ return text
165
+
166
+ def load_text(file_name):
167
+ with open(file_name, 'r', encoding='utf-8') as f:
168
+ return f.read()
169
+
170
+ custom_css = load_text("style.css")
171
+
172
+ # Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ интСрфСйса Gradio
173
+ with gr.Blocks(title="3D Icon Generator", css=custom_css, theme=gr.themes.Soft()) as app:
174
+ gr.Markdown("# iconDDDzilla")
175
+ gr.Markdown("### Create 3d icons with transparent background in one click!")
176
+
177
+ with gr.Row():
178
+ with gr.Column():
179
+ # Π’Ρ…ΠΎΠ΄Π½Ρ‹Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹
180
+ object_input = gr.Textbox(label="Object name",
181
+ placeholder="Type object name (for example: calendar, phone, camera)")
182
+ remove_bg_checkbox = gr.Checkbox(label="Remove background", value=True)
183
+ upscale = gr.Checkbox(label="Upscale", value=True)
184
+
185
+ # with gr.Accordion("Π Π°ΡΡˆΠΈΡ€Π΅Π½Π½Ρ‹Π΅ настройки", open=False):
186
+ # custom_prompt = gr.Textbox(label="ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΏΡ€ΠΎΠΌΠΏΡ‚", placeholder="ΠžΡΡ‚Π°Π²ΡŒΡ‚Π΅ пустым для использования шаблона", lines=3)
187
+ #
188
+ # with gr.Row():
189
+ # seed = gr.Number(label="Seed", value=276789180904019, precision=0)
190
+ # steps = gr.Slider(minimum=1, maximum=5, value=5, step=1, label="Π¨Π°Π³ΠΈ")
191
+ #
192
+ # with gr.Row():
193
+ # width = gr.Slider(minimum=512, maximum=2048, value=1024, step=64, label="Π¨ΠΈΡ€ΠΈΠ½Π°")
194
+ # height = gr.Slider(minimum=512, maximum=2048, value=1024, step=64, label="Высота")
195
+ #
196
+ # with gr.Row():
197
+ # #upscale_checkbox = gr.Checkbox(label="ΠŸΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ апскСйл", value=True)
198
+ # remove_bg_checkbox = gr.Checkbox(label="Π£Π΄Π°Π»ΠΈΡ‚ΡŒ Ρ„ΠΎΠ½", value=False)
199
+
200
+ # Кнопка Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ
201
+ generate_btn = gr.Button("Run")
202
+
203
+ with gr.Column():
204
+ # Π’Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠ΅ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅
205
+ output_image = gr.Image(label="Image")
206
+
207
+ # ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ использования
208
+ # examples = gr.Examples(
209
+ # examples=[
210
+ # ["calendar", "", 276789180904019, 5, 1024, 1024, True],
211
+ # ["camera", "", 391847529184, 5, 1024, 1024, True],
212
+ # ["smartphone", "", 654321987654, 5, 1024, 1024, True],
213
+ # ["headphones", "", 123456789012, 5, 1024, 1024, True],
214
+ # ],
215
+ # inputs=[
216
+ # object_input,
217
+ # custom_prompt,
218
+ # seed,
219
+ # steps,
220
+ # width,
221
+ # height,
222
+ # #upscale_checkbox,
223
+ # remove_bg_checkbox
224
+ # ],
225
+ # outputs=[output_image],
226
+ # fn=generate_image,
227
+ # )
228
+
229
+ # Π˜Π½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡ ΠΎ модСлях
230
+ # with gr.Accordion("Π˜Π½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡ ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Ρ… модСлях", open=False):
231
+ # gr.Markdown("""
232
+ # ## Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ ΠΌΠΎΠ΄Π΅Π»ΠΈ
233
+ #
234
+ # - **Основная модСль:** [flux1-dev-fp8.safetensors](https://huggingface.co/lllyasviel/flux1_dev/blob/main/flux1-dev-fp8.safetensors) ΠΎΡ‚ Stability AI
235
+ # - **МодСль апскСйла:** [4x_NMKD-Superscale-SP_178000_G.pth](https://huggingface.co/gemasai/4x_NMKD-Superscale-SP_178000_G) для ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΡ качСства изобраТСния
236
+ # - **МодСль удалСния Ρ„ΠΎΠ½Π°:** [RMBG-1.4](https://huggingface.co/briaai/RMBG-1.4) для качСствСнного удалСния Ρ„ΠΎΠ½Π°
237
+ #
238
+ # ВсС ΠΌΠΎΠ΄Π΅Π»ΠΈ автоматичСски Π·Π°Π³Ρ€ΡƒΠΆΠ°ΡŽΡ‚ΡΡ ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠΌ запускС прилоТСния.
239
+ # """)
240
+
241
+ # ΠŸΡ€ΠΈΠ²ΡΠ·ΠΊΠ° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΊ Π½Π°ΠΆΠ°Ρ‚ΠΈΡŽ ΠΊΠ½ΠΎΠΏΠΊΠΈ
242
+ generate_btn.click(
243
+ fn=generate_image,
244
+ inputs=[
245
+ object_input,
246
+ # custom_prompt,
247
+ # seed,
248
+ # steps,
249
+ # width,
250
+ # height,
251
+ remove_bg_checkbox,
252
+ upscale
253
+ ],
254
+ outputs=[output_image]
255
+ )
256
+
257
+ # Запуск прилоТСния
258
+ if __name__ == "__main__":
259
+ app.launch()
prompt.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ 3D {object_name} icon: Minimal geo, brushed aluminum, matte acrylic, rubber, 3-point, 8k, PBR, isometric
requirements.txt ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ --extra-index-url https://download.pytorch.org/whl/cu114
2
+ torch
3
+ torchvision
4
+ gradio==3.50.2
5
+ pillow>=9.5.0
6
+ numpy>=1.24.0
7
+ huggingface_hub>=0.17.0
8
+ safetensors>=0.3.0
9
+ accelerate>=0.18.0
10
+ requests>=2.28.0
11
+ opencv-python>=4.6.0
12
+ transformers
13
+ diffusers
14
+ peft
15
+ safetensors
16
+ sentencepiece
17
+ scikit-image
18
+ rembg
19
+ aura-sr
20
+ deep_translator
21
+ pytz
space.yaml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ title: IconDDDzilla_Bot_Backend
2
+ emoji: πŸš€
3
+ colorFrom: blue
4
+ colorTo: indigo
5
+ sdk: gradio
6
+ sdk_version: 3.50.2
7
+ app_file: app.py
8
+ pinned: false
style.css ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ :root {
2
+ --primary: #5A54F9;
3
+ --primary-dark: #4D47D1;
4
+ --secondary: #8B84FF;
5
+ --text: #111827;
6
+ --light: #F9FAFB;
7
+ }
8
+
9
+ .gradio-container {
10
+ background: linear-gradient(135deg, #F9FAFB 0%, #E5E7EB 100%) !important;
11
+ font-family: 'Segoe UI', system-ui, -apple-system, sans-serif !important;
12
+ max-width: 800px !important;
13
+ margin: 20px auto !important;
14
+ border-radius: 16px !important;
15
+ box-shadow: 0 10px 25px -5px rgba(90, 84, 249, 0.1) !important;
16
+ }
17
+
18
+ .dark .gradio-container {
19
+ background: linear-gradient(135deg, #1F2937 0%, #111827 100%) !important;
20
+ --text: #F9FAFB;
21
+ --light: #1F2937;
22
+ }
23
+
24
+ .gr-block {
25
+ border: none !important;
26
+ background: white !important;
27
+ border-radius: 12px !important;
28
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05) !important;
29
+ padding: 20px !important;
30
+ margin-bottom: 24px !important;
31
+ transition: all 0.3s ease !important;
32
+ }
33
+
34
+ .dark .gr-block {
35
+ background: rgba(30, 41, 59, 0.8) !important;
36
+ backdrop-filter: blur(10px) !important;
37
+ }
38
+
39
+ .gr-block:hover {
40
+ transform: translateY(-2px) !important;
41
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1) !important;
42
+ }
43
+
44
+ .gr-button {
45
+ background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%) !important;
46
+ color: white !important;
47
+ border: none !important;
48
+ border-radius: 8px !important;
49
+ padding: 12px 24px !important;
50
+ font-weight: 600 !important;
51
+ text-transform: uppercase !important;
52
+ letter-spacing: 0.5px !important;
53
+ transition: all 0.3s ease !important;
54
+ box-shadow: 0 4px 6px -1px rgba(90, 84, 249, 0.3) !important;
55
+ }
56
+
57
+ .gr-button:hover {
58
+ transform: translateY(-2px) !important;
59
+ box-shadow: 0 10px 15px -3px rgba(90, 84, 249, 0.4) !important;
60
+ }
61
+
62
+ .gr-button:active {
63
+ transform: scale(0.98) !important;
64
+ }
65
+
66
+ .gr-textbox, .gr-number, .gr-slider, .gr-dropdown {
67
+ border: 1px solid #e2e8f0 !important;
68
+ border-radius: 8px !important;
69
+ padding: 12px 16px !important;
70
+ background: var(--light) !important;
71
+ transition: all 0.3s ease !important;
72
+ }
73
+
74
+ .gr-textbox:focus, .gr-number:focus, .gr-dropdown:focus {
75
+ border-color: var(--primary) !important;
76
+ box-shadow: 0 0 0 2px rgba(90, 84, 249, 0.2) !important;
77
+ outline: none !important;
78
+ }
79
+
80
+ h1, h2, h3, h4 {
81
+ color: var(--text) !important;
82
+ font-weight: 600 !important;
83
+ margin-top: 0 !important;
84
+ }
85
+
86
+ .gr-markdown {
87
+ color: var(--text) !important;
88
+ line-height: 1.6 !important;
89
+ }
90
+
91
+ .progress-bar {
92
+ height: 6px !important;
93
+ border-radius: 3px !important;
94
+ background: linear-gradient(90deg, var(--primary), #93c5fd) !important;
95
+ }
96
+
97
+ .tabs {
98
+ background: transparent !important;
99
+ }
100
+
101
+ .tab-button {
102
+ border-radius: 8px 8px 0 0 !important;
103
+ margin-right: 4px !important;
104
+ transition: all 0.3s ease !important;
105
+ }
106
+
107
+ .tab-button.selected {
108
+ background: white !important;
109
+ color: var(--primary) !important;
110
+ font-weight: 600 !important;
111
+ }
112
+
113
+ .dark .tab-button.selected {
114
+ background: rgba(30, 41, 59, 0.8) !important;
115
+ }
116
+
117
+ .gr-checkbox {
118
+ margin: 12px 0 !important;
119
+ }
120
+
121
+ .gr-checkbox label {
122
+ display: flex !important;
123
+ align-items: center !important;
124
+ cursor: pointer !important;
125
+ position: relative !important;
126
+ padding-left: 35px !important;
127
+ min-height: 25px !important;
128
+ }
129
+
130
+ .gr-checkbox input[type="checkbox"] {
131
+ position: absolute !important;
132
+ opacity: 0 !important;
133
+ cursor: pointer !important;
134
+ height: 0 !important;
135
+ width: 0 !important;
136
+ }
137
+
138
+ .checkmark {
139
+ position: absolute !important;
140
+ top: 0 !important;
141
+ left: 0 !important;
142
+ height: 24px !important;
143
+ width: 24px !important;
144
+ background-color: var(--light) !important;
145
+ border: 2px solid var(--primary) !important;
146
+ border-radius: 6px !important;
147
+ transition: all 0.3s ease !important;
148
+ }
149
+
150
+ .gr-checkbox:hover .checkmark {
151
+ transform: scale(1.05) !important;
152
+ box-shadow: 0 0 0 3px rgba(90, 84, 249, 0.1) !important;
153
+ }
154
+
155
+ .gr-checkbox input:checked ~ .checkmark {
156
+ background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%) !important;
157
+ border-color: var(--primary-dark) !important;
158
+ }
159
+
160
+ .checkmark:after {
161
+ content: "" !important;
162
+ position: absolute !important;
163
+ display: none !important;
164
+ }
165
+
166
+ .gr-checkbox input:checked ~ .checkmark:after {
167
+ display: block !important;
168
+ }
169
+
170
+ .gr-checkbox .checkmark:after {
171
+ left: 8px !important;
172
+ top: 4px !important;
173
+ width: 6px !important;
174
+ height: 12px !important;
175
+ border: solid white !important;
176
+ border-width: 0 2px 2px 0 !important;
177
+ transform: rotate(45deg) !important;
178
+ }
179
+
180
+ .dark .gr-checkbox .checkmark {
181
+ background-color: rgba(30, 41, 59, 0.5) !important;
182
+ border-color: #93c5fd !important;
183
+ }
184
+
185
+ .dark .gr-checkbox input:checked ~ .checkmark {
186
+ background: linear-gradient(135deg, var(--primary) 0%, #1e8a50 100%) !important;
187
+ }