OpceanAI commited on
Commit
4811e91
·
verified ·
1 Parent(s): 7cd65c5

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +757 -228
app.py CHANGED
@@ -1,339 +1,797 @@
1
  import gradio as gr
 
2
 
 
3
  custom_css = """
4
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');
5
 
6
  :root {
7
- --bg: #0a0a0a;
8
- --bg-card: #111111;
9
- --bg-input: #141414;
10
- --bg-hover: #1a1a1a;
11
-
12
- --border: rgba(255, 255, 255, 0.07);
13
- --border-hover: rgba(255, 255, 255, 0.14);
 
 
 
 
 
14
  --border-focus: rgba(255, 255, 255, 0.25);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
- --text: #ffffff;
17
- --text-muted: #6b6b6b;
18
- --text-dim: #3d3d3d;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
- --green: #22c55e;
21
- --green-dim: rgba(34, 197, 94, 0.15);
 
 
 
 
22
 
23
- --user-bg: #1c1c1c;
24
- --bot-bg: #111111;
 
 
25
 
26
- --font: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
27
- --mono: 'JetBrains Mono', 'SFMono-Regular', Consolas, monospace;
 
 
 
 
 
 
 
 
 
28
 
29
- --r-sm: 4px;
30
- --r-md: 6px;
31
- --r-lg: 8px;
 
 
 
 
 
 
 
 
32
  }
33
 
34
- *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
 
 
 
 
 
 
 
 
 
 
 
 
 
35
 
36
- body,
37
  .gradio-container,
38
  .gradio-container > .main,
39
  .gradio-container > .main > .wrap {
40
- background: var(--bg) !important;
41
- color: var(--text) !important;
42
- font-family: var(--font) !important;
43
- font-size: 13px !important;
44
- line-height: 1.5 !important;
45
- letter-spacing: -0.01em !important;
46
- -webkit-font-smoothing: antialiased !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  }
48
 
49
- .sidebar, aside {
50
- background: var(--bg) !important;
51
- border-right: 1px solid var(--border) !important;
52
- padding: 28px 20px !important;
53
- min-width: 200px !important;
54
- max-width: 220px !important;
55
- display: flex !important;
56
- flex-direction: column !important;
57
- gap: 0 !important;
58
  }
59
 
60
- .sidebar *, aside * { color: var(--text) !important; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
  .sidebar h1, aside h1 {
63
- font-family: var(--font) !important;
64
- font-size: 15px !important;
65
  font-weight: 700 !important;
66
  letter-spacing: -0.03em !important;
67
- color: var(--text) !important;
68
- line-height: 1.2 !important;
69
- margin-bottom: 14px !important;
70
- }
71
-
72
- .sidebar h1::before, aside h1::before {
73
- content: '● ' !important;
74
- color: var(--green) !important;
75
- font-size: 10px !important;
76
- letter-spacing: 0 !important;
77
  }
78
 
79
  .sidebar p, aside p {
80
  font-size: 12px !important;
81
- line-height: 1.65 !important;
82
- color: var(--text-muted) !important;
83
- font-weight: 400 !important;
84
- letter-spacing: 0 !important;
85
- margin-bottom: 0 !important;
86
  }
87
 
88
  .sidebar button, aside button {
89
- display: flex !important;
90
- align-items: center !important;
91
- justify-content: center !important;
92
- width: 100% !important;
93
- margin-top: 18px !important;
94
  padding: 8px 16px !important;
95
- height: 34px !important;
96
- background: transparent !important;
97
- color: var(--text) !important;
98
- border: 1px solid var(--border-hover) !important;
99
- border-radius: var(--r-md) !important;
100
- font-family: var(--font) !important;
101
  font-size: 12px !important;
102
  font-weight: 500 !important;
103
- letter-spacing: -0.01em !important;
104
  cursor: pointer !important;
105
- transition: border-color 0.12s, background 0.12s !important;
106
  }
107
 
108
  .sidebar button:hover, aside button:hover {
109
- background: var(--bg-hover) !important;
110
- border-color: var(--border-focus) !important;
111
- }
112
-
113
- .contain, .gap, .wrap,
114
- div[class*="col"], div[class*="row"],
115
- .gradio-container .block {
116
- background: var(--bg) !important;
117
- box-shadow: none !important;
118
  }
119
 
120
  .chatbot,
121
  div[data-testid="chatbot"] {
122
- background: var(--bg-card) !important;
123
- border: 1px solid var(--border) !important;
124
- border-radius: var(--r-lg) !important;
125
  box-shadow: none !important;
126
- overflow: hidden !important;
127
- height: 420px !important;
128
- max-height: 420px !important;
129
- min-height: 420px !important;
130
- flex-shrink: 0 !important;
131
- }
132
-
133
- .sidebar-collapse-btn,
134
- button[aria-label="Collapse sidebar"],
135
- button[aria-label="Hide sidebar"],
136
- .sidebar-toggle {
137
- display: none !important;
138
- }
139
-
140
- .chatbot .label-wrap,
141
- div[data-testid="chatbot"] .label-wrap {
142
- background: var(--bg-card) !important;
143
- border-bottom: 1px solid var(--border) !important;
144
- padding: 9px 14px !important;
145
- }
146
-
147
- .chatbot .label-wrap span,
148
- div[data-testid="chatbot"] .label-wrap span {
149
- font-family: var(--mono) !important;
150
- font-size: 10px !important;
151
- font-weight: 500 !important;
152
- letter-spacing: 0.1em !important;
153
- color: var(--text-muted) !important;
154
- text-transform: uppercase !important;
155
  }
156
 
157
  .chatbot .message-wrap,
158
  div[data-testid="chatbot"] .message-wrap {
159
- padding: 14px !important;
160
- background: var(--bg-card) !important;
161
- max-height: 340px !important;
162
- overflow-y: auto !important;
163
- display: flex !important;
164
- flex-direction: column !important;
165
- gap: 8px !important;
166
  }
167
 
168
  .message {
169
- max-width: 82% !important;
170
- padding: 9px 13px !important;
171
- border-radius: var(--r-md) !important;
172
- font-family: var(--font) !important;
173
  font-size: 13px !important;
174
  line-height: 1.6 !important;
175
- letter-spacing: 0 !important;
176
  }
177
 
178
  .message.user, .user.message {
179
- background: var(--user-bg) !important;
180
- color: var(--text) !important;
181
  align-self: flex-end !important;
182
- border: 1px solid var(--border) !important;
183
- border-bottom-right-radius: var(--r-sm) !important;
 
 
184
  }
185
 
186
  .message.bot, .bot.message {
187
- background: var(--bot-bg) !important;
188
- color: rgba(255,255,255,0.85) !important;
189
  align-self: flex-start !important;
190
- border: 1px solid var(--border) !important;
191
- border-bottom-left-radius: var(--r-sm) !important;
192
  }
193
 
194
  .message code {
195
- font-family: var(--mono) !important;
196
- font-size: 11px !important;
197
- background: #1a1a1a !important;
198
- border: 1px solid var(--border) !important;
199
- border-radius: var(--r-sm) !important;
200
- padding: 1px 5px !important;
201
- color: var(--green) !important;
202
  }
203
 
204
  .message pre {
205
- font-family: var(--mono) !important;
206
- font-size: 11px !important;
207
- background: #111 !important;
208
- border: 1px solid var(--border) !important;
209
- border-radius: var(--r-md) !important;
210
- padding: 10px 12px !important;
211
- color: rgba(255,255,255,0.75) !important;
212
  overflow-x: auto !important;
213
- margin-top: 6px !important;
214
  }
215
 
216
  textarea,
217
  input[type="text"],
218
  .scroll-hide {
219
  background: var(--bg-input) !important;
220
- border: 1px solid var(--border) !important;
221
- border-radius: var(--r-md) !important;
222
- color: var(--text) !important;
223
- font-family: var(--font) !important;
224
  font-size: 13px !important;
225
- line-height: 1.5 !important;
226
- padding: 9px 12px !important;
227
  resize: none !important;
228
- transition: border-color 0.12s !important;
229
- caret-color: var(--green) !important;
230
- letter-spacing: 0 !important;
231
  }
232
 
233
  textarea:focus, input[type="text"]:focus {
234
  border-color: var(--border-focus) !important;
235
  outline: none !important;
236
- box-shadow: none !important;
237
  }
238
 
239
  textarea::placeholder, input[type="text"]::placeholder {
240
- color: var(--text-dim) !important;
241
  }
242
 
243
  button[variant="primary"], .submit-btn {
244
- background: var(--text) !important;
245
- color: var(--bg) !important;
246
  border: none !important;
247
- border-radius: var(--r-md) !important;
248
- font-family: var(--font) !important;
249
- font-size: 12px !important;
250
  font-weight: 600 !important;
251
- height: 34px !important;
252
- padding: 0 16px !important;
253
- letter-spacing: -0.01em !important;
254
  cursor: pointer !important;
255
- transition: opacity 0.12s !important;
256
  }
257
 
258
  button[variant="primary"]:hover, .submit-btn:hover {
259
- opacity: 0.88 !important;
 
260
  }
261
 
262
  button[variant="secondary"] {
263
  background: transparent !important;
264
- color: var(--text-muted) !important;
265
- border: 1px solid var(--border) !important;
266
- border-radius: var(--r-md) !important;
267
- font-family: var(--font) !important;
268
  font-size: 12px !important;
269
- height: 32px !important;
270
- padding: 0 12px !important;
271
- transition: border-color 0.12s, color 0.12s !important;
272
  }
273
 
274
  button[variant="secondary"]:hover {
275
- border-color: var(--border-focus) !important;
276
- color: var(--text) !important;
 
277
  }
278
 
279
  label span, .label-wrap span {
280
- font-family: var(--mono) !important;
281
  font-size: 10px !important;
282
  font-weight: 500 !important;
283
- letter-spacing: 0.1em !important;
284
- color: var(--text-muted) !important;
285
  text-transform: uppercase !important;
286
  }
287
 
288
  .block, .gr-block {
289
- background: var(--bg) !important;
290
- border-color: var(--border) !important;
291
- border-radius: var(--r-lg) !important;
292
  box-shadow: none !important;
293
  }
294
 
295
- .examples table { border: none !important; }
296
-
297
  .examples td {
298
  background: var(--bg-card) !important;
299
- border: 1px solid var(--border) !important;
300
- border-radius: var(--r-sm) !important;
301
- font-family: var(--font) !important;
302
  font-size: 12px !important;
303
- color: var(--text-muted) !important;
304
- padding: 7px 11px !important;
305
  cursor: pointer !important;
306
- transition: border-color 0.12s, color 0.12s !important;
307
  }
308
 
309
  .examples td:hover {
310
- border-color: var(--border-hover) !important;
311
- color: var(--text) !important;
 
312
  }
313
 
314
- ::-webkit-scrollbar { width: 3px; height: 3px; }
 
315
  ::-webkit-scrollbar-track { background: transparent; }
316
- ::-webkit-scrollbar-thumb { background: var(--border-hover); border-radius: 99px; }
317
- ::-webkit-scrollbar-thumb:hover { background: var(--text-dim); }
318
- * { scrollbar-width: thin !important; scrollbar-color: var(--border-hover) transparent !important; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
319
 
 
 
 
 
 
320
  footer, .footer, .built-with { display: none !important; }
321
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
322
  @media (max-width: 768px) {
323
- .sidebar, aside {
324
- min-width: 100% !important;
325
- max-width: 100% !important;
326
- border-right: none !important;
327
- border-bottom: 1px solid var(--border) !important;
328
- padding: 20px 16px !important;
 
 
 
 
 
 
 
 
 
 
 
 
329
  }
330
- .message { max-width: 92% !important; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
331
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
332
  """
