prithivMLmods commited on
Commit
ab90afa
·
verified ·
1 Parent(s): bce5199

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +346 -230
app.py CHANGED
@@ -71,354 +71,466 @@ def process_image(image, task):
71
  return output_text.strip()
72
 
73
  css = """
74
- @import url('https://fonts.googleapis.com/css2?family=Outfit:wght@400;600;900&family=IBM+Plex+Mono:wght@400;500&display=swap');
75
 
76
  :root {
77
- --input-focus: #2d8cf0;
78
- --font-color: #1a1a1a;
79
- --font-color-sub: #4a4a4a;
80
- --bg-color: #f5f5dc;
81
- --main-color: #1a1a1a;
82
- --accent-bg: #b8d4e3;
83
- --card-bg: #f0f0f0;
84
- --gradient-start: #e8f5e9;
85
- --gradient-mid: #e3f2fd;
86
- --gradient-end: #fce4ec;
87
- --button-gradient-start: #ffd54f;
88
- --button-gradient-end: #ffb300;
89
- --output-bg: #fffef5;
90
- }
91
-
92
- @media (prefers-color-scheme: dark) {
93
- :root {
94
- --font-color: #e8e8e8;
95
- --font-color-sub: #b0b0b0;
96
- --bg-color: #2a2a2a;
97
- --main-color: #e8e8e8;
98
- --accent-bg: #3a4a5a;
99
- --card-bg: #1e1e1e;
100
- --gradient-start: #1a2a1a;
101
- --gradient-mid: #1a2a3a;
102
- --gradient-end: #2a1a2a;
103
- --button-gradient-start: #cc9a00;
104
- --button-gradient-end: #b38600;
105
- --output-bg: #2a2a2a;
106
- }
107
  }
108
 
109
  .dark {
110
- --font-color: #e8e8e8;
111
- --font-color-sub: #b0b0b0;
112
- --bg-color: #2a2a2a;
113
- --main-color: #e8e8e8;
114
- --accent-bg: #3a4a5a;
115
- --card-bg: #1e1e1e;
116
- --gradient-start: #1a2a1a;
117
- --gradient-mid: #1a2a3a;
118
- --gradient-end: #2a1a2a;
119
- --button-gradient-start: #cc9a00;
120
- --button-gradient-end: #b38600;
121
- --output-bg: #2a2a2a;
 
 
 
122
  }
123
 
124
  * {
125
- font-family: 'Outfit', Arial, sans-serif !important;
126
  }
127
 
128
- .gradio-container {
129
- background: linear-gradient(135deg, var(--gradient-start), var(--gradient-mid), var(--gradient-end)) !important;
130
  min-height: 100vh;
 
 
131
  }
132
 
133
- .main-wrapper {
134
- max-width: 1000px;
135
- margin: 0 auto;
136
- padding: 30px 20px;
137
  }
138
 
139
- .header-card {
140
- background: var(--accent-bg);
141
- padding: 25px 30px;
142
- border-radius: 8px;
143
- border: 3px solid var(--main-color);
144
- box-shadow: 6px 6px var(--main-color);
145
- margin-bottom: 25px;
146
- text-align: center;
 
147
  }
148
 
149
  .header-title {
150
- font-size: 2.5em;
151
  font-weight: 900;
152
- color: var(--font-color);
153
  margin: 0;
154
  letter-spacing: -1px;
155
  }
156
 
157
  .header-subtitle {
158
- font-size: 1.1em;
159
  font-weight: 600;
160
- color: var(--font-color-sub);
161
- margin-top: 8px;
162
  }
163
 
164
- .content-card {
165
- background: var(--accent-bg);
166
- padding: 25px;
167
- border-radius: 8px;
168
- border: 3px solid var(--main-color);
169
- box-shadow: 6px 6px var(--main-color);
 
 
170
  }
171
 
172
- .section-label {
173
- font-weight: 700;
174
- font-size: 0.95em;
175
- color: var(--font-color);
176
- margin-bottom: 10px;
 
 
 
 
 
 
 
 
177
  text-transform: uppercase;
178
- letter-spacing: 0.5px;
179
  }
180
 
181
- .input-field, .input-field textarea, .input-field input {
182
- border-radius: 6px !important;
183
- border: 2px solid var(--main-color) !important;
184
- background-color: var(--bg-color) !important;
185
- box-shadow: 4px 4px var(--main-color) !important;
186
- font-size: 15px !important;
187
- font-weight: 500 !important;
188
- color: var(--font-color) !important;
189
  }
190
 
191
- .input-field textarea:focus, .input-field input:focus {
192
- border-color: var(--input-focus) !important;
193
- outline: none !important;
 
 
 
 
 
194
  }
195
 
 
196
  .upload-box {
197
- border: 3px dashed var(--main-color) !important;
198
- border-radius: 8px !important;
199
- background-color: var(--bg-color) !important;
200
- box-shadow: 4px 4px var(--main-color) !important;
201
- min-height: 200px !important;
202
  transition: all 0.2s ease;
 
203
  }
204
 
205
  .upload-box:hover {
206
- opacity: 0.9;
207
  }
208
 
209
- .upload-box span, .upload-box p, .upload-box label {
210
- color: var(--font-color) !important;
211
  }
212
 
213
- .dropdown-field {
214
- border-radius: 6px !important;
215
- border: 2px solid var(--main-color) !important;
216
- background-color: var(--bg-color) !important;
217
- box-shadow: 4px 4px var(--main-color) !important;
218
  }
219
 
220
- .task-buttons {
221
- display: flex;
222
- gap: 12px;
223
- flex-wrap: wrap;
224
- }
225
-
226
- .task-buttons label {
227
- color: var(--font-color) !important;
228
  }
229
 
230
- .task-buttons input[type="radio"] + label {
231
- color: var(--font-color) !important;
232
- }
233
-
234
- .task-btn {
235
- flex: 1;
236
- min-width: 100px;
237
- height: 45px;
238
- border-radius: 6px !important;
239
- border: 2px solid var(--main-color) !important;
240
- background-color: var(--bg-color) !important;
241
- box-shadow: 4px 4px var(--main-color) !important;
242
- font-size: 15px !important;
243
- font-weight: 600 !important;
244
- color: var(--font-color) !important;
245
- cursor: pointer;
246
- transition: all 0.1s ease;
247
- }
248
-
249
- .task-btn:hover {
250
- opacity: 0.9;
251
  }
252
 
253
- .task-btn.selected, .task-btn:active {
254
- box-shadow: 0px 0px var(--main-color) !important;
255
- transform: translate(3px, 3px);
256
- background-color: var(--button-gradient-start) !important;
257
  }
258
 
 
259
  .go-button {
260
  width: 100%;
261
  height: 55px;
262
- border-radius: 8px !important;
263
- border: 3px solid var(--main-color) !important;
264
- background: linear-gradient(135deg, var(--button-gradient-start), var(--button-gradient-end)) !important;
265
- box-shadow: 5px 5px var(--main-color) !important;
266
- font-size: 1.2em !important;
267
- font-weight: 700 !important;
268
- color: #1a1a1a !important;
269
  cursor: pointer;
270
  transition: all 0.15s ease;
271
- margin-top: 15px;
 
 
272
  }
273
 
274
  .go-button:hover {
275
- opacity: 0.9;
 
 
276
  }
277
 
278
  .go-button:active {
279
- box-shadow: 0px 0px var(--main-color) !important;
280
- transform: translate(4px, 4px);
281
  }
282
 
 
283
  .output-area {
284
- background-color: var(--output-bg) !important;
285
- border: 2px solid var(--main-color) !important;
286
- border-radius: 8px !important;
287
- box-shadow: 4px 4px var(--main-color) !important;
288
  font-family: 'IBM Plex Mono', monospace !important;
289
- min-height: 300px !important;
290
- padding: 15px !important;
 
291
  }
292
 
293
  .output-area textarea {
294
  font-family: 'IBM Plex Mono', monospace !important;
295
- background-color: transparent !important;
296
  border: none !important;
297
  box-shadow: none !important;
298
- color: var(--font-color) !important;
299
- }
300
-
301
- .example-gallery {
302
- margin-top: 15px;
303
  }
304
 
305
- .example-gallery img {
306
- border: 2px solid var(--main-color) !important;
307
- border-radius: 6px !important;
308
- box-shadow: 3px 3px var(--main-color) !important;
309
- transition: all 0.15s ease;
 
 
 
310
  }
311
 
312
- .example-gallery img:hover {
313
- transform: translate(-2px, -2px);
314
- box-shadow: 5px 5px var(--main-color) !important;
 
 
315
  }
316
 
317
- .md-preview {
318
- background-color: var(--output-bg) !important;
319
- border: 2px solid var(--main-color) !important;
320
- border-radius: 8px !important;
321
- box-shadow: 4px 4px var(--main-color) !important;
322
- padding: 20px !important;
323
- min-height: 300px;
324
- color: var(--font-color) !important;
325
  }
326
 
327
- .md-preview p, .md-preview h1, .md-preview h2, .md-preview h3,
328
- .md-preview h4, .md-preview h5, .md-preview h6, .md-preview li,
329
- .md-preview span, .md-preview code, .md-preview pre {
330
- color: var(--font-color) !important;
331
  }
332
 
333
  .tabs-container button {
334
- border: 2px solid var(--main-color) !important;
335
- background-color: var(--bg-color) !important;
336
- font-weight: 600 !important;
337
- border-radius: 6px 6px 0 0 !important;
338
- margin-right: 5px;
339
- color: var(--font-color) !important;
 
 
 
340
  }
341
 
342
- .tabs-container button.selected {
343
- background-color: var(--button-gradient-start) !important;
344
- box-shadow: none !important;
345
- color: #1a1a1a !important;
346
  }
347
 
348
- .footer-note {
 
 
 
 
 
 
 
 
 
 
 
 
349
  text-align: center;
350
- margin-top: 20px;
351
- padding: 15px;
352
- background: var(--card-bg);
353
- border-radius: 8px;
354
- border: 2px solid var(--main-color);
355
- font-size: 0.9em;
356
- color: var(--font-color-sub);
357
  }
358
 
359
- .footer-note strong {
360
- color: var(--font-color);
 
361
  }
362
 
 
363
  footer {
364
  display: none !important;
365
  }
366
 
 
367
  .gr-box, .gr-form, .gr-panel {
368
  border: none !important;
369
  background: transparent !important;
370
  box-shadow: none !important;
 
371
  }
372
 
373
  label {
374
- font-weight: 700 !important;
375
- font-size: 0.9em !important;
376
- color: var(--font-color) !important;
377
  text-transform: uppercase !important;
378
  letter-spacing: 0.5px !important;
379
  }
380
 
381
- .copy-btn {
382
- border: 2px solid var(--main-color) !important;
383
- background-color: var(--bg-color) !important;
384
- box-shadow: 2px 2px var(--main-color) !important;
385
- border-radius: 4px !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
386
  }
387
 
388
- .copy-btn:active {
389
- box-shadow: 0px 0px var(--main-color) !important;
390
- transform: translate(2px, 2px);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
391
  }
392
 
393
- span, p, div, input, textarea, button, a {
394
- color: var(--font-color);
 
 
 
395
  }
396
 
397
- .gr-input, .gr-text-input, .gr-textarea {
398
- color: var(--font-color) !important;
399
- background-color: var(--bg-color) !important;
400
  }
401
 
402
- .gr-radio label span {
403
- color: var(--font-color) !important;
 
404
  }
405
  """
