AkashKumarave commited on
Commit
a4de65c
·
verified ·
1 Parent(s): 8839402

Upload 12 files

Browse files
Files changed (12) hide show
  1. .gitattributes +3 -0
  2. README.md +8 -9
  3. app.py +197 -0
  4. data/1.jpg +3 -0
  5. data/1.webp +0 -0
  6. data/1777043.jpg +3 -0
  7. data/2.webp +0 -0
  8. data/2807615.jpg +3 -0
  9. data/3.webp +0 -0
  10. data/76860.jpg +0 -0
  11. requirements.txt +3 -0
  12. style.css +408 -0
.gitattributes CHANGED
@@ -33,3 +33,6 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ data/1.jpg filter=lfs diff=lfs merge=lfs -text
37
+ data/1777043.jpg filter=lfs diff=lfs merge=lfs -text
38
+ data/2807615.jpg filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -1,13 +1,12 @@
1
  ---
2
- title: Remove Background Web
3
- emoji: 🖼️
4
- colorFrom: red
5
- colorTo: yellow
6
- sdk: static
7
- pinned: false
8
- models:
9
- - briaai/RMBG-1.4
10
- short_description: In-browser background removal
11
  ---
12
 
13
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: Gemini-2.5-Flash-Nano-Banana
3
+ emoji: 📚
4
+ colorFrom: indigo
5
+ colorTo: blue
6
+ sdk: gradio
7
+ sdk_version: 5.34.0
8
+ app_file: app.py
9
+ pinned: true
 
10
  ---
11
 
