seawolf2357 commited on
Commit
7993a52
Β·
verified Β·
1 Parent(s): 533627f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +661 -200
app.py CHANGED
@@ -30,158 +30,583 @@ def generate_static_badge(label, message, color, label_color, logo, logo_color,
30
  html_code = f'<img src="{badge_url}" alt="badge">'
31
 
32
  badge_preview = f"""
33
- <div style='padding:30px; background: linear-gradient(135deg, #f8f9fa, #e9ecef);
34
- border-radius: 16px; display: flex; justify-content: center;
35
- box-shadow: 0 6px 12px rgba(0,0,0,0.05);'>
 
36
  {html_code}
37
  </div>
38
  """
39
- return html_code, badge_preview
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
  # ---------------------------
42
  # Gradio UI
43
  # ---------------------------
44
- with gr.Blocks(theme=gr.themes.Soft()) as demo:
45
- # Product Hunt badge (prominent but non‑intrusive)
46
- gr.HTML(
47
- """
48
- <div style='display:flex; justify-content:center; margin-top:8px; margin-bottom:18px;'>
49
- <a href="https://www.producthunt.com/posts/badgecraft?embed=true&utm_source=badge-featured&utm_medium=badge&utm_souce=badge-badgecraft" target="_blank">
50
- <img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=955939&theme=light&t=1745314452274" alt="BadgeCraft - badge&#0044;&#0032;ai&#0044;&#0032;generation&#0044;&#0032;web&#0044;&#0032;html&#0044;&#0032;link | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a>
51
-
52
  </a>
53
  </div>
 
 
 
 
54
  """
 
 
 
55
  )
56
-
57
- # Custom CSS
58
- gr.HTML("""
59
- <style>
60
- body {
61
- background: linear-gradient(120deg, #f8f9fa, #e2eafc);
62
- font-family: 'Poppins', 'Noto Sans KR', sans-serif;
63
- }
64
- .gradio-container {
65
- background: rgba(255, 255, 255, 0.85);
66
- backdrop-filter: blur(10px);
67
- border-radius: 20px;
68
- padding: 24px;
69
- box-shadow: 0 10px 30px rgba(0,0,0,0.08);
70
- max-width: 1000px;
71
- margin: 0 auto;
72
- }
73
- .gr-button {
74
- background: linear-gradient(135deg, #a8dadc, #88c1e9) !important;
75
- color: #1d3557 !important;
76
- border: none !important;
77
- border-radius: 10px !important;
78
- font-weight: 600 !important;
79
- transition: all 0.3s ease !important;
80
- box-shadow: 0 4px 10px rgba(138, 198, 209, 0.3) !important;
81
- }
82
- .gr-button:hover {
83
- transform: translateY(-2px) !important;
84
- box-shadow: 0 6px 15px rgba(138, 198, 209, 0.4) !important;
85
- }
86
- .gr-textbox, .gr-select, .gr-color {
87
- background: #e8f6f3 !important;
88
- border: 2px solid #d9f0ea !important;
89
- border-radius: 12px !important;
90
- transition: all 0.3s ease !important;
91
- }
92
- .gr-textbox:focus, .gr-select:focus, .gr-color:focus {
93
- border-color: #a8dadc !important;
94
- box-shadow: 0 0 0 3px rgba(168, 218, 220, 0.25) !important;
95
- }
96
- label.block span {
97
- color: #457b9d !important;
98
- font-weight: 600 !important;
99
- font-size: 1rem !important;
100
- }
101
- h1 {
102
- color: #5e60ce;
103
- font-weight: 800;
104
- letter-spacing: -0.5px;
105
- }
106
- h3 {
107
- color: #5e60ce;
108
- font-weight: 600;
109
- }
110
- .footer {
111
- margin-top: 30px;
112
- text-align: center;
113
- font-size: 0.9rem;
114
- color: #6d6875;
115
- }
116
- .badge-section {
117
- background: rgba(255, 255, 255, 0.7);
118
- border-radius: 16px;
119
- padding: 20px;
120
- box-shadow: 0 4px 12px rgba(0,0,0,0.03);
121
- margin-bottom: 24px;
122
- border: 1px solid rgba(230, 240, 255, 0.7);
123
- }
124
- .example-grid {
125
- display: grid;
126
- grid-template-columns: repeat(4, 1fr);
127
- grid-template-rows: repeat(2, auto);
128
- gap: 16px;
129
- margin-top: 20px;
130
- }
131
- .example-item {
132
- background: linear-gradient(135deg, #f1f8ff, #e8f4ff);
133
- border-radius: 12px;
134
- padding: 16px;
135
- text-align: center;
136
- cursor: pointer;
137
- transition: all 0.3s ease;
138
- border: 2px solid transparent;
139
- }
140
- .example-item:hover {
141
- transform: translateY(-3px);
142
- box-shadow: 0 8px 15px rgba(0,0,0,0.05);
143
- border-color: #a8dadc;
144
- }
145
- @media (max-width: 768px) {
146
- .example-grid {
147
- grid-template-columns: repeat(2, 1fr);
148
- }
149
- }
150
- @media (max-width: 600px) {
151
- .example-grid {
152
- grid-template-columns: 1fr;
153
- }
154
- }
155
- .color-preview {
156
- display: inline-block;
157
- width: 20px;
158
- height: 20px;
159
- margin-right: 5px;
160
- border-radius: 4px;
161
- vertical-align: middle;
162
- }
163
- </style>
164
- """)
165
-
166
- # Header section
167
- gr.HTML("""
168
- <div style="text-align:center; margin-bottom:24px;">
169
- <h1 style="font-size:2.8rem; margin-bottom:0.2em; background: linear-gradient(90deg, #5e60ce, #64dfdf); -webkit-background-clip: text; -webkit-text-fill-color: transparent;">
170
- 🎨 BadgeCraft
171
- </h1>
172
- <p style="font-size:1.2rem; margin:0.5em 0; color:#457b9d; max-width:700px; margin:0 auto;">
173
- Create beautiful badges with live preview and HTML snippet
174
- </p>
175
- <div style="margin-top:10px; display:flex; justify-content:center; gap:12px; flex-wrap:wrap;">
176
- <span style="display:inline-block; background:#e9f5db; color:#588157; padding:6px 12px; border-radius:30px; font-size:0.9rem;">
177
- <strong>✨ MIT License</strong>
178
- </span>
179
- <span style="display:inline-block; background:#d8f3dc; color:#2d6a4f; padding:6px 12px; border-radius:30px; font-size:0.9rem;">
180
- <strong>πŸ‘₯ Created by OpenFreeAI Team</strong>
181
- </span>
182
  </div>
183
- </div>
184
- """)
185
 
186
  # Define color options
187
  color_options = {
@@ -202,50 +627,81 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
202
  }
203
 
204
  with gr.Tabs():
205
- with gr.TabItem("Badge Generator"):
206
- with gr.Row():
207
- with gr.Column():
208
  with gr.Group(elem_classes="badge-section"):
209
- gr.HTML("<h3 style='margin-top:0; margin-bottom:16px; font-size:1.3rem;'>✏️ Badge Settings</h3>")
210
- label = gr.Textbox(label="Label", value="Discord", elem_id="label-input", lines=1)
211
- message = gr.Textbox(label="Message", value="Join our community", elem_id="message-input", lines=1)
212
- logo = gr.Textbox(label="Logo", value="discord", elem_id="logo-input", lines=1)
 
 
 
 
 
 
 
 
 
 
 
 
213
  style = gr.Dropdown(
214
- label="Style",
215
  choices=["flat", "flat-square", "plastic", "for-the-badge", "social"],
216
- value="for-the-badge",
217
- elem_id="style-input"
218
  )
219
 
220
- # Dropdown color selections
221
  color = gr.Dropdown(
222
- label="Background Color",
223
  choices=list(color_options.keys()),
224
- value="Blue",
225
- elem_id="color-input"
226
  )
227
  label_color = gr.Dropdown(
228
- label="Label Background Color",
229
  choices=list(color_options.keys()),
230
- value="Purple",
231
- elem_id="label-color-input"
232
  )
233
  logo_color = gr.Dropdown(
234
- label="Logo Color",
235
  choices=["white", "black"] + list(color_options.keys()),
236
- value="white",
237
- elem_id="logo-color-input"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
  )
239
- link = gr.Textbox(label="Link (URL)", value="https://discord.gg/openfreeai", elem_id="link-input", lines=1)
240
- with gr.Column():
241
  with gr.Group(elem_classes="badge-section"):
242
- gr.HTML("<h3 style='margin-top:0; margin-bottom:16px; font-size:1.3rem;'>πŸ‘οΈ Preview</h3>")
243
  out_preview = gr.HTML(label="")
 
244
  with gr.Group(elem_classes="badge-section"):
245
- gr.HTML("<h3 style='margin-top:0; margin-bottom:16px; font-size:1.3rem;'>πŸ’» HTML Code</h3>")
246
  out_code = gr.Code(label="", language="html", lines=3)
 
 
 
 
 
 
 
 
247
 
248
- # Example list (label, message, bg_color, label_color, logo, logo_color, style, link)
249
  examples = [
250
  ["Discord", "Openfree AI", "Blue", "Purple", "discord", "white", "for-the-badge", "https://discord.gg/openfreeai"],
251
  ["X.com", "Follow us", "Blue", "Cyan", "x", "white", "for-the-badge", "https://x.com/openfree_ai"],
@@ -258,6 +714,14 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
258
  ]
259
 
260
  # Example grid preview
 
 
 
 
 
 
 
 
261
  html_items = '<div class="example-grid">'
262
  for idx, ex in enumerate(examples):
263
  color_hex = color_options.get(ex[2], ex[2])
@@ -277,7 +741,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
277
  html_items += f'''
278
  <div class="example-item" onclick="applyExample({idx})">
279
  <img src="{badge_url}" alt="{ex[0]} badge" style="margin-bottom:8px;">
280
- <div style="font-size:0.9rem; color:#457b9d;">{ex[0]}</div>
281
  </div>
282
  '''
283
  html_items += '</div>'
@@ -330,47 +794,34 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
330
 
331
  gr.HTML(html_items + apply_example_js)
332
 
333
- def process_badge(label, message, color_name, label_color_name, logo, logo_color_name, style, link):
334
- color_hex = color_options.get(color_name, "#000000")
335
- label_color_hex = color_options.get(label_color_name, "#000000")
336
- logo_color_hex = logo_color_name if logo_color_name in ["white", "black"] else color_options.get(logo_color_name, "#ffffff")
337
- return generate_static_badge(label, message, color_hex, label_color_hex, logo, logo_color_hex, style, link)
338
-
339
- demo.load(
340
- fn=process_badge,
341
- inputs=[label, message, color, label_color, logo, logo_color, style, link],
342
- outputs=[out_code, out_preview],
343
- )
344
- for inp in [label, message, color, label_color, logo, logo_color, style, link]:
345
- inp.change(
346
- fn=process_badge,
347
- inputs=[label, message, color, label_color, logo, logo_color, style, link],
348
- outputs=[out_code, out_preview],
349
- )
350
-
351
- with gr.TabItem("Help"):
352
  gr.HTML('''
353
- <div style="padding: 20px; background: rgba(255, 255, 255, 0.7); border-radius: 16px; box-shadow: 0 4px 12px rgba(0,0,0,0.03);">
354
- <h3 style="color: #5e60ce; margin-top:0;">πŸ“‹ How to Use BadgeCraft</h3>
355
- <h4 style="color: #457b9d; margin-bottom: 8px;">✨ What are Badges?</h4>
 
356
  <p>Badges are small visual indicators that can be used in README files, websites, and documentation. Shields.io badges are widely used to display project status, social media links, version information, and more.</p>
357
- <h4 style="color: #457b9d; margin-bottom: 8px;">πŸ› οΈ Basic Settings</h4>
 
358
  <ul>
359
  <li><strong>Label</strong>: Text displayed on the left side of the badge (e.g., "Discord", "Version", "Status")</li>
360
  <li><strong>Message</strong>: Text displayed on the right side of the badge</li>
361
  <li><strong>Logo</strong>: Name of a logo provided by Simple Icons (<a href="https://simpleicons.org/" target="_blank">View List</a>)</li>
362
  <li><strong>Style</strong>: Determines the shape of the badge (flat, plastic, for-the-badge, etc.)</li>
363
  </ul>
364
- <h4 style="color: #457b9d; margin-bottom: 8px;">🎨 Color Settings</h4>
 
365
  <ul>
366
  <li><strong>Background Color</strong>: Background color for the right side of the badge</li>
367
  <li><strong>Label Background Color</strong>: Background color for the left side of the badge</li>
368
  <li><strong>Logo Color</strong>: Color of the logo (e.g. white or black)</li>
369
  </ul>
370
- <h4 style="color: #457b9d; margin-bottom: 8px;">πŸ”— Using the HTML</h4>
 
371
  <p>Copy the generated HTML code and paste it into your website, blog, GitHub README, etc.</p>
372
  <p>HTML works in GitHub READMEs, but if you prefer markdown, use <code>![alt text](badge URL)</code>.</p>
373
- <h4 style="color: #457b9d; margin-bottom: 8px;">πŸ’‘ Tips</h4>
 
374
  <ul>
375
  <li>Click on any example in the grid to automatically fill in all settings</li>
376
  <li>The preview updates in real-time as you make changes</li>
@@ -380,14 +831,24 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
380
  </div>
381
  ''')
382
 
383
- # Footer
384
- gr.HTML('''
385
- <div class="footer">
386
- <p>Β© 2023-2025 BadgeCraft | MIT License
387
- <a href="https://discord.gg/openfreeai" target="_blank" style="color:#5e60ce;">Discord</a>
388
- </p>
389
- </div>
390
- ''')
 
 
 
 
 
 
 
 
 
 
391
 
392
  if __name__ == "__main__":
393
  demo.launch()
 
30
  html_code = f'<img src="{badge_url}" alt="badge">'
31
 
32
  badge_preview = f"""
33
+ <div style='padding:30px; background: #FFFFFF;
34
+ border: 4px solid #1F2937; border-radius: 12px;
35
+ display: flex; justify-content: center;
36
+ box-shadow: 6px 6px 0px #1F2937;'>
37
  {html_code}
38
  </div>
39
  """
40
+
41
+ # 정보 둜그 생성
42
+ info_log = f"""βœ… BADGE GENERATED!
43
+ {'=' * 50}
44
+ 🏷️ Badge Info:
45
+ β€’ Label: {label}
46
+ β€’ Message: {message}
47
+ β€’ Logo: {logo}
48
+ {'=' * 50}
49
+ 🎨 Style Settings:
50
+ β€’ Background: {color}
51
+ β€’ Label Color: {label_color}
52
+ β€’ Logo Color: {logo_color}
53
+ β€’ Style: {style}
54
+ {'=' * 50}
55
+ πŸ”— Link: {link if link else 'None'}
56
+ {'=' * 50}
57
+ πŸ’Ύ HTML code ready to copy!"""
58
+
59
+ return html_code, badge_preview, info_log
60
+
61
+
62
+ # ============================================
63
+ # 🎨 Comic Classic Theme - Toon Playground
64
+ # ============================================
65
+
66
+ css = """
67
+ /* ===== 🎨 Google Fonts Import ===== */
68
+ @import url('https://fonts.googleapis.com/css2?family=Bangers&family=Comic+Neue:wght@400;700&display=swap');
69
+
70
+ /* ===== 🎨 Comic Classic λ°°κ²½ - λΉˆν‹°μ§€ 페이퍼 + λ„νŠΈ νŒ¨ν„΄ ===== */
71
+ .gradio-container {
72
+ background-color: #FEF9C3 !important;
73
+ background-image:
74
+ radial-gradient(#1F2937 1px, transparent 1px) !important;
75
+ background-size: 20px 20px !important;
76
+ min-height: 100vh !important;
77
+ font-family: 'Comic Neue', cursive, sans-serif !important;
78
+ }
79
+
80
+ /* ===== ν—ˆκΉ…νŽ˜μ΄μŠ€ 상단 μš”μ†Œ μˆ¨κΉ€ ===== */
81
+ .huggingface-space-header,
82
+ #space-header,
83
+ .space-header,
84
+ [class*="space-header"],
85
+ .svelte-1ed2p3z,
86
+ .space-header-badge,
87
+ .header-badge,
88
+ [data-testid="space-header"],
89
+ .svelte-kqij2n,
90
+ .svelte-1ax1toq,
91
+ .embed-container > div:first-child {
92
+ display: none !important;
93
+ visibility: hidden !important;
94
+ height: 0 !important;
95
+ width: 0 !important;
96
+ overflow: hidden !important;
97
+ opacity: 0 !important;
98
+ pointer-events: none !important;
99
+ }
100
+
101
+ /* ===== Footer μ™„μ „ μˆ¨κΉ€ ===== */
102
+ footer,
103
+ .footer,
104
+ .gradio-container footer,
105
+ .built-with,
106
+ [class*="footer"],
107
+ .gradio-footer,
108
+ .main-footer,
109
+ div[class*="footer"],
110
+ .show-api,
111
+ .built-with-gradio,
112
+ a[href*="gradio.app"],
113
+ a[href*="huggingface.co/spaces"] {
114
+ display: none !important;
115
+ visibility: hidden !important;
116
+ height: 0 !important;
117
+ padding: 0 !important;
118
+ margin: 0 !important;
119
+ }
120
+
121
+ /* ===== 메인 μ»¨ν…Œμ΄λ„ˆ ===== */
122
+ #col-container {
123
+ max-width: 1200px;
124
+ margin: 0 auto;
125
+ }
126
+
127
+ /* ===== 🎨 헀더 타이틀 - μ½”λ―Ή μŠ€νƒ€μΌ ===== */
128
+ .header-text h1 {
129
+ font-family: 'Bangers', cursive !important;
130
+ color: #1F2937 !important;
131
+ font-size: 3.5rem !important;
132
+ font-weight: 400 !important;
133
+ text-align: center !important;
134
+ margin-bottom: 0.5rem !important;
135
+ text-shadow:
136
+ 4px 4px 0px #FACC15,
137
+ 6px 6px 0px #1F2937 !important;
138
+ letter-spacing: 3px !important;
139
+ -webkit-text-stroke: 2px #1F2937 !important;
140
+ }
141
+
142
+ /* ===== 🎨 μ„œλΈŒνƒ€μ΄ν‹€ ===== */
143
+ .subtitle {
144
+ text-align: center !important;
145
+ font-family: 'Comic Neue', cursive !important;
146
+ font-size: 1.2rem !important;
147
+ color: #1F2937 !important;
148
+ margin-bottom: 1.5rem !important;
149
+ font-weight: 700 !important;
150
+ }
151
+
152
+ /* ===== 🎨 μΉ΄λ“œ/νŒ¨λ„ - λ§Œν™” ν”„λ ˆμž„ μŠ€νƒ€μΌ ===== */
153
+ .gr-panel,
154
+ .gr-box,
155
+ .gr-form,
156
+ .block,
157
+ .gr-group {
158
+ background: #FFFFFF !important;
159
+ border: 3px solid #1F2937 !important;
160
+ border-radius: 8px !important;
161
+ box-shadow: 6px 6px 0px #1F2937 !important;
162
+ transition: all 0.2s ease !important;
163
+ }
164
+
165
+ .gr-panel:hover,
166
+ .block:hover {
167
+ transform: translate(-2px, -2px) !important;
168
+ box-shadow: 8px 8px 0px #1F2937 !important;
169
+ }
170
+
171
+ /* ===== 🎨 μž…λ ₯ ν•„λ“œ (Textbox) ===== */
172
+ textarea,
173
+ input[type="text"],
174
+ input[type="number"] {
175
+ background: #FFFFFF !important;
176
+ border: 3px solid #1F2937 !important;
177
+ border-radius: 8px !important;
178
+ color: #1F2937 !important;
179
+ font-family: 'Comic Neue', cursive !important;
180
+ font-size: 1rem !important;
181
+ font-weight: 700 !important;
182
+ transition: all 0.2s ease !important;
183
+ }
184
+
185
+ textarea:focus,
186
+ input[type="text"]:focus,
187
+ input[type="number"]:focus {
188
+ border-color: #3B82F6 !important;
189
+ box-shadow: 4px 4px 0px #3B82F6 !important;
190
+ outline: none !important;
191
+ }
192
+
193
+ textarea::placeholder {
194
+ color: #9CA3AF !important;
195
+ font-weight: 400 !important;
196
+ }
197
+
198
+ /* ===== 🎨 λ“œλ‘­λ‹€μš΄ μŠ€νƒ€μΌ ===== */
199
+ .gr-dropdown {
200
+ background: #FFFFFF !important;
201
+ border: 3px solid #1F2937 !important;
202
+ border-radius: 8px !important;
203
+ box-shadow: 3px 3px 0px #1F2937 !important;
204
+ }
205
+
206
+ .gr-dropdown > div {
207
+ background: #FFFFFF !important;
208
+ border: none !important;
209
+ }
210
+
211
+ .gr-dropdown input {
212
+ color: #1F2937 !important;
213
+ font-family: 'Comic Neue', cursive !important;
214
+ font-weight: 700 !important;
215
+ }
216
+
217
+ .gr-dropdown ul {
218
+ background: #FFFFFF !important;
219
+ border: 3px solid #1F2937 !important;
220
+ border-radius: 8px !important;
221
+ box-shadow: 4px 4px 0px #1F2937 !important;
222
+ }
223
+
224
+ .gr-dropdown ul li {
225
+ color: #1F2937 !important;
226
+ font-family: 'Comic Neue', cursive !important;
227
+ font-weight: 700 !important;
228
+ padding: 8px 12px !important;
229
+ }
230
+
231
+ .gr-dropdown ul li:hover {
232
+ background: #FACC15 !important;
233
+ color: #1F2937 !important;
234
+ }
235
+
236
+ .gr-dropdown ul li.selected {
237
+ background: #3B82F6 !important;
238
+ color: #FFFFFF !important;
239
+ }
240
+
241
+ /* ===== 🎨 Primary λ²„νŠΌ - μ½”λ―Ή 블루 ===== */
242
+ .gr-button-primary,
243
+ button.primary,
244
+ .gr-button.primary,
245
+ .generate-btn {
246
+ background: #3B82F6 !important;
247
+ border: 3px solid #1F2937 !important;
248
+ border-radius: 8px !important;
249
+ color: #FFFFFF !important;
250
+ font-family: 'Bangers', cursive !important;
251
+ font-weight: 400 !important;
252
+ font-size: 1.3rem !important;
253
+ letter-spacing: 2px !important;
254
+ padding: 14px 28px !important;
255
+ box-shadow: 5px 5px 0px #1F2937 !important;
256
+ transition: all 0.1s ease !important;
257
+ text-shadow: 1px 1px 0px #1F2937 !important;
258
+ }
259
+
260
+ .gr-button-primary:hover,
261
+ button.primary:hover,
262
+ .gr-button.primary:hover,
263
+ .generate-btn:hover {
264
+ background: #2563EB !important;
265
+ transform: translate(-2px, -2px) !important;
266
+ box-shadow: 7px 7px 0px #1F2937 !important;
267
+ }
268
+
269
+ .gr-button-primary:active,
270
+ button.primary:active,
271
+ .gr-button.primary:active,
272
+ .generate-btn:active {
273
+ transform: translate(3px, 3px) !important;
274
+ box-shadow: 2px 2px 0px #1F2937 !important;
275
+ }
276
+
277
+ /* ===== 🎨 Secondary λ²„νŠΌ - μ½”λ―Ή λ ˆλ“œ ===== */
278
+ .gr-button-secondary,
279
+ button.secondary {
280
+ background: #EF4444 !important;
281
+ border: 3px solid #1F2937 !important;
282
+ border-radius: 8px !important;
283
+ color: #FFFFFF !important;
284
+ font-family: 'Bangers', cursive !important;
285
+ font-weight: 400 !important;
286
+ font-size: 1.1rem !important;
287
+ letter-spacing: 1px !important;
288
+ box-shadow: 4px 4px 0px #1F2937 !important;
289
+ transition: all 0.1s ease !important;
290
+ text-shadow: 1px 1px 0px #1F2937 !important;
291
+ }
292
+
293
+ .gr-button-secondary:hover,
294
+ button.secondary:hover {
295
+ background: #DC2626 !important;
296
+ transform: translate(-2px, -2px) !important;
297
+ box-shadow: 6px 6px 0px #1F2937 !important;
298
+ }
299
+
300
+ /* ===== 🎨 둜그 좜λ ₯ μ˜μ—­ ===== */
301
+ .info-log textarea {
302
+ background: #1F2937 !important;
303
+ color: #10B981 !important;
304
+ font-family: 'Courier New', monospace !important;
305
+ font-size: 0.9rem !important;
306
+ font-weight: 400 !important;
307
+ border: 3px solid #10B981 !important;
308
+ border-radius: 8px !important;
309
+ box-shadow: 4px 4px 0px #10B981 !important;
310
+ }
311
+
312
+ /* ===== 🎨 μ½”λ“œ 블둝 μŠ€νƒ€μΌ ===== */
313
+ .gr-code,
314
+ pre,
315
+ code {
316
+ background: #1F2937 !important;
317
+ color: #10B981 !important;
318
+ font-family: 'Courier New', monospace !important;
319
+ border: 3px solid #10B981 !important;
320
+ border-radius: 8px !important;
321
+ box-shadow: 4px 4px 0px #10B981 !important;
322
+ padding: 12px !important;
323
+ }
324
+
325
+ /* ===== 🎨 νƒ­ μŠ€νƒ€μΌ ===== */
326
+ .gr-tabs {
327
+ background: transparent !important;
328
+ }
329
+
330
+ .gr-tab-item {
331
+ background: #FFFFFF !important;
332
+ border: 3px solid #1F2937 !important;
333
+ border-radius: 8px 8px 0 0 !important;
334
+ color: #1F2937 !important;
335
+ font-family: 'Bangers', cursive !important;
336
+ font-size: 1.1rem !important;
337
+ letter-spacing: 1px !important;
338
+ padding: 10px 20px !important;
339
+ margin-right: 4px !important;
340
+ box-shadow: 3px -3px 0px #1F2937 !important;
341
+ transition: all 0.2s ease !important;
342
+ }
343
+
344
+ .gr-tab-item:hover {
345
+ background: #FEF3C7 !important;
346
+ transform: translateY(-2px) !important;
347
+ }
348
+
349
+ .gr-tab-item.selected {
350
+ background: #3B82F6 !important;
351
+ color: #FFFFFF !important;
352
+ box-shadow: 4px -4px 0px #1F2937 !important;
353
+ }
354
+
355
+ /* ===== 🎨 라벨 μŠ€νƒ€μΌ ===== */
356
+ label,
357
+ .gr-input-label,
358
+ .gr-block-label {
359
+ color: #1F2937 !important;
360
+ font-family: 'Comic Neue', cursive !important;
361
+ font-weight: 700 !important;
362
+ font-size: 1rem !important;
363
+ }
364
+
365
+ span.gr-label {
366
+ color: #1F2937 !important;
367
+ }
368
+
369
+ /* ===== 🎨 Example Grid μŠ€νƒ€μΌ ===== */
370
+ .example-grid {
371
+ display: grid;
372
+ grid-template-columns: repeat(4, 1fr);
373
+ grid-template-rows: repeat(2, auto);
374
+ gap: 16px;
375
+ margin-top: 20px;
376
+ }
377
+
378
+ .example-item {
379
+ background: #FFFFFF !important;
380
+ border: 3px solid #1F2937 !important;
381
+ border-radius: 12px !important;
382
+ padding: 16px !important;
383
+ text-align: center !important;
384
+ cursor: pointer !important;
385
+ transition: all 0.2s ease !important;
386
+ box-shadow: 4px 4px 0px #1F2937 !important;
387
+ }
388
+
389
+ .example-item:hover {
390
+ transform: translate(-3px, -3px) !important;
391
+ box-shadow: 7px 7px 0px #1F2937 !important;
392
+ background: #FEF3C7 !important;
393
+ }
394
+
395
+ .example-item:active {
396
+ transform: translate(2px, 2px) !important;
397
+ box-shadow: 2px 2px 0px #1F2937 !important;
398
+ }
399
+
400
+ @media (max-width: 768px) {
401
+ .example-grid {
402
+ grid-template-columns: repeat(2, 1fr);
403
+ }
404
+ }
405
+
406
+ @media (max-width: 600px) {
407
+ .example-grid {
408
+ grid-template-columns: 1fr;
409
+ }
410
+ }
411
+
412
+ /* ===== 🎨 Badge Section μŠ€νƒ€μΌ ===== */
413
+ .badge-section {
414
+ background: #FFFFFF !important;
415
+ border: 3px solid #1F2937 !important;
416
+ border-radius: 12px !important;
417
+ padding: 20px !important;
418
+ box-shadow: 6px 6px 0px #1F2937 !important;
419
+ margin-bottom: 20px !important;
420
+ }
421
+
422
+ .badge-section h3 {
423
+ font-family: 'Bangers', cursive !important;
424
+ color: #1F2937 !important;
425
+ font-size: 1.3rem !important;
426
+ letter-spacing: 1px !important;
427
+ margin-bottom: 16px !important;
428
+ }
429
+
430
+ /* ===== 🎨 Help Section μŠ€νƒ€μΌ ===== */
431
+ .help-section {
432
+ background: #FFFFFF !important;
433
+ border: 3px solid #1F2937 !important;
434
+ border-radius: 12px !important;
435
+ padding: 24px !important;
436
+ box-shadow: 6px 6px 0px #1F2937 !important;
437
+ }
438
+
439
+ .help-section h3 {
440
+ font-family: 'Bangers', cursive !important;
441
+ color: #3B82F6 !important;
442
+ font-size: 1.5rem !important;
443
+ letter-spacing: 1px !important;
444
+ margin-bottom: 16px !important;
445
+ }
446
+
447
+ .help-section h4 {
448
+ font-family: 'Comic Neue', cursive !important;
449
+ color: #1F2937 !important;
450
+ font-weight: 700 !important;
451
+ font-size: 1.1rem !important;
452
+ margin: 16px 0 8px 0 !important;
453
+ }
454
+
455
+ .help-section p,
456
+ .help-section li {
457
+ font-family: 'Comic Neue', cursive !important;
458
+ color: #1F2937 !important;
459
+ font-size: 1rem !important;
460
+ line-height: 1.6 !important;
461
+ }
462
+
463
+ .help-section ul {
464
+ padding-left: 20px !important;
465
+ }
466
+
467
+ .help-section a {
468
+ color: #3B82F6 !important;
469
+ font-weight: 700 !important;
470
+ }
471
+
472
+ .help-section a:hover {
473
+ color: #EF4444 !important;
474
+ }
475
+
476
+ /* ===== 🎨 μŠ€ν¬λ‘€λ°” - μ½”λ―Ή μŠ€νƒ€μΌ ===== */
477
+ ::-webkit-scrollbar {
478
+ width: 12px;
479
+ height: 12px;
480
+ }
481
+
482
+ ::-webkit-scrollbar-track {
483
+ background: #FEF9C3;
484
+ border: 2px solid #1F2937;
485
+ }
486
+
487
+ ::-webkit-scrollbar-thumb {
488
+ background: #3B82F6;
489
+ border: 2px solid #1F2937;
490
+ border-radius: 0px;
491
+ }
492
+
493
+ ::-webkit-scrollbar-thumb:hover {
494
+ background: #EF4444;
495
+ }
496
+
497
+ /* ===== 🎨 선택 ν•˜μ΄λΌμ΄νŠΈ ===== */
498
+ ::selection {
499
+ background: #FACC15;
500
+ color: #1F2937;
501
+ }
502
+
503
+ /* ===== 🎨 링크 μŠ€νƒ€μΌ ===== */
504
+ a {
505
+ color: #3B82F6 !important;
506
+ text-decoration: none !important;
507
+ font-weight: 700 !important;
508
+ }
509
+
510
+ a:hover {
511
+ color: #EF4444 !important;
512
+ }
513
+
514
+ /* ===== 🎨 Row/Column 간격 ===== */
515
+ .gr-row {
516
+ gap: 1.5rem !important;
517
+ }
518
+
519
+ .gr-column {
520
+ gap: 1rem !important;
521
+ }
522
+
523
+ /* ===== 🎨 License/Credit 뱃지 ===== */
524
+ .license-badge {
525
+ display: inline-block;
526
+ background: #10B981 !important;
527
+ color: #FFFFFF !important;
528
+ font-family: 'Comic Neue', cursive !important;
529
+ font-weight: 700 !important;
530
+ padding: 6px 14px !important;
531
+ border: 2px solid #1F2937 !important;
532
+ border-radius: 20px !important;
533
+ box-shadow: 2px 2px 0px #1F2937 !important;
534
+ margin: 4px !important;
535
+ }
536
+
537
+ .credit-badge {
538
+ display: inline-block;
539
+ background: #3B82F6 !important;
540
+ color: #FFFFFF !important;
541
+ font-family: 'Comic Neue', cursive !important;
542
+ font-weight: 700 !important;
543
+ padding: 6px 14px !important;
544
+ border: 2px solid #1F2937 !important;
545
+ border-radius: 20px !important;
546
+ box-shadow: 2px 2px 0px #1F2937 !important;
547
+ margin: 4px !important;
548
+ }
549
+
550
+ /* ===== λ°˜μ‘ν˜• μ‘°μ • ===== */
551
+ @media (max-width: 768px) {
552
+ .header-text h1 {
553
+ font-size: 2.2rem !important;
554
+ text-shadow:
555
+ 3px 3px 0px #FACC15,
556
+ 4px 4px 0px #1F2937 !important;
557
+ }
558
+
559
+ .gr-button-primary,
560
+ button.primary {
561
+ padding: 12px 20px !important;
562
+ font-size: 1.1rem !important;
563
+ }
564
+
565
+ .gr-panel,
566
+ .block {
567
+ box-shadow: 4px 4px 0px #1F2937 !important;
568
+ }
569
+ }
570
+
571
+ /* ===== 🎨 닀크λͺ¨λ“œ λΉ„ν™œμ„±ν™” ===== */
572
+ @media (prefers-color-scheme: dark) {
573
+ .gradio-container {
574
+ background-color: #FEF9C3 !important;
575
+ }
576
+ }
577
+ """
578
 
579
  # ---------------------------
580
  # Gradio UI
581
  # ---------------------------
582
+ with gr.Blocks(fill_height=True, css=css, title="BadgeCraft") as demo:
583
+
584
+ # HOME Badge
585
+ gr.HTML("""
586
+ <div style="text-align: center; margin: 20px 0 10px 0;">
587
+ <a href="https://www.humangen.ai" target="_blank" style="text-decoration: none;">
588
+ <img src="https://img.shields.io/static/v1?label=🏠 HOME&message=HUMANGEN.AI&color=0000ff&labelColor=ffcc00&style=for-the-badge" alt="HOME">
 
589
  </a>
590
  </div>
591
+ """)
592
+
593
+ # Header Title
594
+ gr.Markdown(
595
  """
596
+ # 🎨 BADGECRAFT GENERATOR 🏷️
597
+ """,
598
+ elem_classes="header-text"
599
  )
600
+
601
+ gr.Markdown(
602
+ """
603
+ <p class="subtitle">✨ Create beautiful badges with live preview and HTML snippet! πŸ’»</p>
604
+ <div style="text-align: center; margin: 10px 0;">
605
+ <span class="license-badge">✨ MIT License</span>
606
+ <span class="credit-badge">πŸ‘₯ OpenFreeAI Team</span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
607
  </div>
608
+ """,
609
+ )
610
 
611
  # Define color options
612
  color_options = {
 
627
  }
628
 
629
  with gr.Tabs():
630
+ with gr.TabItem("🎨 Badge Generator"):
631
+ with gr.Row(equal_height=False):
632
+ with gr.Column(scale=1, min_width=400):
633
  with gr.Group(elem_classes="badge-section"):
634
+ gr.HTML("<h3>✏️ BADGE SETTINGS</h3>")
635
+ label = gr.Textbox(
636
+ label="🏷️ Label",
637
+ value="Discord",
638
+ lines=1
639
+ )
640
+ message = gr.Textbox(
641
+ label="πŸ’¬ Message",
642
+ value="Join our community",
643
+ lines=1
644
+ )
645
+ logo = gr.Textbox(
646
+ label="πŸ–ΌοΈ Logo",
647
+ value="discord",
648
+ lines=1
649
+ )
650
  style = gr.Dropdown(
651
+ label="🎭 Style",
652
  choices=["flat", "flat-square", "plastic", "for-the-badge", "social"],
653
+ value="for-the-badge"
 
654
  )
655
 
 
656
  color = gr.Dropdown(
657
+ label="🎨 Background Color",
658
  choices=list(color_options.keys()),
659
+ value="Blue"
 
660
  )
661
  label_color = gr.Dropdown(
662
+ label="🏷️ Label Background Color",
663
  choices=list(color_options.keys()),
664
+ value="Purple"
 
665
  )
666
  logo_color = gr.Dropdown(
667
+ label="✨ Logo Color",
668
  choices=["white", "black"] + list(color_options.keys()),
669
+ value="white"
670
+ )
671
+ link = gr.Textbox(
672
+ label="πŸ”— Link (URL)",
673
+ value="https://discord.gg/openfreeai",
674
+ lines=1
675
+ )
676
+
677
+ with gr.Accordion("πŸ“œ Generation Log", open=True):
678
+ info_log = gr.Textbox(
679
+ label="",
680
+ placeholder="Badge info will appear here...",
681
+ lines=14,
682
+ max_lines=20,
683
+ interactive=False,
684
+ elem_classes="info-log"
685
  )
686
+
687
+ with gr.Column(scale=1, min_width=400):
688
  with gr.Group(elem_classes="badge-section"):
689
+ gr.HTML("<h3>πŸ‘οΈ LIVE PREVIEW</h3>")
690
  out_preview = gr.HTML(label="")
691
+
692
  with gr.Group(elem_classes="badge-section"):
693
+ gr.HTML("<h3>πŸ’» HTML CODE</h3>")
694
  out_code = gr.Code(label="", language="html", lines=3)
695
+
696
+ gr.Markdown(
697
+ """
698
+ <p style="text-align: center; margin-top: 15px; font-weight: 700; color: #1F2937;">
699
+ πŸ’‘ Copy the HTML code and paste it into your website or README!
700
+ </p>
701
+ """
702
+ )
703
 
704
+ # Example list
705
  examples = [
706
  ["Discord", "Openfree AI", "Blue", "Purple", "discord", "white", "for-the-badge", "https://discord.gg/openfreeai"],
707
  ["X.com", "Follow us", "Blue", "Cyan", "x", "white", "for-the-badge", "https://x.com/openfree_ai"],
 
714
  ]
715
 
716
  # Example grid preview
717
+ gr.Markdown(
718
+ """
719
+ <p style="text-align: center; margin: 25px 0 15px 0; font-family: 'Bangers', cursive; font-size: 1.5rem; color: #1F2937;">
720
+ 🌟 CLICK AN EXAMPLE TO USE! 🌟
721
+ </p>
722
+ """
723
+ )
724
+
725
  html_items = '<div class="example-grid">'
726
  for idx, ex in enumerate(examples):
727
  color_hex = color_options.get(ex[2], ex[2])
 
741
  html_items += f'''
742
  <div class="example-item" onclick="applyExample({idx})">
743
  <img src="{badge_url}" alt="{ex[0]} badge" style="margin-bottom:8px;">
744
+ <div style="font-size:0.9rem; color:#1F2937; font-family: 'Comic Neue', cursive; font-weight: 700;">{ex[0]}</div>
745
  </div>
746
  '''
747
  html_items += '</div>'
 
794
 
795
  gr.HTML(html_items + apply_example_js)
796
 
797
+ with gr.TabItem("❓ Help"):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
798
  gr.HTML('''
799
+ <div class="help-section">
800
+ <h3>πŸ“‹ HOW TO USE BADGECRAFT</h3>
801
+
802
+ <h4>✨ What are Badges?</h4>
803
  <p>Badges are small visual indicators that can be used in README files, websites, and documentation. Shields.io badges are widely used to display project status, social media links, version information, and more.</p>
804
+
805
+ <h4>πŸ› οΈ Basic Settings</h4>
806
  <ul>
807
  <li><strong>Label</strong>: Text displayed on the left side of the badge (e.g., "Discord", "Version", "Status")</li>
808
  <li><strong>Message</strong>: Text displayed on the right side of the badge</li>
809
  <li><strong>Logo</strong>: Name of a logo provided by Simple Icons (<a href="https://simpleicons.org/" target="_blank">View List</a>)</li>
810
  <li><strong>Style</strong>: Determines the shape of the badge (flat, plastic, for-the-badge, etc.)</li>
811
  </ul>
812
+
813
+ <h4>🎨 Color Settings</h4>
814
  <ul>
815
  <li><strong>Background Color</strong>: Background color for the right side of the badge</li>
816
  <li><strong>Label Background Color</strong>: Background color for the left side of the badge</li>
817
  <li><strong>Logo Color</strong>: Color of the logo (e.g. white or black)</li>
818
  </ul>
819
+
820
+ <h4>πŸ”— Using the HTML</h4>
821
  <p>Copy the generated HTML code and paste it into your website, blog, GitHub README, etc.</p>
822
  <p>HTML works in GitHub READMEs, but if you prefer markdown, use <code>![alt text](badge URL)</code>.</p>
823
+
824
+ <h4>πŸ’‘ Tips</h4>
825
  <ul>
826
  <li>Click on any example in the grid to automatically fill in all settings</li>
827
  <li>The preview updates in real-time as you make changes</li>
 
831
  </div>
832
  ''')
833
 
834
+ def process_badge(label, message, color_name, label_color_name, logo, logo_color_name, style, link):
835
+ color_hex = color_options.get(color_name, "#000000")
836
+ label_color_hex = color_options.get(label_color_name, "#000000")
837
+ logo_color_hex = logo_color_name if logo_color_name in ["white", "black"] else color_options.get(logo_color_name, "#ffffff")
838
+ return generate_static_badge(label, message, color_hex, label_color_hex, logo, logo_color_hex, style, link)
839
+
840
+ demo.load(
841
+ fn=process_badge,
842
+ inputs=[label, message, color, label_color, logo, logo_color, style, link],
843
+ outputs=[out_code, out_preview, info_log],
844
+ )
845
+
846
+ for inp in [label, message, color, label_color, logo, logo_color, style, link]:
847
+ inp.change(
848
+ fn=process_badge,
849
+ inputs=[label, message, color, label_color, logo, logo_color, style, link],
850
+ outputs=[out_code, out_preview, info_log],
851
+ )
852
 
853
  if __name__ == "__main__":
854
  demo.launch()