406
 
407
  with gr.Blocks(title="GLM-OCR") as demo:
408
 
 
409
  gr.HTML("""
410
- <div class="main-wrapper">
411
- <div class="header-card">
412
  <h1 class="header-title">GLM-OCR</h1>
413
  <p class="header-subtitle">Document parsing and text recognition powered by AI</p>
414
  </div>
415
  </div>
416
  """)
417
 
418
- with gr.Row(elem_classes=["main-wrapper"]):
419
- with gr.Column(scale=1, elem_classes=["content-card"]):
420
- gr.HTML('<div class="section-label">Upload Image</div>')
 
 
 
421
 
 
422
  image_input = gr.Image(
423
  type="pil",
424
  label="",
@@ -427,13 +539,12 @@ with gr.Blocks(title="GLM-OCR") as demo:
427
  height=250
428
  )
429
 
430
- gr.HTML('<div class="section-label" style="margin-top: 20px;">Recognition Type</div>')
431
-
432
  task = gr.Radio(
433
  choices=list(TASK_PROMPTS.keys()),
434
  value="Text",
435
  label="",
436
- elem_classes=["task-buttons"]
437
  )
438
 
439
  btn = gr.Button(
@@ -442,8 +553,7 @@ with gr.Blocks(title="GLM-OCR") as demo:
442
  elem_classes=["go-button"]
443
  )
