EvgenyKu commited on
Commit
f2d49da
·
1 Parent(s): eb9aa6b

initial commit

Browse files
Files changed (6) hide show
  1. README.md +6 -5
  2. app.py +318 -0
  3. prompt.txt +1 -0
  4. requirements.txt +19 -0
  5. space.yaml +8 -0
  6. style.css +187 -0
README.md CHANGED
@@ -1,12 +1,13 @@
1
  ---
2
- title: IconDDDzilla Test
3
- emoji: 🦀
4
- colorFrom: purple
5
- colorTo: yellow
6
  sdk: gradio
7
- sdk_version: 5.23.3
8
  app_file: app.py
9
  pinned: false
 
10
  ---
11
 
12
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: IconDDDzilla
3
+ emoji: 🦖
4
+ colorFrom: gray
5
+ colorTo: gray
6
  sdk: gradio
7
+ sdk_version: 5.23.0
8
  app_file: app.py
9
  pinned: false
10
+ license: apache-2.0
11
  ---
12
 
13
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py ADDED
@@ -0,0 +1,318 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ #import random
3
+ import datetime
4
+ import spaces
5
+ import torch
6
+ import gradio as gr
7
+ #from huggingface_hub import hf_hub_download
8
+ import traceback
9
+ from transformers import pipeline
10
+ from huggingface_hub import login
11
+ from diffusers import FluxPipeline
12
+ from deep_translator import GoogleTranslator
13
+
14
+ login(token = os.getenv('HF_TOKEN'))
15
+
16
+ print("="*50)
17
+ print(f"PyTorch version: {torch.__version__}")
18
+ print(f"CUDA available: {torch.cuda.is_available()}")
19
+ print(f"GPU count: {torch.cuda.device_count()}")
20
+ if torch.cuda.is_available():
21
+ print(f"Current device: {torch.cuda.current_device()}")
22
+ print(f"Device name: {torch.cuda.get_device_name(0)}")
23
+ print("="*50)
24
+
25
+ device = "cuda" if torch.cuda.is_available() else "cpu"
26
+
27
+ print(f"{datetime.datetime.now()} Загрузка модели FLUX.1-dev")
28
+ pipe = FluxPipeline.from_pretrained(
29
+ # pretrained_model_name_or_path = local_path,
30
+ "black-forest-labs/FLUX.1-dev",
31
+ torch_dtype=torch.bfloat16, # Используем bfloat16 для A100
32
+ # low_cpu_mem_usage=True, # Экономия памяти
33
+ # device_map="balanced",
34
+ # local_files_only=True
35
+ # variant="fp16",
36
+ use_safetensors=True
37
+ )
38
+ print(f"{datetime.datetime.now()} Загрузка модели FLUX.1-dev успешно завершена")
39
+
40
+ print(f"{datetime.datetime.now()} Загрузка LoRA")
41
+ pipe.load_lora_weights("Shakker-Labs/FLUX.1-dev-LoRA-add-details", weight_name="FLUX-dev-lora-add_details.safetensors")
42
+ print(f"{datetime.datetime.now()} Загрузка LoRA успешно завершена")
43
+
44
+ pipe.fuse_lora(lora_scale=1.0)
45
+ pipe.to(device)
46
+ pipe.enable_model_cpu_offload() # Выгрузка неиспользуемых компонентов
47
+
48
+ # print(f"{datetime.datetime.now()} Загрузка модели stabilityai/stable-diffusion-x4-upscaler")
49
+ # upscaler_pipeline = StableDiffusionUpscalePipeline.from_pretrained(
50
+ # "stabilityai/stable-diffusion-x4-upscaler",
51
+ # torch_dtype=torch.float16
52
+ # ).to(device)
53
+ # print(f"{datetime.datetime.now()} Загрузка модели stabilityai/stable-diffusion-x4-upscaler успешно завершена")
54
+ #
55
+ # upscaler_pipeline.enable_model_cpu_offload() # Выгрузка неиспользуемых компонентов
56
+
57
+ print(f"{datetime.datetime.now()} Загрузка модели briaai/RMBG-1.4")
58
+ bg_remover = pipeline("image-segmentation", "briaai/RMBG-1.4", trust_remote_code=True )
59
+ print(f"{datetime.datetime.now()} Загрузка модели briaai/RMBG-1.4 успешно завершена")
60
+
61
+ @spaces.GPU()
62
+ def generate_image(object_name, remove_bg=True):
63
+ try:
64
+ # Формирование промпта
65
+ object_name = translate_ru_en(object_name)
66
+ prompt = create_template_prompt(object_name)
67
+
68
+ # Для имитации генерации (можно заменить на реальный вызов ComfyUI API)
69
+ print(f"Генерация иконки для объекта: {object_name}")
70
+ print(f"Промпт: {prompt[:100]}...")
71
+ # print(f"Параметры: seed={seed}, steps={steps}, размер={width}x{height}")
72
+ print(f"Опции: remove_bg={remove_bg}")
73
+ steps = os.getenv('STEPS') if os.getenv('STEPS') is not None else 10
74
+ print(f"Шаги: {steps}")
75
+
76
+ image = pipe(
77
+ prompt,
78
+ height=1024,
79
+ width=1024,
80
+ guidance_scale=3.5,
81
+ num_inference_steps=int(steps),
82
+ generator=torch.Generator(device).manual_seed(42)
83
+ ).images[0]
84
+
85
+ torch.cuda.empty_cache()
86
+
87
+ # if upscale :
88
+ # torch.cuda.empty_cache()
89
+ # upscaled_image = upscaler_pipeline(
90
+ # prompt="", # Обязательный параметр, но может быть пустым
91
+ # image=image,
92
+ # num_inference_steps=steps, # Оптимально для качества/скорости
93
+ # guidance_scale=1.0 # Минимальное значение для апскейла
94
+ # ).images[0]
95
+ # return upscaled_image
96
+
97
+ if remove_bg :
98
+ remove_bg_image = bg_remover(image)
99
+ torch.cuda.empty_cache()
100
+ return remove_bg_image
101
+
102
+ torch.cuda.empty_cache()
103
+ return image
104
+
105
+ except Exception as e:
106
+ print(f"Ошибка при генерации изображения: {e}")
107
+ traceback.print_exc()
108
+ return None
109
+
110
+ def create_template_prompt(object_name):
111
+ template = load_text("prompt.txt")
112
+ return template.format(object_name = object_name)
113
+
114
+ def translate_ru_en(text: str):
115
+ try:
116
+ # Проверка на кириллицу (если включено)
117
+ if not any('\u0400' <= char <= '\u04FF' for char in text):
118
+ return text
119
+
120
+ # Создаем переводчик
121
+ translator = GoogleTranslator(source="ru", target="en")
122
+ # Выполняем перевод
123
+ return translator.translate(text)
124
+
125
+ except Exception as e:
126
+ print(f"Ошибка перевода: {e}")
127
+ traceback.print_exc()
128
+ return text
129
+
130
+ def load_text(file_name):
131
+ with open(file_name, 'r', encoding='utf-8') as f:
132
+ return f.read()
133
+
134
+ custom_css = load_text("style.css")
135
+
136
+ # Создание интерфейса Gradio
137
+ with gr.Blocks(title="3D Icon Generator", css=custom_css, theme=gr.themes.Default()) as app:
138
+ gr.Markdown("# iconDDDzilla")
139
+ gr.Markdown("### Create 3d icons with transparent background in one click!")
140
+
141
+ with gr.Row():
142
+ with gr.Column():
143
+ # Входные параметры
144
+ object_input = gr.Textbox(label="Object name", placeholder="Type object name (for example: calendar, phone, camera)")
145
+ remove_bg_checkbox = gr.Checkbox(label="Remove background", value=True)
146
+
147
+ # with gr.Accordion("Расширенные настройки", open=False):
148
+ # custom_prompt = gr.Textbox(label="Пользовательский промпт", placeholder="Оставьте пустым для использования шаблона", lines=3)
149
+ #
150
+ # with gr.Row():
151
+ # seed = gr.Number(label="Seed", value=276789180904019, precision=0)
152
+ # steps = gr.Slider(minimum=1, maximum=5, value=5, step=1, label="Шаги")
153
+ #
154
+ # with gr.Row():
155
+ # width = gr.Slider(minimum=512, maximum=2048, value=1024, step=64, label="Ширина")
156
+ # height = gr.Slider(minimum=512, maximum=2048, value=1024, step=64, label="Высота")
157
+ #
158
+ # with gr.Row():
159
+ # #upscale_checkbox = gr.Checkbox(label="Применить апскейл", value=True)
160
+ # remove_bg_checkbox = gr.Checkbox(label="Удалить фон", value=False)
161
+
162
+ # Кнопка генерации
163
+ generate_btn = gr.Button("Run")
164
+
165
+ with gr.Column():
166
+ # Выходное изображение
167
+ output_image = gr.Image(label="Image")
168
+
169
+ # Примеры использования
170
+ # examples = gr.Examples(
171
+ # examples=[
172
+ # ["calendar", "", 276789180904019, 5, 1024, 1024, True],
173
+ # ["camera", "", 391847529184, 5, 1024, 1024, True],
174
+ # ["smartphone", "", 654321987654, 5, 1024, 1024, True],
175
+ # ["headphones", "", 123456789012, 5, 1024, 1024, True],
176
+ # ],
177
+ # inputs=[
178
+ # object_input,
179
+ # custom_prompt,
180
+ # seed,
181
+ # steps,
182
+ # width,
183
+ # height,
184
+ # #upscale_checkbox,
185
+ # remove_bg_checkbox
186
+ # ],
187
+ # outputs=[output_image],
188
+ # fn=generate_image,
189
+ # )
190
+
191
+ # Информация о моделях
192
+ # with gr.Accordion("Информация о используемых моделях", open=False):
193
+ # gr.Markdown("""
194
+ # ## Используемые модели
195
+ #
196
+ # - **Основная модель:** [flux1-dev-fp8.safetensors](https://huggingface.co/lllyasviel/flux1_dev/blob/main/flux1-dev-fp8.safetensors) от Stability AI
197
+ # - **Модель апскейла:** [4x_NMKD-Superscale-SP_178000_G.pth](https://huggingface.co/gemasai/4x_NMKD-Superscale-SP_178000_G) для улучшения качества изображения
198
+ # - **Модель удаления фона:** [RMBG-1.4](https://huggingface.co/briaai/RMBG-1.4) для качественного удаления фона
199
+ #
200
+ # Все модели автоматически загружаются при первом запуске приложения.
201
+ # """)
202
+
203
+ # Привязка функции к нажатию кнопки
204
+ generate_btn.click(
205
+ fn=generate_image,
206
+ inputs=[
207
+ object_input,
208
+ # custom_prompt,
209
+ # seed,
210
+ # steps,
211
+ # width,
212
+ # height,
213
+ #upscale_checkbox,
214
+ remove_bg_checkbox
215
+ ],
216
+ outputs=[output_image]
217
+ )
218
+
219
+ # Запуск приложения
220
+ if __name__ == "__main__":
221
+ app.launch()
222
+
223
+
224
+
225
+
226
+ ### OLD UNUSED CODE!!! BE CAREFUL!!! ###
227
+
228
+ # Создаем необходимые директории
229
+ # os.makedirs("models", exist_ok=True)
230
+ # os.makedirs("models/checkpoints", exist_ok=True)
231
+ # os.makedirs("models/loras", exist_ok=True)
232
+ # os.makedirs("models/upscale_models", exist_ok=True)
233
+ # os.makedirs("models/rembg", exist_ok=True)
234
+ # os.makedirs("outputs", exist_ok=True)
235
+ # os.makedirs("temp_uploads", exist_ok=True)
236
+
237
+
238
+ # Загрузка моделей с Hugging Face
239
+ # def download_model(repo_id, filename, local_dir):
240
+ # """Загрузка модели с Hugging Face Hub"""
241
+ # local_path = os.path.join(local_dir, filename)
242
+ # if not os.path.exists(local_path):
243
+ # print(f"Загрузка {filename} из {repo_id}...")
244
+ # try:
245
+ # file_path = hf_hub_download(
246
+ # repo_id=repo_id,
247
+ # filename=filename,
248
+ # local_dir=local_dir,
249
+ # local_dir_use_symlinks=False
250
+ # )
251
+ # print(f"Модель успешно загружена: {file_path}")
252
+ # return file_path
253
+ # except Exception as e:
254
+ # print(f"Ошибка при загрузке модели {filename}: {e}")
255
+ # return None
256
+ # else:
257
+ # print(f"Модель {filename} уже присутствует: {local_path}")
258
+ # return local_path
259
+
260
+ # Вынесем загрузку моделей за пределы функции generate_image
261
+ # это критично для работы на ZeroGPU в Hugging Face Spaces
262
+ # def download_all_models():
263
+ # models = {
264
+ # "flux": download_model(
265
+ # "lllyasviel/flux1_dev",
266
+ # "flux1-dev-fp8.safetensors",
267
+ # "models/checkpoints"
268
+ # ),
269
+ # # "upscale": download_model(
270
+ # # "gemasai/4x_NMKD-Superscale-SP_178000_G",
271
+ # # "4x_NMKD-Superscale-SP_178000_G.pth",
272
+ # # "models/upscale_models"
273
+ # # ),
274
+ # # "rembg": "briaai/RMBG-1.4" # Используем модель RMBG-1.4 через transformers pipeline
275
+ # }
276
+ # return models
277
+
278
+ # def save_uploaded_file(file):
279
+ # """Сохранение загруженного файла"""
280
+ # if file is None:
281
+ # return None
282
+ #
283
+ # filename = os.path.join("temp_uploads", f"{random.randint(1000000, 9999999)}{os.path.splitext(file.name)[1]}")
284
+ # with open(filename, "wb") as f:
285
+ # f.write(file.read())
286
+ # return filename
287
+
288
+ # Функция для получения значения по индексу (используется в ComfyUI)
289
+ # def get_value_at_index(obj, index):
290
+ # """Получение значения из объекта по индексу из экспортированного ComfyUI кода"""
291
+ # if isinstance(obj, list):
292
+ # return obj[index]
293
+ # elif isinstance(obj, tuple):
294
+ # return obj[index]
295
+ # elif isinstance(obj, dict):
296
+ # return list(obj.values())[index]
297
+ # else:
298
+ # return obj[index]
299
+
300
+ # Загрузка моделей при запуске
301
+ #models = download_all_models()
302
+
303
+ # Инициализация pipeline для удаления фона
304
+ # try:
305
+ # rembg_pipeline = pipeline("image-segmentation", model=models["rembg"], trust_remote_code=True)
306
+ # print(f"Модель удаления фона успешно загружена: {models['rembg']}")
307
+ # except Exception as e:
308
+ # print(f"Ошибка при загрузке модели удаления фона: {e}")
309
+ # rembg_pipeline = None
310
+
311
+ # Укажите абсолютный путь к модели
312
+ # model_path = os.path.abspath("models/checkpoints/flux1-dev-fp8.safetensors")
313
+
314
+ # Проверьте существование ключевого файла
315
+ # if not os.path.exists(os.path.join(model_path, "model_index.json")):
316
+ # raise FileNotFoundError(f"Модель не найдена по пути: {model_path}")
317
+
318
+ # local_path = os.path.join("models/checkpoints", "")
prompt.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ 3D {object_name} icon: Minimal geo, layered, aluminum, acrylic, rubber, 3-point, 8k, PBR, Bezier, isometric
requirements.txt ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ deep_translator
space.yaml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ title: iconDDDzilla
2
+ emoji: 🦖
3
+ colorFrom: gray
4
+ colorTo: gray
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
+ }