12
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import os
3
+ import time
4
+ import uuid
5
+ import tempfile
6
+ from PIL import Image, ImageDraw, ImageFont
7
+ import gradio as gr
8
+ import base64
9
+ import mimetypes
10
+ from io import BytesIO
11
+
12
+ from google import genai
13
+ from google.genai import types
14
+
15
+ def generate(text, images, api_key, model="gemini-2.5-flash-image-preview"):
16
+ # Initialize client using provided api_key (or fallback to env variable)
17
+ client = genai.Client(api_key=(api_key.strip() if api_key and api_key.strip() != ""
18
+ else os.environ.get("GEMINI_API_KEY")))
19
+
20
+ # Prepare contents with images first, then text
21
+ contents = images + [text]
22
+
23
+ response = client.models.generate_content(
24
+ model=model,
25
+ contents=contents,
26
+ )
27
+
28
+ text_response = ""
29
+ image_path = None
30
+
31
+ for part in response.candidates[0].content.parts:
32
+ if part.text is not None:
33
+ text_response += part.text + "\n"
34
+ elif part.inline_data is not None:
35
+ # Create a temporary file to store the generated image
36
+ with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as tmp:
37
+ temp_path = tmp.name
38
+ generated_image = Image.open(BytesIO(part.inline_data.data))
39
+ generated_image.save(temp_path)
40
+ image_path = temp_path
41
+ print(f"Generated image saved to: {temp_path} with prompt: {text}")
42
+
43
+ return image_path, text_response
44
+
45
+ def load_uploaded_images(uploaded_files):
46
+ """Load and display uploaded images immediately"""
47
+ uploaded_images = []
48
+ if uploaded_files:
49
+ for file in uploaded_files:
50
+ if file.name.lower().endswith(('.png', '.jpg', '.jpeg', '.webp')):
51
+ img = Image.open(file.name)
52
+ if img.mode == "RGBA":
53
+ img = img.convert("RGBA")
54
+ uploaded_images.append(img)
55
+ return uploaded_images
56
+
57
+ def process_image_and_prompt(uploaded_files, prompt, gemini_api_key):
58
+ try:
59
+ input_text = prompt
60
+ model = "gemini-2.5-flash-image-preview"
61
+
62
+ # Load images from uploaded files
63
+ images = []
64
+ uploaded_images = []
65
+ if uploaded_files:
66
+ for file in uploaded_files:
67
+ if file.name.lower().endswith(('.png', '.jpg', '.jpeg', '.webp')):
68
+ img = Image.open(file.name)
69
+ if img.mode == "RGBA":
70
+ img = img.convert("RGBA")
71
+ images.append(img)
72
+ uploaded_images.append(img)
73
+
74
+ if not images:
75
+ raise gr.Error("Please upload at least one image", duration=5)
76
+
77
+ # Format: [dress_image, model_image, text_input] or [image1, image2, ..., text_input]
78
+ image_path, text_response = generate(text=input_text, images=images, api_key=gemini_api_key, model=model)
79
+
80
+ if image_path:
81
+ # Load and convert the image if needed.
82
+ result_img = Image.open(image_path)
83
+ if result_img.mode == "RGBA":
84
+ result_img = result_img.convert("RGBA")
85
+ return uploaded_images, [result_img], "" # Return uploaded images, generated image, and empty text output.
86
+ else:
87
+ # Return uploaded images, no generated image, and the text response.
88
+ return uploaded_images, None, text_response
89
+ except Exception as e:
90
+ raise gr.Error(f"Error Getting {e}", duration=5)
91
+
92
+
93
+ # Build a Blocks-based interface with a custom HTML header and CSS
94
+ with gr.Blocks(css_paths="style.css",) as demo:
95
+ # Custom HTML header with proper class for styling
96
+ gr.HTML(
97
+ """
98
+ <div class="header-container">
99
+ <div>
100
+ <img src="https://www.gstatic.com/lamda/images/gemini_favicon_f069958c85030456e93de685481c559f160ea06b.png" alt="Gemini logo">
101
+ </div>
102
+ <div>
103
+ <h1>Gemini for Image Editing</h1>
104
+ <p>Powered by <a href="https://gradio.app/">Gradio</a>⚡️|
105
+ <a href="https://huggingface.co/spaces/ameerazam08/Gemini-Image-Edit?duplicate=true">Duplicate</a> this Repo |
106
+ <a href="https://aistudio.google.com/apikey">Get an API Key</a> |
107
+ Follow me on Twitter: <a href="https://x.com/Ameerazam18">Ameerazam18</a></p>
108
+ </div>
109
+ </div>
110
+ """
111
+ )
112
+
113
+ with gr.Accordion("⚠️ API Configuration ⚠️", open=False, elem_classes="config-accordion"):
114
+ gr.Markdown("""
115
+ - **Issue:** ❗ Sometimes the model returns text instead of an image.
116
+ ### 🔧 Steps to Address:
117
+ 1. **🛠️ Duplicate the Repository**
118
+ - Create a separate copy for modifications.
119
+ 2. **🔑 Use Your Own Gemini API Key**
120
+ - You **must** configure your own Gemini key for generation!
121
+ """)
122
+
123
+ with gr.Accordion("📌 Usage Instructions", open=False, elem_classes="instructions-accordion"):
124
+ gr.Markdown("""
125
+ ### 📌 Usage
126
+ - Upload an image and enter a prompt to generate outputs.
127
+ - If text is returned instead of an image, it will appear in the text output.
128
+ - Upload Only PNG Image
129
+ - ❌ **Do not use NSFW images!**
130
+ """)
131
+
132
+ with gr.Row(elem_classes="main-content"):
133
+ with gr.Column(elem_classes="input-column"):
134
+ image_input = gr.File(
135
+ file_types=["image"],
136
+ file_count="multiple",
137
+ label="Upload Images ",
138
+ elem_id="image-input",
139
+ elem_classes="upload-box"
140
+ )
141
+ gemini_api_key = gr.Textbox(
142
+ lines=1,
143
+ placeholder="Enter Gemini API Key (optional)",
144
+ label="Gemini API Key (optional)",
145
+ elem_classes="api-key-input"
146
+ )
147
+ prompt_input = gr.Textbox(
148
+ lines=2,
149
+ placeholder="Enter prompt here...",
150
+ label="Prompt",
151
+ elem_classes="prompt-input"
152
+ )
153
+ submit_btn = gr.Button("Generate", elem_classes="generate-btn")
154
+
155
+ with gr.Column(elem_classes="output-column"):
156
+ uploaded_gallery = gr.Gallery(label="Uploaded Images", elem_classes="uploaded-gallery")
157
+ output_gallery = gr.Gallery(label="Generated Outputs", elem_classes="output-gallery")
158
+ output_text = gr.Textbox(
159
+ label="Gemini Output",
160
+ placeholder="Text response will appear here if no image is generated.",
161
+ elem_classes="output-text"
162
+ )
163
+
164
+ # Set up the interaction with three outputs.
165
+ submit_btn.click(
166
+ fn=process_image_and_prompt,
167
+ inputs=[image_input, prompt_input, gemini_api_key],
168
+ outputs=[uploaded_gallery, output_gallery, output_text],
169
+ )
170
+
171
+ # Update uploaded gallery immediately when files are uploaded
172
+ image_input.upload(
173
+ fn=load_uploaded_images,
174
+ inputs=[image_input],
175
+ outputs=[uploaded_gallery],
176
+ )
177
+
178
+ gr.Markdown("## Try these examples", elem_classes="gr-examples-header")
179
+
180
+ examples = [
181
+ ["data/1.webp", 'change text to "AMEER"'],
182
+ ["data/2.webp", "remove the spoon from hand only"],
183
+ ["data/3.webp", 'change text to "Make it "'],
184
+ ["data/1.jpg", "add joker style only on face"],
185
+ ["data/1777043.jpg", "add joker style only on face"],
186
+ ["data/2807615.jpg", "add lipstick on lip only"],
187
+ ["data/76860.jpg", "add lipstick on lip only"],
188
+ ["data/2807615.jpg", "make it happy looking face only"],
189
+ ]
190
+
191
+ gr.Examples(
192
+ examples=examples,
193
+ inputs=[image_input, prompt_input,],
194
+ elem_id="examples-grid"
195
+ )
196
+
197
+ demo.queue(max_size=50).launch(mcp_server=True, share=True)
data/1.jpg ADDED