444
 
445
- gr.HTML('<div class="section-label" style="margin-top: 20px;">Examples</div>')
446
-
447
  examples = gr.Examples(
448
  examples=[
449
  "examples/1.jpg",
@@ -453,9 +563,12 @@ with gr.Blocks(title="GLM-OCR") as demo:
453
  inputs=image_input,
454
  label=""
455
  )
 
 
456
 
457
- with gr.Column(scale=1, elem_classes=["content-card"]):
458
- gr.HTML('<div class="section-label">Output</div>')
 
459
 
460
  with gr.Tabs(elem_classes=["tabs-container"]):
461
  with gr.Tab("Text"):
@@ -463,7 +576,7 @@ with gr.Blocks(title="GLM-OCR") as demo:
463
  label="",
464
  lines=18,
465
  elem_classes=["output-area"],
466
- #show_copy_button=True
467
  )
468
 
469
  with gr.Tab("Markdown"):
@@ -471,16 +584,19 @@ with gr.Blocks(title="GLM-OCR") as demo:
471
  value="",
472
  elem_classes=["md-preview"]
473
  )
 
 
474
 
 
475
  gr.HTML("""
476
- <div class="main-wrapper">
477
- <div class="footer-note">
478
- Powered by <strong>zai-org/GLM-OCR</strong> |
479
- Supports text, formula, and table recognition
480
  </div>
481
  </div>
482
  """)
