Daizzyy commited on
Commit
df4f89b
·
verified ·
1 Parent(s): 264ec81

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +125 -174
app.py CHANGED
@@ -1,53 +1,101 @@
1
-
2
-
3
- # gradio_app.py
4
-
5
  import gradio as gr
6
  from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline
7
- # ---------------- Load Model ----------------
 
 
8
  def load_model():
 
9
  model_path = "."
10
- tokenizer = AutoTokenizer.from_pretrained(model_path)
11
- model = AutoModelForSequenceClassification.from_pretrained(model_path)
12
- return pipeline(
13
- "text-classification",
14
- model=model,
15
- tokenizer=tokenizer,
16
- return_all_scores=True
17
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  classifier = load_model()
19
- # ---------------- Prediction Logic ----------------
 
 
 
 
20
  def predict(text):
 
21
  if not text.strip():
22
  return "<div class='warn'>⚠️ Please enter some text.</div>"
23
- results = classifier(text)[0]
24
- best = max(results, key=lambda x: x["score"])
25
- label = best["label"]
26
- score = best["score"]
27
- if label.lower() == "not_cyberbullying":
28
- return f"""
29
- <div class='safe'>
30
- <div class='checkmark'>✅</div>
31
- <div class='safe-text'>Safe Message</div>
32
- <div class='confidence-bar'>
33
- <div class='confidence-fill safe-fill' style='width: {score*100}%'></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  </div>
35
- <span class='confidence-score'>Confidence: {score:.2%}</span>
36
- </div>
37
- """
38
- else:
39
- return f"""
40
- <div class='bully'>
41
- <div class='warning-icon'>⚠️</div>
42
- <div class='bully-text'>Cyberbullying Detected</div>
43
- <div class='label-badge'>{label}</div>
44
- <div class='confidence-bar'>
45
- <div class='confidence-fill bully-fill' style='width: {score*100}%'></div>
 
46
  </div>
47
- <span class='confidence-score'>Confidence: {score:.2%}</span>
48
- </div>
49
- """
50
- # ---------------- UI ----------------
 
 
 
 
 
 
 
 
51
  with gr.Blocks(theme=gr.themes.Soft(), css="""
52
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
53
 
@@ -58,14 +106,11 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
58
  }
59
 
60
  html, body {
61
- background: linear-gradient(-45deg, #ff4b4b, #ff8c00, #4b7fff, #7d00ff);
62
- background-size: 400% 400%;
63
  animation: gradientBG 15s ease infinite;
64
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
65
  min-height: 100vh;
66
- position: fixed;
67
- width: 100%;
68
- height: 100%;
69
  }
70
 
71
  @keyframes gradientBG {
@@ -89,13 +134,12 @@ html, body {
89
  font-size: 52px;
90
  font-weight: 900;
91
  text-align: center;
92
- background: linear-gradient(135deg, #ff4b4b, #ff8c00, #4b7fff, #7d00ff);
93
  -webkit-background-clip: text;
94
  -webkit-text-fill-color: transparent;
95
  background-clip: text;
96
  animation: slideInDown 1s ease-out, glow 3s ease-in-out infinite;
97
  margin-bottom: 10px;
98
- text-shadow: 0 0 30px rgba(255, 75, 75, 0.5);
99
  }
100
 
101
  @keyframes slideInDown {
@@ -111,10 +155,10 @@ html, body {
111
 
112
  @keyframes glow {
113
  0%, 100% {
114
- text-shadow: 0 0 20px rgba(255, 75, 75, 0.5), 0 0 40px rgba(255, 140, 0, 0.3);
115
  }
116
  50% {
117
- text-shadow: 0 0 30px rgba(75, 127, 255, 0.6), 0 0 60px rgba(125, 0, 255, 0.4);
118
  }
119
  }
120
 
@@ -139,22 +183,6 @@ html, body {
139
  }
140
  }
141
 
142
- /* Input Container */
143
- .textbox-container {
144
- animation: scaleIn 0.7s ease-out 0.3s both;
145
- }
146
-
147
- @keyframes scaleIn {
148
- from {
149
- opacity: 0;
150
- transform: scale(0.9) rotateX(10deg);
151
- }
152
- to {
153
- opacity: 1;
154
- transform: scale(1) rotateX(0deg);
155
- }
156
- }
157
-
158
  textarea {
159
  background: rgba(255, 255, 255, 0.08) !important;
160
  border: 2px solid rgba(75, 127, 255, 0.3) !important;
@@ -172,24 +200,13 @@ textarea::placeholder {
172
  }
173
 
174
  textarea:focus {
175
- border-color: #4b7fff !important;
176
- box-shadow: 0 15px 50px rgba(75, 127, 255, 0.4), inset 0 0 30px rgba(75, 127, 255, 0.1) !important;
177
  transform: translateY(-5px) scale(1.02);
178
- animation: inputGlow 2s ease-in-out infinite;
179
  }
180
 
181
- @keyframes inputGlow {
182
- 0%, 100% {
183
- box-shadow: 0 15px 50px rgba(75, 127, 255, 0.4), inset 0 0 30px rgba(75, 127, 255, 0.1);
184
- }
185
- 50% {
186
- box-shadow: 0 20px 60px rgba(125, 0, 255, 0.5), inset 0 0 40px rgba(125, 0, 255, 0.2);
187
- }
188
- }
189
-
190
- /* Button Styling with Ripple Effect */
191
  .btn-primary {
192
- background: linear-gradient(135deg, #4b7fff, #7d00ff, #ff4b4b) !important;
193
  background-size: 300% 300% !important;
194
  border: 2px solid rgba(75, 127, 255, 0.5) !important;
195
  color: white !important;
@@ -199,7 +216,7 @@ textarea:focus {
199
  border-radius: 50px !important;
200
  cursor: pointer !important;
201
  transition: all 0.4s ease !important;
202
- box-shadow: 0 10px 40px rgba(75, 127, 255, 0.4), inset 0 0 20px rgba(255, 255, 255, 0.1) !important;
203
  animation: bounceIn 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55) 0.4s both;
204
  position: relative;
205
  overflow: hidden;
@@ -221,41 +238,14 @@ textarea:focus {
221
 
222
  .btn-primary:hover {
223
  transform: translateY(-5px) scale(1.05);
224
- box-shadow: 0 20px 60px rgba(125, 0, 255, 0.6), inset 0 0 30px rgba(255, 255, 255, 0.15) !important;
225
  background-position: 100% 0 !important;
226
- animation: gradientShift 3s ease infinite;
227
- }
228
-
229
- @keyframes gradientShift {
230
- 0% {background-position: 0% 50%;}
231
- 50% {background-position: 100% 50%;}
232
- 100% {background-position: 0% 50%;}
233
  }
234
 
235
  .btn-primary:active {
236
  transform: translateY(-2px) scale(0.98);
237
  }
238
 
239
- /* Ripple Effect */
240
- .btn-primary::before {
241
- content: '';
242
- position: absolute;
243
- top: 50%;
244
- left: 50%;
245
- width: 0;
246
- height: 0;
247
- border-radius: 50%;
248
- background: rgba(255, 255, 255, 0.6);
249
- transform: translate(-50%, -50%);
250
- transition: width 0.6s, height 0.6s;
251
- }
252
-
253
- .btn-primary:active::before {
254
- width: 400px;
255
- height: 400px;
256
- }
257
-
258
- /* Result Cards */
259
  .safe {
260
  background: linear-gradient(135deg, rgba(0, 255, 100, 0.15), rgba(100, 255, 150, 0.08));
261
  border: 2px solid rgba(0, 255, 100, 0.4);
@@ -264,7 +254,7 @@ textarea:focus {
264
  color: #00ff64;
265
  text-align: center;
266
  animation: slideInRight 0.8s cubic-bezier(0.34, 1.56, 0.64, 1), cardGlowGreen 3s ease-in-out infinite;
267
- box-shadow: 0 20px 60px rgba(0, 255, 100, 0.25), inset 0 0 30px rgba(0, 255, 100, 0.1);
268
  backdrop-filter: blur(15px);
269
  }
270
 
@@ -276,7 +266,7 @@ textarea:focus {
276
  color: #ff6b6b;
277
  text-align: center;
278
  animation: slideInRight 0.8s cubic-bezier(0.34, 1.56, 0.64, 1), cardGlowRed 2s ease-in-out infinite;
279
- box-shadow: 0 20px 60px rgba(255, 107, 107, 0.25), inset 0 0 30px rgba(255, 107, 107, 0.1);
280
  backdrop-filter: blur(15px);
281
  }
282
 
@@ -293,19 +283,19 @@ textarea:focus {
293
 
294
  @keyframes cardGlowGreen {
295
  0%, 100% {
296
- box-shadow: 0 20px 60px rgba(0, 255, 100, 0.25), inset 0 0 30px rgba(0, 255, 100, 0.1);
297
  }
298
  50% {
299
- box-shadow: 0 30px 80px rgba(0, 255, 100, 0.4), inset 0 0 40px rgba(0, 255, 100, 0.2);
300
  }
301
  }
302
 
303
  @keyframes cardGlowRed {
304
  0%, 100% {
305
- box-shadow: 0 20px 60px rgba(255, 107, 107, 0.25), inset 0 0 30px rgba(255, 107, 107, 0.1);
306
  }
307
  50% {
308
- box-shadow: 0 30px 80px rgba(255, 107, 107, 0.4), inset 0 0 40px rgba(255, 107, 107, 0.2);
309
  }
310
  }
311
 
@@ -314,7 +304,7 @@ textarea:focus {
314
  text-align: center;
315
  font-weight: 700;
316
  font-size: 18px;
317
- animation: shake 0.5s ease-in-out, pulse 1.5s ease-in-out infinite 0.5s;
318
  padding: 20px;
319
  }
320
 
@@ -324,12 +314,6 @@ textarea:focus {
324
  20%, 40%, 60%, 80% {transform: translateX(8px);}
325
  }
326
 
327
- @keyframes pulse {
328
- 0%, 100% {opacity: 1;}
329
- 50% {opacity: 0.6;}
330
- }
331
-
332
- /* Icons */
333
  .checkmark, .warning-icon {
334
  font-size: 56px;
335
  margin-bottom: 15px;
@@ -351,39 +335,11 @@ textarea:focus {
351
  }
352
  }
353
 
354
- .warning-icon {
355
- animation: bounce 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55), pulse-warning 1.5s ease-in-out 0.8s infinite;
356
- }
357
-
358
- @keyframes pulse-warning {
359
- 0%, 100% {
360
- transform: scale(1);
361
- filter: drop-shadow(0 0 5px rgba(255, 107, 107, 0.5));
362
- }
363
- 50% {
364
- transform: scale(1.2);
365
- filter: drop-shadow(0 0 20px rgba(255, 107, 107, 1));
366
- }
367
- }
368
-
369
- /* Text */
370
  .safe-text, .bully-text {
371
  font-size: 28px;
372
  font-weight: 800;
373
  margin-bottom: 15px;
374
  animation: fadeInDown 0.8s ease-out 0.2s both;
375
- letter-spacing: 0.5px;
376
- }
377
-
378
- @keyframes fadeInDown {
379
- from {
380
- opacity: 0;
381
- transform: translateY(-20px);
382
- }
383
- to {
384
- opacity: 1;
385
- transform: translateY(0);
386
- }
387
  }
388
 
389
  .label-badge {
@@ -396,7 +352,6 @@ textarea:focus {
396
  font-size: 14px;
397
  font-weight: 700;
398
  animation: zoomIn 0.7s ease-out 0.3s both;
399
- box-shadow: 0 5px 20px rgba(255, 107, 107, 0.2);
400
  }
401
 
402
  @keyframes zoomIn {
@@ -410,7 +365,17 @@ textarea:focus {
410
  }
411
  }
412
 
413
- /* Confidence Bar */
 
 
 
 
 
 
 
 
 
 
414
  .confidence-bar {
415
  width: 100%;
416
  height: 10px;
@@ -420,7 +385,6 @@ textarea:focus {
420
  overflow: hidden;
421
  animation: fadeIn 0.8s ease-out 0.1s both;
422
  border: 1px solid rgba(255, 255, 255, 0.2);
423
- box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.3);
424
  }
425
 
426
  .confidence-fill {
@@ -437,22 +401,13 @@ textarea:focus {
437
  }
438
 
439
  .safe-fill {
440
- background: linear-gradient(90deg, #00ff64, #00d452, #00ff64);
441
- background-size: 200% 200%;
442
- box-shadow: 0 0 25px rgba(0, 255, 100, 0.8), inset 0 0 10px rgba(255, 255, 255, 0.3);
443
- animation: fillWidth 1.2s ease-out, shimmer 2s ease-in-out infinite;
444
  }
445
 
446
  .bully-fill {
447
- background: linear-gradient(90deg, #ff6b6b, #ff4444, #ff6b6b);
448
- background-size: 200% 200%;
449
- box-shadow: 0 0 25px rgba(255, 107, 107, 0.8), inset 0 0 10px rgba(255, 255, 255, 0.3);
450
- animation: fillWidth 1.2s ease-out, shimmer 2s ease-in-out infinite;
451
- }
452
-
453
- @keyframes shimmer {
454
- 0%, 100% {background-position: 0% 50%;}
455
- 50% {background-position: 100% 50%;}
456
  }
457
 
458
  .confidence-score {
@@ -460,7 +415,6 @@ textarea:focus {
460
  opacity: 0.9;
461
  animation: fadeIn 0.8s ease-out 0.4s both;
462
  font-weight: 600;
463
- letter-spacing: 0.5px;
464
  }
465
 
466
  @keyframes fadeIn {
@@ -472,7 +426,6 @@ textarea:focus {
472
  }
473
  }
474
 
475
- /* Responsive */
476
  @media (max-width: 768px) {
477
  .title {
478
  font-size: 36px;
@@ -481,12 +434,9 @@ textarea:focus {
481
  .safe, .bully {
482
  padding: 25px;
483
  }
484
-
485
- html, body {
486
- background-size: 600% 600%;
487
- }
488
  }
489
  """) as demo:
 
490
  gr.Markdown("<div class='title'>🛡️ Cyberbullying Detection System</div>")
491
  gr.Markdown("<div class='subtitle'>End-to-end NLP system for detecting cyberbullying, including religion-based abuse</div>")
492
 
@@ -494,8 +444,7 @@ textarea:focus {
494
  text_input = gr.Textbox(
495
  lines=4,
496
  placeholder="Enter a message to analyze...",
497
- label="Input Text",
498
- elem_classes="textbox-container"
499
  )
500
  detect_btn = gr.Button("🔍 Detect", variant="primary")
501
 
@@ -507,4 +456,6 @@ textarea:focus {
507
  outputs=output
508
  )
509
 
510
- demo.launch()
 
 
 
 
 
 
 
1
  import gradio as gr
2
  from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline
3
+ import os
4
+
5
+
6
  def load_model():
7
+ """Load model from root directory"""
8
  model_path = "."
9
+
10
+ try:
11
+ print(f"Loading model from root directory...")
12
+ tokenizer = AutoTokenizer.from_pretrained(model_path)
13
+ model = AutoModelForSequenceClassification.from_pretrained(model_path)
14
+ classifier = pipeline(
15
+ "text-classification",
16
+ model=model,
17
+ tokenizer=tokenizer,
18
+ return_all_scores=True
19
+ )
20
+ print(f"✅ Successfully loaded model")
21
+ return classifier
22
+ except Exception as e:
23
+ print(f"❌ Error loading model: {str(e)}")
24
+ classifier = pipeline(
25
+ "text-classification",
26
+ model="bert-base-uncased",
27
+ return_all_scores=True
28
+ )
29
+ return classifier
30
+
31
  classifier = load_model()
32
+
33
+ # ============================================================
34
+ # PREDICTION LOGIC WITH CORRECT LABELS
35
+ # ============================================================
36
+
37
  def predict(text):
38
+ """Predict cyberbullying category"""
39
  if not text.strip():
40
  return "<div class='warn'>⚠️ Please enter some text.</div>"
41
+
42
+ try:
43
+ results = classifier(text)[0]
44
+ best = max(results, key=lambda x: x["score"])
45
+ label = best["label"]
46
+ score = best["score"]
47
+
48
+ print(f"Label: {label}, Score: {score}")
49
+
50
+ # Your model labels
51
+ cyberbullying_types = {
52
+ "age": {"emoji": "👶", "color": "#ff6b6b", "text": "Age-Based Cyberbullying"},
53
+ "gender": {"emoji": "⚥️", "color": "#ff8c42", "text": "Gender-Based Cyberbullying"},
54
+ "ethnicity": {"emoji": "🌍", "color": "#ffa502", "text": "Ethnicity-Based Cyberbullying"},
55
+ "religion": {"emoji": "🙏", "color": "#ff6b9d", "text": "Religion-Based Cyberbullying"},
56
+ "other_cyberbullying": {"emoji": "⚠️", "color": "#ff4757", "text": "Other Cyberbullying Detected"},
57
+ "not_cyberbullying": {"emoji": "✅", "color": "#00ff64", "text": "Safe Message"}
58
+ }
59
+
60
+ # Get the category info
61
+ category = cyberbullying_types.get(label.lower(), cyberbullying_types["not_cyberbullying"])
62
+
63
+ # Safe message
64
+ if label.lower() == "not_cyberbullying":
65
+ return f"""
66
+ <div class='safe'>
67
+ <div class='checkmark'>{category['emoji']}</div>
68
+ <div class='safe-text'>{category['text']}</div>
69
+ <div class='confidence-bar'>
70
+ <div class='confidence-fill safe-fill' style='width: {score*100}%'></div>
71
+ </div>
72
+ <span class='confidence-score'>Confidence: {score:.2%}</span>
73
  </div>
74
+ """
75
+ else:
76
+ # Cyberbullying message
77
+ return f"""
78
+ <div class='bully'>
79
+ <div class='warning-icon'>{category['emoji']}</div>
80
+ <div class='bully-text'>{category['text']}</div>
81
+ <div class='label-badge' style='background: {category["color"]}33; border-color: {category["color"]};'>{label}</div>
82
+ <div class='confidence-bar'>
83
+ <div class='confidence-fill bully-fill' style='width: {score*100}%; background: {category["color"]};'></div>
84
+ </div>
85
+ <span class='confidence-score'>Confidence: {score:.2%}</span>
86
  </div>
87
+ """
88
+
89
+ except Exception as e:
90
+ import traceback
91
+ print(f"ERROR: {str(e)}")
92
+ print(traceback.format_exc())
93
+ return f"<div class='warn'>❌ Error: {str(e)}</div>"
94
+
95
+ # ============================================================
96
+ # GRADIO INTERFACE WITH PURPLE-TO-BLUE GRADIENT
97
+ # ============================================================
98
+
99
  with gr.Blocks(theme=gr.themes.Soft(), css="""
100
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
101
 
 
106
  }
107
 
108
  html, body {
109
+ background: linear-gradient(-45deg, #7d00ff, #5500ff, #4b7fff, #0099ff, #00bfff);
110
+ background-size: 500% 500%;
111
  animation: gradientBG 15s ease infinite;
112
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
113
  min-height: 100vh;
 
 
 
114
  }
115
 
116
  @keyframes gradientBG {
 
134
  font-size: 52px;
135
  font-weight: 900;
136
  text-align: center;
137
+ background: linear-gradient(135deg, #7d00ff, #5500ff, #4b7fff, #0099ff);
138
  -webkit-background-clip: text;
139
  -webkit-text-fill-color: transparent;
140
  background-clip: text;
141
  animation: slideInDown 1s ease-out, glow 3s ease-in-out infinite;
142
  margin-bottom: 10px;
 
143
  }
144
 
145
  @keyframes slideInDown {
 
155
 
156
  @keyframes glow {
157
  0%, 100% {
158
+ text-shadow: 0 0 20px rgba(125, 0, 255, 0.5), 0 0 40px rgba(75, 127, 255, 0.3);
159
  }
160
  50% {
161
+ text-shadow: 0 0 30px rgba(75, 127, 255, 0.6), 0 0 60px rgba(0, 153, 255, 0.4);
162
  }
163
  }
164
 
 
183
  }
184
  }
185
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
  textarea {
187
  background: rgba(255, 255, 255, 0.08) !important;
188
  border: 2px solid rgba(75, 127, 255, 0.3) !important;
 
200
  }
201
 
202
  textarea:focus {
203
+ border-color: #0099ff !important;
204
+ box-shadow: 0 15px 50px rgba(0, 153, 255, 0.4), inset 0 0 30px rgba(0, 153, 255, 0.1) !important;
205
  transform: translateY(-5px) scale(1.02);
 
206
  }
207
 
 
 
 
 
 
 
 
 
 
 
208
  .btn-primary {
209
+ background: linear-gradient(135deg, #7d00ff, #5500ff, #4b7fff, #0099ff) !important;
210
  background-size: 300% 300% !important;
211
  border: 2px solid rgba(75, 127, 255, 0.5) !important;
212
  color: white !important;
 
216
  border-radius: 50px !important;
217
  cursor: pointer !important;
218
  transition: all 0.4s ease !important;
219
+ box-shadow: 0 10px 40px rgba(75, 127, 255, 0.4) !important;
220
  animation: bounceIn 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55) 0.4s both;
221
  position: relative;
222
  overflow: hidden;
 
238
 
239
  .btn-primary:hover {
240
  transform: translateY(-5px) scale(1.05);
241
+ box-shadow: 0 20px 60px rgba(0, 153, 255, 0.6) !important;
242
  background-position: 100% 0 !important;
 
 
 
 
 
 
 
243
  }
244
 
245
  .btn-primary:active {
246
  transform: translateY(-2px) scale(0.98);
247
  }
248
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249
  .safe {
250
  background: linear-gradient(135deg, rgba(0, 255, 100, 0.15), rgba(100, 255, 150, 0.08));
251
  border: 2px solid rgba(0, 255, 100, 0.4);
 
254
  color: #00ff64;
255
  text-align: center;
256
  animation: slideInRight 0.8s cubic-bezier(0.34, 1.56, 0.64, 1), cardGlowGreen 3s ease-in-out infinite;
257
+ box-shadow: 0 20px 60px rgba(0, 255, 100, 0.25);
258
  backdrop-filter: blur(15px);
259
  }
260
 
 
266
  color: #ff6b6b;
267
  text-align: center;
268
  animation: slideInRight 0.8s cubic-bezier(0.34, 1.56, 0.64, 1), cardGlowRed 2s ease-in-out infinite;
269
+ box-shadow: 0 20px 60px rgba(255, 107, 107, 0.25);
270
  backdrop-filter: blur(15px);
271
  }
272
 
 
283
 
284
  @keyframes cardGlowGreen {
285
  0%, 100% {
286
+ box-shadow: 0 20px 60px rgba(0, 255, 100, 0.25);
287
  }
288
  50% {
289
+ box-shadow: 0 30px 80px rgba(0, 255, 100, 0.4);
290
  }
291
  }
292
 
293
  @keyframes cardGlowRed {
294
  0%, 100% {
295
+ box-shadow: 0 20px 60px rgba(255, 107, 107, 0.25);
296
  }
297
  50% {
298
+ box-shadow: 0 30px 80px rgba(255, 107, 107, 0.4);
299
  }
300
  }
301
 
 
304
  text-align: center;
305
  font-weight: 700;
306
  font-size: 18px;
307
+ animation: shake 0.5s ease-in-out;
308
  padding: 20px;
309
  }
310
 
 
314
  20%, 40%, 60%, 80% {transform: translateX(8px);}
315
  }
316
 
 
 
 
 
 
 
317
  .checkmark, .warning-icon {
318
  font-size: 56px;
319
  margin-bottom: 15px;
 
335
  }
336
  }
337
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
  .safe-text, .bully-text {
339
  font-size: 28px;
340
  font-weight: 800;
341
  margin-bottom: 15px;
342
  animation: fadeInDown 0.8s ease-out 0.2s both;
 
 
 
 
 
 
 
 
 
 
 
 
343
  }
344
 
345
  .label-badge {
 
352
  font-size: 14px;
353
  font-weight: 700;
354
  animation: zoomIn 0.7s ease-out 0.3s both;
 
355
  }
356
 
357
  @keyframes zoomIn {
 
365
  }
366
  }
367
 
368
+ @keyframes fadeInDown {
369
+ from {
370
+ opacity: 0;
371
+ transform: translateY(-20px);
372
+ }
373
+ to {
374
+ opacity: 1;
375
+ transform: translateY(0);
376
+ }
377
+ }
378
+
379
  .confidence-bar {
380
  width: 100%;
381
  height: 10px;
 
385
  overflow: hidden;
386
  animation: fadeIn 0.8s ease-out 0.1s both;
387
  border: 1px solid rgba(255, 255, 255, 0.2);
 
388
  }
389
 
390
  .confidence-fill {
 
401
  }
402
 
403
  .safe-fill {
404
+ background: linear-gradient(90deg, #00ff64, #00d452);
405
+ box-shadow: 0 0 25px rgba(0, 255, 100, 0.8);
 
 
406
  }
407
 
408
  .bully-fill {
409
+ background: linear-gradient(90deg, #ff6b6b, #ff4444);
410
+ box-shadow: 0 0 25px rgba(255, 107, 107, 0.8);
 
 
 
 
 
 
 
411
  }
412
 
413
  .confidence-score {
 
415
  opacity: 0.9;
416
  animation: fadeIn 0.8s ease-out 0.4s both;
417
  font-weight: 600;
 
418
  }
419
 
420
  @keyframes fadeIn {
 
426
  }
427
  }
428
 
 
429
  @media (max-width: 768px) {
430
  .title {
431
  font-size: 36px;
 
434
  .safe, .bully {
435
  padding: 25px;
436
  }
 
 
 
 
437
  }
438
  """) as demo:
439
+
440
  gr.Markdown("<div class='title'>🛡️ Cyberbullying Detection System</div>")
441
  gr.Markdown("<div class='subtitle'>End-to-end NLP system for detecting cyberbullying, including religion-based abuse</div>")
442
 
 
444
  text_input = gr.Textbox(
445
  lines=4,
446
  placeholder="Enter a message to analyze...",
447
+ label="Input Text"
 
448
  )
449
  detect_btn = gr.Button("🔍 Detect", variant="primary")
450
 
 
456
  outputs=output
457
  )
458
 
459
+ # Launch the app
460
+ if __name__ == "__main__":
461
+ demo.launch()