333
 
 
334
  with gr.Blocks(
335
  fill_height=True,
336
  css=custom_css,
 
337
  title="Yuuki-RxG",
338
  theme=gr.themes.Base(
339
  primary_hue="zinc",
@@ -343,44 +801,115 @@ with gr.Blocks(
343
  radius_size=gr.themes.sizes.radius_sm,
344
  spacing_size=gr.themes.sizes.spacing_sm,
345
  ).set(
346
- body_background_fill="#0a0a0a",
347
- body_text_color="#ffffff",
348
- background_fill_primary="#0a0a0a",
349
- background_fill_secondary="#111111",
350
- border_color_primary="rgba(255,255,255,0.07)",
351
  color_accent="#22c55e",
352
  color_accent_soft="rgba(34,197,94,0.12)",
353
- button_primary_background_fill="#ffffff",
354
- button_primary_text_color="#0a0a0a",
355
- button_primary_background_fill_hover="#e5e5e5",
356
  button_secondary_background_fill="transparent",
357
- button_secondary_border_color="rgba(255,255,255,0.07)",
358
- button_secondary_text_color="#6b6b6b",
359
- block_border_color="rgba(255,255,255,0.07)",
360
- block_background_fill="#111111",
361
  block_shadow="none",
362
- input_background_fill="#141414",
363
- input_border_color="rgba(255,255,255,0.07)",
364
  input_border_color_focus="rgba(255,255,255,0.25)",
365
  input_shadow_focus="none",
366
  shadow_drop="none",
367
  shadow_drop_lg="none",
368
  )
369
  ) as demo:
370
- with gr.Sidebar():
371
- gr.Markdown("# Yuuki-RxG")
372
- gr.Markdown(
373
- "Modelo servido via featherless-ai. "
374
- "Inicia sesión con tu cuenta de Hugging Face para acceder a la inferencia."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
375
  )
376
- button = gr.LoginButton("Iniciar sesión")
377
 
378
- gr.load(
379
- "models/OpceanAI/Yuuki-RxG",
380
- accept_token=button,
381
- provider="featherless-ai",
382
- )
 
 
 
383
 
384
  if __name__ == "__main__":
385
  demo.launch()
386
-
 
1
  import gradio as gr
2
+ import os
3
 
4
+ # ─── Custom CSS ───────────────────────────────────────────────────────────────
5
  custom_css = """
6
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&family=JetBrains+Mono:wght@400;500;600&display=swap');
7
 
8
  :root {
9
+ /* Dark theme (default) */
10
+ --bg-primary: #09090b;
11
+ --bg-secondary: #111113;
12
+ --bg-tertiary: #18181b;
13
+ --bg-card: rgba(255, 255, 255, 0.03);
14
+ --bg-card-hover: rgba(255, 255, 255, 0.05);
15
+ --bg-glass: rgba(255, 255, 255, 0.04);
16
+ --bg-glass-strong: rgba(255, 255, 255, 0.07);
17
+ --bg-input: rgba(255, 255, 255, 0.04);
18
+
19
+ --border-primary: rgba(255, 255, 255, 0.08);
20
+ --border-secondary: rgba(255, 255, 255, 0.12);
21
  --border-focus: rgba(255, 255, 255, 0.25);
22
+ --border-glass: rgba(255, 255, 255, 0.1);
23
+
24
+ --text-primary: #fafafa;
25
+ --text-secondary: #a1a1aa;
26
+ --text-tertiary: #52525b;
27
+ --text-inverse: #09090b;
28
+
29
+ --accent: #22c55e;
30
+ --accent-soft: rgba(34, 197, 94, 0.12);
31
+ --accent-glow: rgba(34, 197, 94, 0.25);
32
+
33
+ --purple: #a855f7;
34
+ --purple-soft: rgba(168, 85, 247, 0.12);
35
+ --blue: #3b82f6;
36
+ --blue-soft: rgba(59, 130, 246, 0.12);
37
+
38
+ --blur-sm: 8px;
39
+ --blur-md: 16px;
40
+ --blur-lg: 24px;
41
+ --blur-xl: 40px;
42
+
43
+ --radius-sm: 6px;
44
+ --radius-md: 10px;
45
+ --radius-lg: 14px;
46
+ --radius-xl: 20px;
47
+ --radius-full: 9999px;
48
+
49
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
50
+ --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4);
51
+ --shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.5);
52
+ --shadow-glow: 0 0 40px rgba(34, 197, 94, 0.15);
53
+
54
+ --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
55
+ --font-mono: 'JetBrains Mono', 'SF Mono', 'Fira Code', monospace;
56
+
57
+ --transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
58
+ --transition-base: 250ms cubic-bezier(0.4, 0, 0.2, 1);
59
+ --transition-slow: 400ms cubic-bezier(0.4, 0, 0.2, 1);
60
+ }
61
 
62
+ /* Light theme */
63
+ [data-theme="light"] {
64
+ --bg-primary: #ffffff;
65
+ --bg-secondary: #f4f4f5;
66
+ --bg-tertiary: #e4e4e7;
67
+ --bg-card: rgba(0, 0, 0, 0.02);
68
+ --bg-card-hover: rgba(0, 0, 0, 0.04);
69
+ --bg-glass: rgba(255, 255, 255, 0.7);
70
+ --bg-glass-strong: rgba(255, 255, 255, 0.85);
71
+ --bg-input: rgba(0, 0, 0, 0.03);
72
+
73
+ --border-primary: rgba(0, 0, 0, 0.08);
74
+ --border-secondary: rgba(0, 0, 0, 0.12);
75
+ --border-focus: rgba(0, 0, 0, 0.25);
76
+ --border-glass: rgba(255, 255, 255, 0.5);
77
+
78
+ --text-primary: #09090b;
79
+ --text-secondary: #52525b;
80
+ --text-tertiary: #a1a1aa;
81
+ --text-inverse: #fafafa;
82
+
83
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
84
+ --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08);
85
+ --shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.12);
86
+ }
87
 
88
+ /* ─── Reset & Base ─────────────────────────────────────────────────────────── */
89
+ *, *::before, *::after {
90
+ box-sizing: border-box;
91
+ margin: 0;
92
+ padding: 0;
93
+ }
94
 
95
+ html {
96
+ scroll-behavior: smooth;
97
+ -webkit-text-size-adjust: 100%;
98
+ }
99
 
100
+ body {
101
+ font-family: var(--font-sans) !important;
102
+ font-size: 14px !important;
103
+ line-height: 1.6 !important;
104
+ letter-spacing: -0.01em !important;
105
+ color: var(--text-primary) !important;
106
+ background: var(--bg-primary) !important;
107
+ -webkit-font-smoothing: antialiased !important;
108
+ -moz-osx-font-smoothing: grayscale !important;
109
+ overflow-x: hidden !important;
110
+ }
111
 
112
+ /* ─── Grain Overlay ────────────────────────────────────────────────────────── */
113
+ body::before {
114
+ content: '';
115
+ position: fixed;
116
+ inset: 0;
117
+ pointer-events: none;
118
+ z-index: 9999;
119
+ opacity: 0.015;
120
+ background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");
121
+ background-repeat: repeat;
122
+ background-size: 128px 128px;
123
  }
124
 
125
+ /* ─── Gradient Orbs (Background Depth) ─────────────────────────────────────── */
126
+ body::after {
127
+ content: '';
128
+ position: fixed;
129
+ top: -20%;
130
+ left: 50%;
131
+ transform: translateX(-50%);
132
+ width: 80vw;
133
+ height: 80vh;
134
+ background: radial-gradient(ellipse at center, var(--accent-soft) 0%, transparent 70%);
135
+ pointer-events: none;
136
+ z-index: -1;
137
+ opacity: 0.5;
138
+ }
139
 
140
+ /* ─── Gradio Container ─────────────────────────────────────────────────────── */
141
  .gradio-container,
142
  .gradio-container > .main,
143
  .gradio-container > .main > .wrap {
144
+ background: transparent !important;
145
+ padding: 0 !important;
146
+ max-width: 100% !important;
147
+ }
148
+
149
+ /* ─── Navbar / Top Bar ─────────────────────────────────────────────────────── */
150
+ .navbar {
151
+ position: fixed;
152
+ top: 0;
153
+ left: 0;
154
+ right: 0;
155
+ z-index: 1000;
156
+ display: flex;
157
+ align-items: center;
158
+ justify-content: space-between;
159
+ padding: 12px 24px;
160
+ background: var(--bg-glass-strong);
161
+ backdrop-filter: blur(var(--blur-lg));
162
+ -webkit-backdrop-filter: blur(var(--blur-lg));
163
+ border-bottom: 1px solid var(--border-primary);
164
+ transition: background var(--transition-base), border-color var(--transition-base);
165
+ }
166
+
167
+ .navbar-brand {
168
+ display: flex;
169
+ align-items: center;
170
+ gap: 10px;
171
+ text-decoration: none;
172
+ }
173
+
174
+ .navbar-logo {
175
+ width: 28px;
176
+ height: 28px;
177
+ border-radius: var(--radius-md);
178
+ background: linear-gradient(135deg, var(--accent), var(--purple));
179
+ display: flex;
180
+ align-items: center;
181
+ justify-content: center;
182
+ font-weight: 800;
183
+ font-size: 14px;
184
+ color: var(--text-inverse);
185
+ box-shadow: var(--shadow-glow);
186
+ }
187
+
188
+ .navbar-title {
189
+ font-size: 15px;
190
+ font-weight: 700;
191
+ letter-spacing: -0.03em;
192
+ color: var(--text-primary);
193
+ }
194
+
195
+ .navbar-actions {
196
+ display: flex;
197
+ align-items: center;
198
+ gap: 8px;
199
+ }
200
+
201
+ .theme-toggle {
202
+ width: 36px;
203
+ height: 36px;
204
+ border-radius: var(--radius-full);
205
+ background: var(--bg-card);
206
+ border: 1px solid var(--border-primary);
207
+ color: var(--text-secondary);
208
+ cursor: pointer;
209
+ display: flex;
210
+ align-items: center;
211
+ justify-content: center;
212
+ transition: all var(--transition-fast);
213
+ }
214
+
215
+ .theme-toggle:hover {
216
+ background: var(--bg-card-hover);
217
+ border-color: var(--border-secondary);
218
+ color: var(--text-primary);
219
+ }
220
+
221
+ .theme-toggle svg {
222
+ width: 16px;
223
+ height: 16px;
224
+ }
225
+
226
+ /* ─── Hero Section ─────────────────────────────────────────────────────────── */
227
+ .hero {
228
+ padding: 120px 24px 60px;
229
+ text-align: center;
230
+ max-width: 800px;
231
+ margin: 0 auto;
232
+ position: relative;
233
+ }
234
+
235
+ .hero-badge {
236
+ display: inline-flex;
237
+ align-items: center;
238
+ gap: 6px;
239
+ padding: 6px 14px;
240
+ border-radius: var(--radius-full);
241
+ background: var(--bg-glass);
242
+ border: 1px solid var(--border-primary);
243
+ font-size: 12px;
244
+ font-weight: 500;
245
+ color: var(--text-secondary);
246
+ margin-bottom: 24px;
247
+ backdrop-filter: blur(var(--blur-sm));
248
+ -webkit-backdrop-filter: blur(var(--blur-sm));
249
+ }
250
+
251
+ .hero-badge-dot {
252
+ width: 6px;
253
+ height: 6px;
254
+ border-radius: 50%;
255
+ background: var(--accent);
256
+ box-shadow: 0 0 8px var(--accent-glow);
257
+ animation: pulse 2s ease-in-out infinite;
258
+ }
259
+
260
+ @keyframes pulse {
261
+ 0%, 100% { opacity: 1; transform: scale(1); }
262
+ 50% { opacity: 0.6; transform: scale(1.2); }
263
+ }
264
+
265
+ .hero h1 {
266
+ font-size: clamp(2.5rem, 6vw, 4rem) !important;
267
+ font-weight: 800 !important;
268
+ letter-spacing: -0.04em !important;
269
+ line-height: 1.1 !important;
270
+ margin-bottom: 16px !important;
271
+ background: linear-gradient(135deg, var(--text-primary) 0%, var(--text-secondary) 100%);
272
+ -webkit-background-clip: text;
273
+ -webkit-text-fill-color: transparent;
274
+ background-clip: text;
275
+ }
276
+
277
+ .hero p {
278
+ font-size: 18px;
279
+ color: var(--text-secondary);
280
+ max-width: 560px;
281
+ margin: 0 auto 32px;
282
+ line-height: 1.7;
283
+ }
284
+
285
+ .hero-cta {
286
+ display: flex;
287
+ align-items: center;
288
+ justify-content: center;
289
+ gap: 12px;
290
+ flex-wrap: wrap;
291
+ }
292
+
293
+ .btn {
294
+ display: inline-flex;
295
+ align-items: center;
296
+ gap: 8px;
297
+ padding: 10px 20px;
298
+ border-radius: var(--radius-md);
299
+ font-family: var(--font-sans);
300
+ font-size: 14px;
301
+ font-weight: 600;
302
+ letter-spacing: -0.01em;
303
+ cursor: pointer;
304
+ transition: all var(--transition-fast);
305
+ text-decoration: none;
306
+ border: none;
307
+ }
308
+
309
+ .btn-primary {
310
+ background: var(--text-primary);
311
+ color: var(--text-inverse);
312
+ }
313
+
314
+ .btn-primary:hover {
315
+ opacity: 0.85;
316
+ transform: translateY(-1px);
317
+ box-shadow: var(--shadow-md);
318
+ }
319
+
320
+ .btn-secondary {
321
+ background: var(--bg-card);
322
+ color: var(--text-primary);
323
+ border: 1px solid var(--border-primary);
324
+ }
325
+
326
+ .btn-secondary:hover {
327
+ background: var(--bg-card-hover);
328
+ border-color: var(--border-secondary);
329
+ }
330
+
331
+ /* ─── Features Section ─────────────────────────────────────────────────────── */
332
+ .features {
333
+ padding: 40px 24px 60px;
334
+ max-width: 1100px;
335
+ margin: 0 auto;
336
+ }
337
+
338
+ .features-grid {
339
+ display: grid;
340
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
341
+ gap: 16px;
342
+ }
343
+
344
+ .feature-card {
345
+ padding: 24px;
346
+ border-radius: var(--radius-lg);
347
+ background: var(--bg-glass);
348
+ border: 1px solid var(--border-primary);
349
+ backdrop-filter: blur(var(--blur-md));
350
+ -webkit-backdrop-filter: blur(var(--blur-md));
351
+ transition: all var(--transition-base);
352
+ position: relative;
353
+ overflow: hidden;
354
+ }
355
+
356
+ .feature-card::before {
357
+ content: '';
358
+ position: absolute;
359
+ inset: 0;
360
+ background: linear-gradient(135deg, transparent 0%, var(--bg-card-hover) 100%);
361
+ opacity: 0;
362
+ transition: opacity var(--transition-base);
363
+ }
364
+
365
+ .feature-card:hover {
366
+ border-color: var(--border-secondary);
367
+ transform: translateY(-2px);
368
+ box-shadow: var(--shadow-lg);
369
+ }
370
+
371
+ .feature-card:hover::before {
372
+ opacity: 1;
373
+ }
374
+
375
+ .feature-icon {
376
+ width: 40px;
377
+ height: 40px;
378
+ border-radius: var(--radius-md);
379
+ background: var(--bg-card);
380
+ border: 1px solid var(--border-primary);
381
+ display: flex;
382
+ align-items: center;
383
+ justify-content: center;
384
+ margin-bottom: 16px;
385
+ color: var(--accent);
386
+ }
387
+
388
+ .feature-card h3 {
389
+ font-size: 15px;
390
+ font-weight: 600;
391
+ letter-spacing: -0.02em;
392
+ margin-bottom: 8px;
393
+ color: var(--text-primary);
394
+ }
395
+
396
+ .feature-card p {
397
+ font-size: 13px;
398
+ color: var(--text-secondary);
399
+ line-height: 1.6;
400
+ }
401
+
402
+ /* ─── Chat Section ─────────────────────────────────────────────────────────── */
403
+ .chat-section {
404
+ padding: 40px 24px 80px;
405
+ max-width: 900px;
406
+ margin: 0 auto;
407
  }
408
 
409
+ .chat-container {
410
+ border-radius: var(--radius-xl);
411
+ background: var(--bg-glass);
412
+ border: 1px solid var(--border-primary);
413
+ backdrop-filter: blur(var(--blur-lg));
414
+ -webkit-backdrop-filter: blur(var(--blur-lg));
415
+ overflow: hidden;
416
+ box-shadow: var(--shadow-lg);
 
417
  }
418
 
419
+ .chat-header {
420
+ padding: 16px 20px;
421
+ border-bottom: 1px solid var(--border-primary);
422
+ display: flex;
423
+ align-items: center;
424
+ gap: 12px;
425
+ background: var(--bg-glass-strong);
426
+ }
427
+
428
+ .chat-header-dot {
429
+ width: 8px;
430
+ height: 8px;
431
+ border-radius: 50%;
432
+ background: var(--accent);
433
+ box-shadow: 0 0 12px var(--accent-glow);
434
+ }
435
+
436
+ .chat-header h3 {
437
+ font-size: 13px;
438
+ font-weight: 600;
439
+ letter-spacing: -0.01em;
440
+ color: var(--text-primary);
441
+ }
442
+
443
+ .chat-header span {
444
+ font-size: 12px;
445
+ color: var(--text-tertiary);
446
+ margin-left: auto;
447
+ }
448
+
449
+ /* ─── Gradio Overrides ─────────────────────────────────────────────────────── */
450
+ .gradio-container .sidebar,
451
+ .gradio-container aside {
452
+ background: var(--bg-glass-strong) !important;
453
+ backdrop-filter: blur(var(--blur-lg)) !important;
454
+ -webkit-backdrop-filter: blur(var(--blur-lg)) !important;
455
+ border-right: 1px solid var(--border-primary) !important;
456
+ padding: 80px 20px 24px !important;
457
+ min-width: 220px !important;
458
+ max-width: 240px !important;
459
+ }
460
 
461
  .sidebar h1, aside h1 {
462
+ font-family: var(--font-sans) !important;
463
+ font-size: 16px !important;
464
  font-weight: 700 !important;
465
  letter-spacing: -0.03em !important;
466
+ color: var(--text-primary) !important;
467
+ margin-bottom: 12px !important;
 
 
 
 
 
 
 
 
468
  }
469
 
470
  .sidebar p, aside p {
471
  font-size: 12px !important;
472
+ color: var(--text-secondary) !important;
473
+ line-height: 1.6 !important;
 
 
 
474
  }
475
 
476
  .sidebar button, aside button {
477
+ margin-top: 16px !important;
 
 
 
 
478
  padding: 8px 16px !important;
479
+ height: 36px !important;
480
+ background: var(--bg-card) !important;
481
+ color: var(--text-primary) !important;
482
+ border: 1px solid var(--border-primary) !important;
483
+ border-radius: var(--radius-md) !important;
484
+ font-family: var(--font-sans) !important;
485
  font-size: 12px !important;
486
  font-weight: 500 !important;
 
487
  cursor: pointer !important;
488
+ transition: all var(--transition-fast) !important;
489
  }
490
 
491
  .sidebar button:hover, aside button:hover {
492
+ background: var(--bg-card-hover) !important;
493
+ border-color: var(--border-secondary) !important;
 
 
 
 
 
 
 
494
  }
495
 
496
  .chatbot,
497
  div[data-testid="chatbot"] {
498
+ background: transparent !important;
499
+ border: none !important;
500
+ border-radius: 0 !important;
501
  box-shadow: none !important;
502
+ height: 480px !important;
503
+ max-height: 480px !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
504
  }
505
 
506
  .chatbot .message-wrap,
507
  div[data-testid="chatbot"] .message-wrap {
508
+ padding: 16px !important;
509
+ background: transparent !important;
 
 
 
 
 
510
  }
511
 
512
  .message {
513
+ max-width: 80% !important;
514
+ padding: 10px 14px !important;
515
+ border-radius: var(--radius-md) !important;
516
+ font-family: var(--font-sans) !important;
517
  font-size: 13px !important;
518
  line-height: 1.6 !important;
 
519
  }
520
 
521
  .message.user, .user.message {
522
+ background: var(--bg-glass-strong) !important;
523
+ color: var(--text-primary) !important;
524
  align-self: flex-end !important;
525
+ border: 1px solid var(--border-primary) !important;
526
+ border-bottom-right-radius: var(--radius-sm) !important;
527
+ backdrop-filter: blur(var(--blur-sm)) !important;
528
+ -webkit-backdrop-filter: blur(var(--blur-sm)) !important;
529
  }
530
 
531
  .message.bot, .bot.message {
532
+ background: var(--bg-card) !important;
533
+ color: var(--text-secondary) !important;
534
  align-self: flex-start !important;
535
+ border: 1px solid var(--border-primary) !important;
536
+ border-bottom-left-radius: var(--radius-sm) !important;
537
  }
538
 
539
  .message code {
540
+ font-family: var(--font-mono) !important;
541
+ font-size: 12px !important;
542
+ background: var(--bg-tertiary) !important;
543
+ border: 1px solid var(--border-primary) !important;
544
+ border-radius: var(--radius-sm) !important;
545
+ padding: 2px 6px !important;
546
+ color: var(--accent) !important;
547
  }
548
 
549
  .message pre {
550
+ font-family: var(--font-mono) !important;
551
+ font-size: 12px !important;
552
+ background: var(--bg-secondary) !important;
553
+ border: 1px solid var(--border-primary) !important;
554
+ border-radius: var(--radius-md) !important;
555
+ padding: 12px !important;
556
+ color: var(--text-secondary) !important;
557
  overflow-x: auto !important;
558
+ margin-top: 8px !important;
559
  }
560
 
561
  textarea,
562
  input[type="text"],
563
  .scroll-hide {
564
  background: var(--bg-input) !important;
565
+ border: 1px solid var(--border-primary) !important;
566
+ border-radius: var(--radius-md) !important;
567
+ color: var(--text-primary) !important;
568
+ font-family: var(--font-sans) !important;
569
  font-size: 13px !important;
570
+ padding: 10px 14px !important;
 
571
  resize: none !important;
572
+ transition: border-color var(--transition-fast) !important;
573
+ caret-color: var(--accent) !important;
 
574
  }
575
 
576
  textarea:focus, input[type="text"]:focus {
577
  border-color: var(--border-focus) !important;
578
  outline: none !important;
579
+ box-shadow: 0 0 0 3px var(--accent-soft) !important;
580
  }
581
 
582
  textarea::placeholder, input[type="text"]::placeholder {
583
+ color: var(--text-tertiary) !important;
584
  }
585
 
586
  button[variant="primary"], .submit-btn {
587
+ background: var(--text-primary) !important;
588
+ color: var(--text-inverse) !important;
589
  border: none !important;
590
+ border-radius: var(--radius-md) !important;
591
+ font-family: var(--font-sans) !important;
592
+ font-size: 13px !important;
593
  font-weight: 600 !important;
594
+ height: 38px !important;
595
+ padding: 0 18px !important;
 
596
  cursor: pointer !important;
597
+ transition: all var(--transition-fast) !important;
598
  }
599
 
600
  button[variant="primary"]:hover, .submit-btn:hover {
601
+ opacity: 0.85;
602
+ transform: translateY(-1px);
603
  }
604
 
605
  button[variant="secondary"] {
606
  background: transparent !important;
607
+ color: var(--text-secondary) !important;
608
+ border: 1px solid var(--border-primary) !important;
609
+ border-radius: var(--radius-md) !important;
610
+ font-family: var(--font-sans) !important;
611
  font-size: 12px !important;
612
+ height: 34px !important;
613
+ padding: 0 14px !important;
614
+ transition: all var(--transition-fast) !important;
615
  }
616
 
617
  button[variant="secondary"]:hover {
618
+ border-color: var(--border-secondary) !important;
619
+ color: var(--text-primary) !important;
620
+ background: var(--bg-card) !important;
621
  }
622
 
623
  label span, .label-wrap span {
624
+ font-family: var(--font-mono) !important;
625
  font-size: 10px !important;
626
  font-weight: 500 !important;
627
+ letter-spacing: 0.08em !important;
628
+ color: var(--text-tertiary) !important;
629
  text-transform: uppercase !important;
630
  }
631
 
632
  .block, .gr-block {
633
+ background: transparent !important;
634
+ border-color: var(--border-primary) !important;
635
+ border-radius: var(--radius-lg) !important;
636
  box-shadow: none !important;
637
  }
638
 
 
 
639
  .examples td {
640
  background: var(--bg-card) !important;
641
+ border: 1px solid var(--border-primary) !important;
642
+ border-radius: var(--radius-sm) !important;
643
+ font-family: var(--font-sans) !important;
644
  font-size: 12px !important;
645
+ color: var(--text-secondary) !important;
646
+ padding: 8px 12px !important;
647
  cursor: pointer !important;
648
+ transition: all var(--transition-fast) !important;
649
  }
650
 
651
  .examples td:hover {
652
+ border-color: var(--border-secondary) !important;
653
+ color: var(--text-primary) !important;
654
+ background: var(--bg-card-hover) !important;
655
  }
656
 
657
+ /* ─── Scrollbar ────────────────────────────────────────────────────────────── */
658
+ ::-webkit-scrollbar { width: 4px; height: 4px; }
659
  ::-webkit-scrollbar-track { background: transparent; }
660
+ ::-webkit-scrollbar-thumb { background: var(--border-secondary); border-radius: 99px; }
661
+ ::-webkit-scrollbar-thumb:hover { background: var(--text-tertiary); }
662
+ * { scrollbar-width: thin !important; scrollbar-color: var(--border-secondary) transparent !important; }
663
+
664
+ /* ─── Footer ───────────────────────────────────────────────────────────────── */
665
+ .footer {
666
+ padding: 24px;
667
+ text-align: center;
668
+ border-top: 1px solid var(--border-primary);
669
+ color: var(--text-tertiary);
670
+ font-size: 12px;
671
+ }
672
+
673
+ .footer a {
674
+ color: var(--text-secondary);
675
+ text-decoration: none;
676
+ transition: color var(--transition-fast);
677
+ }
678
 
679
+ .footer a:hover {
680
+ color: var(--text-primary);
681
+ }
682
+
683
+ /* ─── Hide Gradio Footer ───────────────────────────────────────────────────── */
684
  footer, .footer, .built-with { display: none !important; }
685
 
686
+ /* ─── Animations ───────────────────────────────────────────────────────────── */
687
+ @keyframes fadeInUp {
688
+ from {
689
+ opacity: 0;
690
+ transform: translateY(20px);
691
+ }
692
+ to {
693
+ opacity: 1;
694
+ transform: translateY(0);
695
+ }
696
+ }
697
+
698
+ .hero { animation: fadeInUp 0.6s ease-out; }
699
+ .features-grid { animation: fadeInUp 0.6s ease-out 0.1s both; }
700
+ .chat-section { animation: fadeInUp 0.6s ease-out 0.2s both; }
701
+
702
+ /* ─── Responsive ───────────────────────────────────────────────────────────── */
703
  @media (max-width: 768px) {
704
+ .navbar { padding: 10px 16px; }
705
+ .hero { padding: 100px 16px 40px; }
706
+ .hero h1 { font-size: 2rem !important; }
707
+ .hero p { font-size: 15px; }
708
+ .features { padding: 24px 16px 40px; }
709
+ .chat-section { padding: 24px 16px 60px; }
710
+
711
+ .gradio-container .sidebar,
712
+ .gradio-container aside {
713
+ position: fixed !important;
714
+ top: 0 !important;
715
+ left: 0 !important;
716
+ bottom: 0 !important;
717
+ width: 280px !important;
718
+ max-width: 80vw !important;
719
+ z-index: 999 !important;
720
+ transform: translateX(-100%) !important;
721
+ transition: transform var(--transition-base) !important;
722
  }
723
+
724
+ .gradio-container .sidebar.open,
725
+ .gradio-container aside.open {
726
+ transform: translateX(0) !important;
727
+ }
728
+
729
+ .message { max-width: 90% !important; }
730
+ }
731
+
732
+ /* ─── Reduced Motion ───────────────────────────────────────────────────────── */
733
+ @media (prefers-reduced-motion: reduce) {
734
+ *, *::before, *::after {
735
+ animation-duration: 0.01ms !important;
736
+ animation-iteration-count: 1 !important;
737
+ transition-duration: 0.01ms !important;
738
+ }
739
+ }
740
+ """
741
+
742
+ # ─── Custom JS ────────────────────────────────────────────────────────────────
743
+ custom_js = """
744
+ function initTheme() {
745
+ const stored = localStorage.getItem('theme');
746
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
747
+ const theme = stored || (prefersDark ? 'dark' : 'light');
748
+ document.documentElement.setAttribute('data-theme', theme);
749
+ updateThemeIcon(theme);
750
+ }
751
+
752
+ function toggleTheme() {
753
+ const current = document.documentElement.getAttribute('data-theme');
754
+ const next = current === 'dark' ? 'light' : 'dark';
755
+ document.documentElement.setAttribute('data-theme', next);
756
+ localStorage.setItem('theme', next);
757
+ updateThemeIcon(next);
758
+ }
759
+
760
+ function updateThemeIcon(theme) {
761
+ const btn = document.querySelector('.theme-toggle');
762
+ if (!btn) return;
763
+ const isDark = theme === 'dark';
764
+ btn.innerHTML = isDark
765
+ ? '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2"/><path d="M12 20v2"/><path d="m4.93 4.93 1.41 1.41"/><path d="m17.66 17.66 1.41 1.41"/><path d="M2 12h2"/><path d="M20 12h2"/><path d="m6.34 17.66-1.41 1.41"/><path d="m19.07 4.93-1.41 1.41"/></svg>'
766
+ : '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/></svg>';
767
  }
768
+
769
+ function setupNavbar() {
770
+ const navbar = document.createElement('nav');
771
+ navbar.className = 'navbar';
772
+ navbar.innerHTML = `
773
+ <div class="navbar-brand">
774
+ <div class="navbar-logo">Y</div>
775
+ <span class="navbar-title">Yuuki-RxG</span>
776
+ </div>
777
+ <div class="navbar-actions">
778
+ <button class="theme-toggle" onclick="toggleTheme()" aria-label="Toggle theme"></button>
779
+ </div>
780
+ `;
781
+ document.body.insertBefore(navbar, document.body.firstChild);
782
+ }
783
+
784
+ document.addEventListener('DOMContentLoaded', () => {
785
+ initTheme();
786
+ setupNavbar();
787
+ });
788
  """
789
 
790
+ # ─── App ──────────────────────────────────────────────────────────────────────
791
  with gr.Blocks(
792
  fill_height=True,
793
  css=custom_css,
794
+ js=custom_js,
795
  title="Yuuki-RxG",
796
  theme=gr.themes.Base(
797
  primary_hue="zinc",
 
801
  radius_size=gr.themes.sizes.radius_sm,
802
  spacing_size=gr.themes.sizes.spacing_sm,
803
  ).set(
804
+ body_background_fill="#09090b",
805
+ body_text_color="#fafafa",
806
+ background_fill_primary="#09090b",
807
+ background_fill_secondary="#111113",
808
+ border_color_primary="rgba(255,255,255,0.08)",
809
  color_accent="#22c55e",
810
  color_accent_soft="rgba(34,197,94,0.12)",
811
+ button_primary_background_fill="#fafafa",
812
+ button_primary_text_color="#09090b",
813
+ button_primary_background_fill_hover="#e4e4e7",
814
  button_secondary_background_fill="transparent",
815
+ button_secondary_border_color="rgba(255,255,255,0.08)",
816
+ button_secondary_text_color="#a1a1aa",
817
+ block_border_color="rgba(255,255,255,0.08)",
818
+ block_background_fill="transparent",
819
  block_shadow="none",
820
+ input_background_fill="rgba(255,255,255,0.04)",
821
+ input_border_color="rgba(255,255,255,0.08)",
822
  input_border_color_focus="rgba(255,255,255,0.25)",
823
  input_shadow_focus="none",
824
  shadow_drop="none",
825
  shadow_drop_lg="none",
826
  )
827
  ) as demo:
828
+ # Hero Section
829
+ gr.HTML("""
830
+ <section class="hero">
831
+ <div class="hero-badge">
832
+ <span class="hero-badge-dot"></span>
833
+ Powered by Featherless AI
834
+ </div>
835
+ <h1>Yuuki-RxG</h1>
836
+ <p>Modelo de lenguaje de última generación servido vía featherless-ai. Inferencia rápida, segura y con autenticación Hugging Face.</p>
837
+ <div class="hero-cta">
838
+ <a href="#chat" class="btn btn-primary">
839
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/></svg>
840
+ Iniciar chat
841
+ </a>
842
+ <a href="https://huggingface.co/OpceanAI/Yuuki-RxG" target="_blank" class="btn btn-secondary">
843
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1-2.5-1.5-5.5-1.5-8 0-2-1-3-1-3-1-.28 1.15-.28 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4"/><path d="M9 18H6a2 2 0 0 1-2-2v-1a2 2 0 0 1 2-2h3"/></svg>
844
+ Ver modelo
845
+ </a>
846
+ </div>
847
+ </section>
848
+ """)
849
+
850
+ # Features Section
851
+ gr.HTML("""
852
+ <section class="features">
853
+ <div class="features-grid">
854
+ <div class="feature-card">
855
+ <div class="feature-icon">
856
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2 3 14h9l-1 8 10-12h-9l1-8z"/></svg>
857
+ </div>
858
+ <h3>Inferencia Ultra-Rápida</h3>
859
+ <p>Respuestas en milisegundos gracias a la infraestructura optimizada de Featherless AI.</p>
860
+ </div>
861
+ <div class="feature-card">
862
+ <div class="feature-icon">
863
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
864
+ </div>
865
+ <h3>Autenticación Segura</h3>
866
+ <p>Acceso protegido con OAuth de Hugging Face. Solo usuarios autorizados pueden interactuar.</p>
867
+ </div>
868
+ <div class="feature-card">
869
+ <div class="feature-icon">
870
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10"/></svg>
871
+ </div>
872
+ <h3>Privacidad Primero</h3>
873
+ <p>Tus conversaciones no se almacenan. Cada sesión es efímera y completamente privada.</p>
874
+ </div>
875
+ </div>
876
+ </section>
877
+ """)
878
+
879
+ # Chat Section
880
+ with gr.Group(elem_classes="chat-section"):
881
+ gr.HTML("""
882
+ <div class="chat-container" id="chat">
883
+ <div class="chat-header">
884
+ <span class="chat-header-dot"></span>
885
+ <h3>Chat con Yuuki-RxG</h3>
886
+ <span>Featherless AI</span>
887
+ </div>
888
+ </div>
889
+ """)
890
+
891
+ with gr.Sidebar():
892
+ gr.Markdown("# Yuuki-RxG")
893
+ gr.Markdown(
894
+ "Modelo servido via featherless-ai. "
895
+ "Inicia sesión con tu cuenta de Hugging Face para acceder a la inferencia."
896
+ )
897
+ button = gr.LoginButton("Iniciar sesión")
898
+
899
+ gr.load(
900
+ "models/OpceanAI/Yuuki-RxG",
901
+ accept_token=button,
902
+ provider="featherless-ai",
903
  )
 
904
 
905
+ # Footer
906
+ gr.HTML("""
907
+ <footer class="footer">
908
+ <p>Construido con <a href="https://gradio.app" target="_blank">Gradio</a> ·
909
+ Servido vía <a href="https://featherless.ai" target="_blank">Featherless AI</a> ·
910
+ <a href="https://huggingface.co/OpceanAI/Yuuki-RxG" target="_blank">Hugging Face</a></p>
911
+ </footer>
912
+ """)
913
 
914
  if __name__ == "__main__":
915
  demo.launch()