483
 
 
484
  def run_ocr(image, task):
485
  result = process_image(image, task)
486
  return result, result
 
71
  return output_text.strip()
72
 
73
  css = """
74
+ @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600;700;900&family=IBM+Plex+Mono:wght@400;500;600&display=swap');
75
 
76
  :root {
77
+ --bg-main: #ffd6e7;
78
+ --bg-card: #ff66a3;
79
+ --bg-header: #ffffff;
80
+ --bg-result: #ffffff;
81
+ --bg-dropdown-active: #ff66a3;
82
+ --bg-advanced: rgba(255, 255, 255, 0.3);
83
+ --bg-uploader: rgba(255, 255, 255, 0.4);
84
+ --bg-button-primary: #4ade80;
85
+ --bg-button-primary-hover: #1ac2ff;
86
+ --bg-button-secondary: #fde047;
87
+ --bg-button-secondary-hover: #f97316;
88
+ --color-border: #000000;
89
+ --color-text: #000000;
90
+ --color-text-button: #000000;
91
+ --color-text-muted: #444444;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  }
93
 
94
  .dark {
95
+ --bg-main: #2c132c;
96
+ --bg-card: #592659;
97
+ --bg-header: #1a1a1a;
98
+ --bg-result: #2a2a2a;
99
+ --bg-dropdown-active: #7f397f;
100
+ --bg-advanced: rgba(0, 0, 0, 0.3);
101
+ --bg-uploader: rgba(0, 0, 0, 0.4);
102
+ --bg-button-primary: #22c55e;
103
+ --bg-button-primary-hover: #0ea5e9;
104
+ --bg-button-secondary: #eab308;
105
+ --bg-button-secondary-hover: #ea580c;
106
+ --color-border: #e0e0e0;
107
+ --color-text: #f0f0f0;
108
+ --color-text-button: #000000;
109
+ --color-text-muted: #b0b0b0;
110
  }
111
 
112
  * {
113
+ font-family: 'Montserrat', sans-serif !important;
114
  }
115
 
116
+ body, .gradio-container {
117
+ background: var(--bg-main) !important;
118
  min-height: 100vh;
119
+ margin: 0;
120
+ padding: 0;
121
  }
122
 
123
+ .gradio-container {
124
+ max-width: 100% !important;
 
 
125
  }
126
 
127
+ /* Header Styles */
128
+ .app-header {
129
+ background: var(--bg-header);
130
+ padding: 1.5rem 2rem;
131
+ border-bottom: 3px solid var(--color-border);
132
+ display: flex;
133
+ justify-content: space-between;
134
+ align-items: center;
135
+ margin-bottom: 2rem;
136
  }
137
 
138
  .header-title {
139
+ font-size: 2.2rem;
140
  font-weight: 900;
141
+ color: var(--color-text);
142
  margin: 0;
143
  letter-spacing: -1px;
144
  }
145
 
146
  .header-subtitle {
147
+ font-size: 0.95rem;
148
  font-weight: 600;
149
+ color: var(--color-text-muted);
150
+ margin-top: 0.25rem;
151
  }
152
 
153
+ /* Card Styles */
154
+ .card-container {
155
+ translate: -6px -6px;
156
+ background: var(--bg-card);
157
+ border: 3px solid var(--color-border);
158
+ box-shadow: 12px 12px 0 var(--color-border);
159
+ transition: all 0.2s ease;
160
+ margin-bottom: 1rem;
161
  }
162
 
163
+ .card-container:hover {
164
+ translate: -3px -3px;
165
+ box-shadow: 9px 9px 0 var(--color-border);
166
+ }
167
+
168
+ .card-head {
169
+ font-size: 14px;
170
+ font-weight: 900;
171
+ width: 100%;
172
+ background: var(--bg-header);
173
+ padding: 10px 14px;
174
+ color: var(--color-text);
175
+ border-bottom: 3px solid var(--color-border);
176
  text-transform: uppercase;
177
+ letter-spacing: 1px;
178
  }
179
 
180
+ .card-content {
181
+ padding: 1.5rem;
182
+ font-size: 14px;
183
+ font-weight: 600;
184
+ color: var(--color-text);
 
 
 
185
  }
186
 
187
+ /* Section Labels */
188
+ .section-label {
189
+ font-weight: 900;
190
+ font-size: 13px;
191
+ color: var(--color-text);
192
+ margin-bottom: 8px;
193
+ text-transform: uppercase;
194
+ letter-spacing: 0.5px;
195
  }
196
 
197
+ /* Upload Box */
198
  .upload-box {
199
+ border: 3px dashed var(--color-border) !important;
200
+ background: var(--bg-uploader) !important;
201
+ min-height: 220px !important;
 
 
202
  transition: all 0.2s ease;
203
+ cursor: pointer;
204
  }
205
 
206
  .upload-box:hover {
207
+ background: rgba(255, 255, 255, 0.5) !important;
208
  }
209
 
210
+ .dark .upload-box:hover {
211
+ background: rgba(0, 0, 0, 0.5) !important;
212
  }
213
 
214
+ .upload-box span, .upload-box p, .upload-box label, .upload-box svg {
215
+ color: var(--color-text) !important;
 
 
 
216
  }
217
 
218
+ /* Task Buttons */
219
+ .task-radio {
220
+ background: var(--bg-uploader);
221
+ border: 3px solid var(--color-border);
222
+ padding: 0.75rem;
 
 
 
223
  }
224
 
225
+ .task-radio label {
226
+ font-weight: 700 !important;
227
+ color: var(--color-text) !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
  }
229
 
230
+ .task-radio input[type="radio"]:checked + label {
231
+ background: var(--bg-button-secondary) !important;
232
+ color: var(--color-text-button) !important;
 
233
  }
234
 
235
+ /* Primary Button */
236
  .go-button {
237
  width: 100%;
238
  height: 55px;
239
+ border: 3px solid var(--color-border) !important;
240
+ background: var(--bg-button-primary) !important;
241
+ box-shadow: 6px 6px 0 var(--color-border) !important;
242
+ font-size: 1rem !important;
243
+ font-weight: 900 !important;
244
+ color: var(--color-text-button) !important;
 
245
  cursor: pointer;
246
  transition: all 0.15s ease;
247
+ border-radius: 0 !important;
248
+ text-transform: uppercase;
249
+ letter-spacing: 1px;
250
  }
251
 
252
  .go-button:hover {
253
+ background: var(--bg-button-primary-hover) !important;
254
+ translate: 2px 2px;
255
+ box-shadow: 4px 4px 0 var(--color-border) !important;
256
  }
257
 
258
  .go-button:active {
259
+ translate: 4px 4px;
260
+ box-shadow: 2px 2px 0 var(--color-border) !important;
261
  }
262
 
263
+ /* Output Area */
264
  .output-area {
265
+ background: var(--bg-result) !important;
266
+ border: 3px solid var(--color-border) !important;
267
+ box-shadow: 6px 6px 0 var(--color-border) !important;
 
268
  font-family: 'IBM Plex Mono', monospace !important;
269
+ min-height: 350px !important;
270
+ padding: 1rem !important;
271
+ border-radius: 0 !important;
272
  }
273
 
274
  .output-area textarea {
275
  font-family: 'IBM Plex Mono', monospace !important;
276
+ background: transparent !important;
277
  border: none !important;
278
  box-shadow: none !important;
279
+ color: var(--color-text) !important;
280
+ font-weight: 500 !important;
281
+ font-size: 14px !important;
282
+ line-height: 1.6 !important;
 
283
  }
284
 
285
+ /* Markdown Preview */
286
+ .md-preview {
287
+ background: var(--bg-result) !important;
288
+ border: 3px solid var(--color-border) !important;
289
+ box-shadow: 6px 6px 0 var(--color-border) !important;
290
+ padding: 1.5rem !important;
291
+ min-height: 350px;
292
+ border-radius: 0 !important;
293
  }
294
 
295
+ .md-preview p, .md-preview h1, .md-preview h2, .md-preview h3,
296
+ .md-preview h4, .md-preview h5, .md-preview h6, .md-preview li,
297
+ .md-preview span, .md-preview code, .md-preview pre, .md-preview td,
298
+ .md-preview th, .md-preview table {
299
+ color: var(--color-text) !important;
300
  }
301
 
302
+ .md-preview code {
303
+ background: var(--bg-advanced) !important;
304
+ padding: 2px 6px;
305
+ font-family: 'IBM Plex Mono', monospace !important;
 
 
 
 
306
  }
307
 
308
+ /* Tabs */
309
+ .tabs-container {
310
+ margin-top: 0.5rem;
 
311
  }
312
 
313
  .tabs-container button {
314
+ border: 3px solid var(--color-border) !important;
315
+ background: var(--bg-uploader) !important;
316
+ font-weight: 700 !important;
317
+ border-radius: 0 !important;
318
+ margin-right: 0 !important;
319
+ padding: 10px 20px !important;
320
+ color: var(--color-text) !important;
321
+ box-shadow: 4px 4px 0 var(--color-border) !important;
322
+ transition: all 0.15s ease;
323
  }
324
 
325
+ .tabs-container button:hover {
326
+ background: var(--bg-button-secondary) !important;
327
+ color: var(--color-text-button) !important;
 
328
  }
329
 
330
+ .tabs-container button.selected {
331
+ background: var(--bg-button-secondary) !important;
332
+ color: var(--color-text-button) !important;
333
+ translate: 2px 2px;
334
+ box-shadow: 2px 2px 0 var(--color-border) !important;
335
+ }
336
+
337
+ /* Footer */
338
+ .footer-card {
339
+ background: var(--bg-header);
340
+ border: 3px solid var(--color-border);
341
+ box-shadow: 6px 6px 0 var(--color-border);
342
+ padding: 1rem 1.5rem;
343
  text-align: center;
344
+ font-size: 0.9rem;
345
+ color: var(--color-text-muted);
346
+ font-weight: 600;
347
+ margin-top: 1.5rem;
 
 
 
348
  }
349
 
350
+ .footer-card strong {
351
+ color: var(--color-text);
352
+ font-weight: 900;
353
  }
354
 
355
+ /* Hide default footer */
356
  footer {
357
  display: none !important;
358
  }
359
 
360
+ /* Form elements reset */
361
  .gr-box, .gr-form, .gr-panel {
362
  border: none !important;
363
  background: transparent !important;
364
  box-shadow: none !important;
365
+ border-radius: 0 !important;
366
  }
367
 
368
  label {
369
+ font-weight: 900 !important;
370
+ font-size: 13px !important;
371
+ color: var(--color-text) !important;
372
  text-transform: uppercase !important;
373
  letter-spacing: 0.5px !important;
374
  }
375
 
376
+ /* Copy button */
377
+ button[title="Copy"] {
378
+ border: 2px solid var(--color-border) !important;
379
+ background: var(--bg-button-secondary) !important;
380
+ box-shadow: 3px 3px 0 var(--color-border) !important;
381
+ border-radius: 0 !important;
382
+ transition: all 0.15s ease;
383
+ }
384
+
385
+ button[title="Copy"]:hover {
386
+ translate: 1px 1px;
387
+ box-shadow: 2px 2px 0 var(--color-border) !important;
388
+ }
389
+
390
+ button[title="Copy"]:active {
391
+ translate: 2px 2px;
392
+ box-shadow: 1px 1px 0 var(--color-border) !important;
393
+ }
394
+
395
+ /* Radio buttons styling */
396
+ .gr-radio, .gr-checkbox {
397
+ accent-color: var(--bg-button-primary);
398
+ }
399
+
400
+ /* Dropdown and select */
401
+ select, .gr-dropdown {
402
+ border: 3px solid var(--color-border) !important;
403
+ background: var(--bg-result) !important;
404
+ color: var(--color-text) !important;
405
+ font-weight: 600 !important;
406
+ border-radius: 0 !important;
407
+ padding: 8px 12px !important;
408
+ }
409
+
410
+ /* Input fields */
411
+ input[type="text"], input[type="password"], textarea {
412
+ border: 3px solid var(--color-border) !important;
413
+ background: var(--bg-result) !important;
414
+ color: var(--color-text) !important;
415
+ font-weight: 600 !important;
416
+ border-radius: 0 !important;
417
+ }
418
+
419
+ /* Examples section */
420
+ .examples-section {
421
+ margin-top: 1rem;
422
+ }
423
+
424
+ .examples-section img {
425
+ border: 3px solid var(--color-border) !important;
426
+ box-shadow: 4px 4px 0 var(--color-border) !important;
427
+ transition: all 0.15s ease;
428
+ }
429
+
430
+ .examples-section img:hover {
431
+ translate: -2px -2px;
432
+ box-shadow: 6px 6px 0 var(--color-border) !important;
433
+ }
434
+
435
+ /* Animations */
436
+ @keyframes fadeIn {
437
+ from { opacity: 0; transform: translateY(10px); }
438
+ to { opacity: 1; transform: translateY(0); }
439
+ }
440
+
441
+ .card-container {
442
+ animation: fadeIn 0.3s ease-out;
443
+ }
444
+
445
+ /* Scrollbar styling */
446
+ ::-webkit-scrollbar {
447
+ width: 12px;
448
+ height: 12px;
449
+ }
450
+
451
+ ::-webkit-scrollbar-track {
452
+ background: var(--bg-uploader);
453
+ border: 2px solid var(--color-border);
454
+ }
455
+
456
+ ::-webkit-scrollbar-thumb {
457
+ background: var(--bg-button-secondary);
458
+ border: 2px solid var(--color-border);
459
+ }
460
+
461
+ ::-webkit-scrollbar-thumb:hover {
462
+ background: var(--bg-button-secondary-hover);
463
  }
464
 
465
+ /* Loading state */
466
+ .generating {
467
+ animation: pulse 1.5s infinite;
468
+ }
469
+
470
+ @keyframes pulse {
471
+ 0%, 100% { opacity: 1; }
472
+ 50% { opacity: 0.6; }
473
+ }
474
+
475
+ /* Responsive adjustments */
476
+ @media (max-width: 768px) {
477
+ .header-title {
478
+ font-size: 1.6rem;
479
+ }
480
+
481
+ .header-subtitle {
482
+ font-size: 0.85rem;
483
+ }
484
+
485
+ .card-container {
486
+ translate: -4px -4px;
487
+ box-shadow: 8px 8px 0 var(--color-border);
488
+ }
489
+
490
+ .go-button {
491
+ height: 50px;
492
+ font-size: 0.9rem !important;
493
+ }
494
  }
495
 
496
+ /* Main content wrapper */
497
+ .main-content {
498
+ padding: 0 2rem 2rem 2rem;
499
+ max-width: 1200px;
500
+ margin: 0 auto;
501
  }
502
 
503
+ /* Row styling */
504
+ .main-row {
505
+ gap: 2rem;
506
  }
507
 
508
+ /* Column styling */
509
+ .input-column, .output-column {
510
+ min-width: 0;
511
  }
512
  """