Git LFS Details

  • SHA256: 9ed6db97eca38db724e4144a9507ef07ee531dd324f3ddd97a9c78d8d58d0131
  • Pointer size: 131 Bytes
  • Size of remote file: 149 kB
data/1.webp ADDED
data/1777043.jpg ADDED

Git LFS Details

  • SHA256: 57fa80bcac85aa2af14193857983047edde29b016971221d71a6f11cf1d1d72d
  • Pointer size: 131 Bytes
  • Size of remote file: 237 kB
data/2.webp ADDED
data/2807615.jpg ADDED

Git LFS Details

  • SHA256: f2592b7ec591e6797450c2749c450d28057eb0b538b6510c7b8cb3f7df7fe989
  • Pointer size: 131 Bytes
  • Size of remote file: 244 kB
data/3.webp ADDED
data/76860.jpg ADDED
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ google-genai==1.5.0
2
+ gradio
3
+ pydantic==2.10.6
style.css ADDED
@@ -0,0 +1,408 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Creating a more modern looking UI for the Gemini Image Editing App */
2
+ /* Global Styles */
3
+ :root {
4
+ --primary-color: #4f46e5;
5
+ --primary-light: #6366f1;
6
+ --primary-dark: #3730a3;
7
+ --secondary-color: #9333ea;
8
+ --accent-color: #ec4899;
9
+ --text-color: #0f172a;
10
+ --text-light: #64748b;
11
+ --bg-color: #f8fafc;
12
+ --card-bg: #ffffff;
13
+ --border-color: #e2e8f0;
14
+ --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
15
+ --transition: all 0.3s ease;
16
+ --radius: 12px;
17
+ --header-gradient: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
18
+ }
19
+
20
+ /* Dark mode support */
21
+ .dark {
22
+ --text-color: #e2e8f0;
23
+ --text-light: #94a3b8;
24
+ --bg-color: #0f172a;
25
+ --card-bg: #1e293b;
26
+ --border-color: #334155;
27
+ }
28
+
29
+ /* Base container styling */
30
+ .gradio-container {
31
+ font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
32
+ background-color: var(--bg-color);
33
+ color: var(--text-color);
34
+ max-width: 1200px;
35
+ margin: 0 auto;
36
+ padding: 2rem;
37
+ box-shadow: var(--shadow);
38
+ border-radius: var(--radius);
39
+ }
40
+
41
+ /* Header styling */
42
+ .header-container {
43
+ background: var(--header-gradient);
44
+ border-radius: var(--radius);
45
+ padding: 2rem;
46
+ margin-bottom: 2rem;
47
+ box-shadow: var(--shadow);
48
+ color: white;
49
+ display: flex;
50
+ align-items: center;
51
+ justify-content: center;
52
+ gap: 20px;
53
+ }
54
+
55
+ .header-container img {
56
+ width: 100px;
57
+ height: 100px;
58
+ filter: drop-shadow(0 0 8px rgba(255, 255, 255, 0.5));
59
+ transition: var(--transition);
60
+ }
61
+
62
+ .header-container img:hover {
63
+ transform: scale(1.05) rotate(5deg);
64
+ }
65
+
66
+ .header-container h1 {
67
+ font-size: 2.5rem;
68
+ font-weight: 700;
69
+ margin-bottom: 0.5rem;
70
+ background: linear-gradient(45deg, #fff, #f0f0ff);
71
+ -webkit-background-clip: text;
72
+ background-clip: text;
73
+ color: transparent;
74
+ display: inline-block;
75
+ }
76
+
77
+ .header-container a {
78
+ color: white;
79
+ text-decoration: none;
80
+ font-weight: 600;
81
+ border-bottom: 2px solid rgba(255, 255, 255, 0.5);
82
+ transition: var(--transition);
83
+ padding-bottom: 2px;
84
+ }
85
+
86
+ .header-container a:hover {
87
+ border-color: white;
88
+ }
89
+
90
+ /* Accordion styling */
91
+ .gr-accordion {
92
+ border: none !important;
93
+ background: var(--card-bg);
94
+ border-radius: var(--radius);
95
+ overflow: hidden;
96
+ box-shadow: var(--shadow);
97
+ margin-bottom: 1.5rem;
98
+ transition: var(--transition);
99
+ }
100
+
101
+ .gr-accordion:hover {
102
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
103
+ }
104
+
105
+ .gr-accordion-title {
106
+ background-color: var(--primary-color);
107
+ color: white !important;
108
+ padding: 1rem 1.5rem;
109
+ font-weight: 600;
110
+ cursor: pointer;
111
+ }
112
+
113
+
114
+ /* Input fields */
115
+ .gr-input, .gr-textarea {
116
+ width: 100%;
117
+ padding: 0.75rem 1rem;
118
+ border: 1px solid var(--border-color);
119
+ border-radius: var(--radius);
120
+ background-color: var(--card-bg);
121
+ transition: var(--transition);
122
+ font-size: 1rem;
123
+ color: var(--text-color);
124
+ }
125
+
126
+ .gr-input:focus, .gr-textarea:focus {
127
+ border-color: var(--primary-color);
128
+ box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.2);
129
+ outline: none;
130
+ }
131
+
132
+ .gr-form .gr-form-label {
133
+ font-weight: 600;
134
+ color: var(--text-color);
135
+ margin-bottom: 0.5rem;
136
+ }
137
+
138
+ /* Adding Dark mode handling */
139
+ /* Generate button - Modified to use header gradient in both light and dark mode */
140
+ .gr-button.gr-button-primary,
141
+ button.generate-btn,
142
+ #component-54 > div.svelte-1pf7t34 > div > button {
143
+ background: var(--header-gradient) !important;
144
+ color: white !important;
145
+ border: none !important;
146
+ border-radius: var(--radius) !important;
147
+ padding: 0.75rem 1.5rem !important;
148
+ font-size: 1rem !important;
149
+ font-weight: 600 !important;
150
+ cursor: pointer !important;
151
+ transition: var(--transition) !important;
152
+ width: 100% !important;
153
+ text-transform: uppercase !important;
154
+ letter-spacing: 1px !important;
155
+ box-shadow: 0 4px 6px -1px rgba(79, 70, 229, 0.4) !important;
156
+ }
157
+
158
+ .gr-button.gr-button-primary:hover,
159
+ button.generate-btn:hover,
160
+ #component-54 > div.svelte-1pf7t34 > div > button:hover {
161
+ transform: translateY(-2px) !important;
162
+ box-shadow: 0 10px 15px -3px rgba(79, 70, 229, 0.4) !important;
163
+ }
164
+
165
+ .gr-button.gr-button-primary:active,
166
+ button.generate-btn:active,
167
+ #component-54 > div.svelte-1pf7t34 > div > button:active {
168
+ transform: translateY(1px) !important;
169
+ }
170
+
171
+ /* Gallery output */
172
+ .gr-gallery {
173
+ background-color: var(--card-bg);
174
+ border-radius: var(--radius);
175
+ padding: 1rem;
176
+ box-shadow: var(--shadow);
177
+ min-height: 300px;
178
+ }
179
+
180
+ .gr-gallery img {
181
+ border-radius: calc(var(--radius) - 4px);
182
+ transition: var(--transition);
183
+ object-fit: contain !important;
184
+ max-height: 100% !important;
185
+ max-width: 100% !important;
186
+ }
187
+
188
+ .gr-gallery img:hover {
189
+ transform: scale(1.02);
190
+ }
191
+
192
+ /* Output text area */
193
+ .output-text {
194
+ background-color: var(--card-bg);
195
+ border-radius: var(--radius);
196
+ padding: 1.5rem;
197
+ box-shadow: var(--shadow);
198
+ line-height: 1.6;
199
+ min-height: 100px;
200
+ color: var(--text-color);
201
+ }
202
+
203
+ /* Examples section - Fixed for dark mode */
204
+ .gr-examples-header {
205
+ font-weight: 600 !important;
206
+ margin: 2rem 0 1rem !important;
207
+ padding-bottom: 0.5rem !important;
208
+ /* Removed border-bottom to avoid duplicate lines */
209
+ color: var(--primary-light) !important;
210
+ font-size: 1.5rem !important;
211
+ display: block !important;
212
+ visibility: visible !important;
213
+ }
214
+
215
+ /* Handling duplicate lines coming up below the examples header */
216
+ .gradio-container hr {
217
+ display: none !important;
218
+ }
219
+
220
+ /* Fix horizontal separator styling if needed */
221
+ .gradio-container hr:first-of-type {
222
+ display: block !important;
223
+ border-top: 2px solid var(--primary-light) !important;
224
+ margin: 1rem 0 2rem 0 !important;
225
+ }
226
+
227
+ /* Fix dark mode examples grid */
228
+ .gr-examples {
229
+ display: grid;
230
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
231
+ gap: 1rem;
232
+ margin-top: 1.5rem;
233
+ }
234
+
235
+ /* Fix dark mode examples background */
236
+ .gr-sample {
237
+ background-color: var(--card-bg) !important;
238
+ border-radius: var(--radius);
239
+ overflow: hidden;
240
+ box-shadow: var(--shadow);
241
+ transition: var(--transition);
242
+ cursor: pointer;
243
+ }
244
+
245
+ .gr-sample:hover {
246
+ transform: translateY(-2px);
247
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
248
+ }
249
+
250
+ .gr-sample img {
251
+ width: 100%;
252
+ height: 150px;
253
+ object-fit: cover;
254
+ }
255
+
256
+ /* Examples table styling fixes for dark mode */
257
+ table {
258
+ background-color: transparent !important;
259
+ color: var(--text-color) !important;
260
+ }
261
+
262
+ table tr {
263
+ background-color: var(--card-bg) !important;
264
+ color: var(--text-color) !important;
265
+ }
266
+
267
+ table td {
268
+ background-color: var(--card-bg) !important;
269
+ color: var(--text-color) !important;
270
+ border-color: var(--border-color) !important;
271
+ }
272
+
273
+ /* Responsive adjustments */
274
+ @media (max-width: 768px) {
275
+ .gradio-container {
276
+ padding: 1rem;
277
+ }
278
+
279
+ .header-container {
280
+ flex-direction: column;
281
+ text-align: center;
282
+ padding: 1.5rem;
283
+ }
284
+
285
+ .header-container h1 {
286
+ font-size: 2rem;
287
+ }
288
+ }
289
+
290
+ /* Custom scrollbar */
291
+ ::-webkit-scrollbar {
292
+ width: 8px;
293
+ height: 8px;
294
+ }
295
+
296
+ ::-webkit-scrollbar-track {
297
+ background: var(--bg-color);
298
+ }
299
+
300
+ ::-webkit-scrollbar-thumb {
301
+ background: var(--primary-light);
302
+ border-radius: 4px;
303
+ }
304
+
305
+ ::-webkit-scrollbar-thumb:hover {
306
+ background: var(--primary-color);
307
+ }
308
+
309
+ /* Ensure proper viewport handling for mobile */
310
+ @media screen and (max-width: 767px) {
311
+ body, html {
312
+ overflow-x: hidden !important;
313
+ width: 100vw !important;
314
+ max-width: 100% !important;
315
+ }
316
+
317
+ /* Force central alignment for the entire app container */
318
+ .gradio-container {
319
+ padding: 1rem !important;
320
+ margin: 0 auto !important;
321
+ max-width: 100% !important;
322
+ width: 100% !important;
323
+ left: 0 !important;
324
+ right: 0 !important;
325
+ box-sizing: border-box !important;
326
+ overflow-x: hidden !important;
327
+ }
328
+
329
+ /* Fix header container on mobile */
330
+ .header-container {
331
+ flex-direction: column !important;
332
+ text-align: center !important;
333
+ padding: 1rem !important;
334
+ width: 100% !important;
335
+ box-sizing: border-box !important;
336
+ margin-left: auto !important;
337
+ margin-right: auto !important;
338
+ }
339
+
340
+ /* Ensure all content blocks are properly centered */
341
+ .main-content,
342
+ .input-column,
343
+ .output-column,
344
+ .gr-form,
345
+ .gr-panel,
346
+ .gr-box,
347
+ .gr-input,
348
+ .gr-text-input,
349
+ .gr-gallery,
350
+ .gr-button,
351
+ #component-54 > div.svelte-1pf7t34 > div > button {
352
+ width: 100% !important;
353
+ max-width: 100% !important;
354
+ margin-left: auto !important;
355
+ margin-right: auto !important;
356
+ box-sizing: border-box !important;
357
+ }
358
+
359
+
360
+ /* Fix examples area */
361
+ .gr-examples {
362
+ grid-template-columns: 1fr !important;
363
+ width: 100% !important;
364
+ }
365
+
366
+ /* Fix example tables on mobile */
367
+ table {
368
+ table-layout: fixed !important;
369
+ width: 100% !important;
370
+ }
371
+
372
+ table td {
373
+ word-break: break-word !important;
374
+ }
375
+ }
376
+
377
+ /* Fix for extreme narrow screens (small Android phones) */
378
+ @media screen and (max-width: 380px) {
379
+ .header-container h1 {
380
+ font-size: 1.8rem !important;
381
+ }
382
+
383
+ .header-container p {
384
+ font-size: 0.9rem !important;
385
+ }
386
+
387
+ /* Stack everything vertically */
388
+ .gr-panel {
389
+ display: flex !important;
390
+ flex-direction: column !important;
391
+ }
392
+ }
393
+
394
+ /* Custom fix for the container to always stay centered on any device */
395
+ #gradio-app {
396
+ display: flex !important;
397
+ justify-content: center !important;
398
+ width: 100% !important;
399
+ max-width: 100% !important;
400
+ margin: 0 auto !important;
401
+ overflow-x: hidden !important;
402
+ }
403
+
404
+ /* Ensure the root container doesn't cause horizontal scroll */
405
+ .root {
406
+ max-width: 100% !important;
407
+ overflow-x: hidden !important;
408
+ }