513
 
514
  with gr.Blocks(title="GLM-OCR") as demo:
515
 
516
+ # Header
517
  gr.HTML("""
518
+ <div class="app-header">
519
+ <div>
520
  <h1 class="header-title">GLM-OCR</h1>
521
  <p class="header-subtitle">Document parsing and text recognition powered by AI</p>
522
  </div>
523
  </div>
524
  """)
525
 
526
+ # Main Content
527
+ with gr.Row(elem_classes=["main-content", "main-row"]):
528
+
529
+ # Input Column
530
+ with gr.Column(scale=1, elem_classes=["input-column"]):
531
+ gr.HTML('<div class="card-container"><div class="card-head">Input</div><div class="card-content">')
532
 
533
+ gr.HTML('<div class="section-label">Upload Image</div>')
534
  image_input = gr.Image(
535
  type="pil",
536
  label="",
 
539
  height=250
540
  )
541
 
542
+ gr.HTML('<div class="section-label" style="margin-top: 1.25rem;">Recognition Type</div>')
 
543
  task = gr.Radio(
544
  choices=list(TASK_PROMPTS.keys()),
545
  value="Text",
546
  label="",
547
+ elem_classes=["task-radio"]
548
  )
549
 
550
  btn = gr.Button(
 
553
  elem_classes=["go-button"]
554
  )
555
 
556
+ gr.HTML('<div class="section-label" style="margin-top: 1.25rem;">Examples</div>')
 
557
  examples = gr.Examples(
558
  examples=[
559
  "examples/1.jpg",
 
563
  inputs=image_input,
564
  label=""
565
  )
566
+
567
+ gr.HTML('</div></div>')
568
 
569
+ # Output Column
570
+ with gr.Column(scale=1, elem_classes=["output-column"]):
571
+ gr.HTML('<div class="card-container"><div class="card-head">Result</div><div class="card-content">')
572
 
573
  with gr.Tabs(elem_classes=["tabs-container"]):
574
  with gr.Tab("Text"):
 
576
  label="",
577
  lines=18,
578
  elem_classes=["output-area"],
579
+ # show_copy_button=True
580
  )
581
 
582
  with gr.Tab("Markdown"):
 
584
  value="",
585
  elem_classes=["md-preview"]
586
  )
587
+
588
+ gr.HTML('</div></div>')
589
 
590
+ # Footer
591
  gr.HTML("""
592
+ <div class="main-content">
593
+ <div class="footer-card">
594
+ Powered by <strong>zai-org/GLM-OCR</strong> | Supports text, formula, and table recognition
 
595
  </div>
596
  </div>
597
  """)
598
 
599
+ # Event handlers
600
  def run_ocr(image, task):
601
  result = process_image(image, task)
602
  return result, result