zerochat 7.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. zerochat-7.3.0.dist-info/METADATA +70 -0
  2. zerochat-7.3.0.dist-info/RECORD +130 -0
  3. zerochat-7.3.0.dist-info/WHEEL +5 -0
  4. zerochat-7.3.0.dist-info/entry_points.txt +2 -0
  5. zerochat-7.3.0.dist-info/licenses/LICENSE +34 -0
  6. zerochat-7.3.0.dist-info/top_level.txt +2 -0
  7. zerochat.py +2004 -0
  8. zerochat_runtime/__init__.py +1 -0
  9. zerochat_runtime/assets/css/base.css +199 -0
  10. zerochat_runtime/assets/css/components/composer.css +1258 -0
  11. zerochat_runtime/assets/css/components/debug.css +777 -0
  12. zerochat_runtime/assets/css/components/header.css +97 -0
  13. zerochat_runtime/assets/css/components/icons.css +39 -0
  14. zerochat_runtime/assets/css/components/markdown.css +685 -0
  15. zerochat_runtime/assets/css/components/messages.css +473 -0
  16. zerochat_runtime/assets/css/components/modals.css +1319 -0
  17. zerochat_runtime/assets/css/components/sidebar.css +622 -0
  18. zerochat_runtime/assets/css/components/tools.css +1223 -0
  19. zerochat_runtime/assets/css/layout.css +171 -0
  20. zerochat_runtime/assets/css/print.css +120 -0
  21. zerochat_runtime/assets/css/styles.css +18 -0
  22. zerochat_runtime/assets/css/theme-overrides.css +555 -0
  23. zerochat_runtime/assets/css/tokens.css +165 -0
  24. zerochat_runtime/assets/help/architecture.html +247 -0
  25. zerochat_runtime/assets/help/composer.html +134 -0
  26. zerochat_runtime/assets/help/conversations.html +105 -0
  27. zerochat_runtime/assets/help/debug.html +108 -0
  28. zerochat_runtime/assets/help/en/architecture.html +247 -0
  29. zerochat_runtime/assets/help/en/composer.html +134 -0
  30. zerochat_runtime/assets/help/en/conversations.html +104 -0
  31. zerochat_runtime/assets/help/en/debug.html +105 -0
  32. zerochat_runtime/assets/help/en/gemini-free.html +39 -0
  33. zerochat_runtime/assets/help/en/index.html +191 -0
  34. zerochat_runtime/assets/help/en/learning.html +71 -0
  35. zerochat_runtime/assets/help/en/mcp.html +143 -0
  36. zerochat_runtime/assets/help/en/openrouter-free.html +39 -0
  37. zerochat_runtime/assets/help/en/profiles.html +173 -0
  38. zerochat_runtime/assets/help/en/rag.html +130 -0
  39. zerochat_runtime/assets/help/en/reasoning-telemetry.html +108 -0
  40. zerochat_runtime/assets/help/en/tools-agent.html +133 -0
  41. zerochat_runtime/assets/help/en/webllm.html +355 -0
  42. zerochat_runtime/assets/help/gemini-free.html +39 -0
  43. zerochat_runtime/assets/help/help.css +604 -0
  44. zerochat_runtime/assets/help/help.js +51 -0
  45. zerochat_runtime/assets/help/index.html +194 -0
  46. zerochat_runtime/assets/help/learning.html +71 -0
  47. zerochat_runtime/assets/help/mcp.html +143 -0
  48. zerochat_runtime/assets/help/openrouter-free.html +39 -0
  49. zerochat_runtime/assets/help/profiles.html +174 -0
  50. zerochat_runtime/assets/help/rag.html +130 -0
  51. zerochat_runtime/assets/help/reasoning-telemetry.html +111 -0
  52. zerochat_runtime/assets/help/tools-agent.html +133 -0
  53. zerochat_runtime/assets/help/webllm.html +359 -0
  54. zerochat_runtime/assets/js/agent-core.js +1553 -0
  55. zerochat_runtime/assets/js/api.js +844 -0
  56. zerochat_runtime/assets/js/app.js +2558 -0
  57. zerochat_runtime/assets/js/attachments.js +220 -0
  58. zerochat_runtime/assets/js/charts.js +338 -0
  59. zerochat_runtime/assets/js/chat-engine.js +566 -0
  60. zerochat_runtime/assets/js/config-store.js +207 -0
  61. zerochat_runtime/assets/js/context-manager.js +584 -0
  62. zerochat_runtime/assets/js/conversation-service.js +484 -0
  63. zerochat_runtime/assets/js/cookies.js +688 -0
  64. zerochat_runtime/assets/js/data-reset-service.js +136 -0
  65. zerochat_runtime/assets/js/debug.js +508 -0
  66. zerochat_runtime/assets/js/defaults.js +16 -0
  67. zerochat_runtime/assets/js/export.js +179 -0
  68. zerochat_runtime/assets/js/file-parser.js +2088 -0
  69. zerochat_runtime/assets/js/generation-controller.js +417 -0
  70. zerochat_runtime/assets/js/i18n.js +1483 -0
  71. zerochat_runtime/assets/js/icons.js +156 -0
  72. zerochat_runtime/assets/js/ingestionEngine.js +436 -0
  73. zerochat_runtime/assets/js/markdown.js +588 -0
  74. zerochat_runtime/assets/js/mcp.js +1271 -0
  75. zerochat_runtime/assets/js/message-turns.js +62 -0
  76. zerochat_runtime/assets/js/profile-backup.js +118 -0
  77. zerochat_runtime/assets/js/profile-export-bundle.js +481 -0
  78. zerochat_runtime/assets/js/profile-repository.js +213 -0
  79. zerochat_runtime/assets/js/providers-webllm.js +486 -0
  80. zerochat_runtime/assets/js/providers.js +1560 -0
  81. zerochat_runtime/assets/js/rag-index.js +295 -0
  82. zerochat_runtime/assets/js/rag-service.js +530 -0
  83. zerochat_runtime/assets/js/rag-ui.js +997 -0
  84. zerochat_runtime/assets/js/ragStorage.js +676 -0
  85. zerochat_runtime/assets/js/sandbox.js +449 -0
  86. zerochat_runtime/assets/js/state.js +704 -0
  87. zerochat_runtime/assets/js/storage-db.js +144 -0
  88. zerochat_runtime/assets/js/tool-cards.js +330 -0
  89. zerochat_runtime/assets/js/tool-security.js +653 -0
  90. zerochat_runtime/assets/js/tools/README.md +50 -0
  91. zerochat_runtime/assets/js/tools/builtin/agent-checkpoint.tool.js +212 -0
  92. zerochat_runtime/assets/js/tools/builtin/download-pdf.tool.js +111 -0
  93. zerochat_runtime/assets/js/tools/builtin/execute-javascript.tool.js +219 -0
  94. zerochat_runtime/assets/js/tools/builtin/fetch-web-page.tool.js +112 -0
  95. zerochat_runtime/assets/js/tools/builtin/list-documents.tool.js +117 -0
  96. zerochat_runtime/assets/js/tools/builtin/read-knowledge-chunk.tool.js +129 -0
  97. zerochat_runtime/assets/js/tools/builtin/read-knowledge-image.tool.js +95 -0
  98. zerochat_runtime/assets/js/tools/builtin/render-chart.tool.js +90 -0
  99. zerochat_runtime/assets/js/tools/builtin/search-knowledge-base.tool.js +124 -0
  100. zerochat_runtime/assets/js/tools/builtin/search-web.tool.js +125 -0
  101. zerochat_runtime/assets/js/tools/tool-manifest.js +53 -0
  102. zerochat_runtime/assets/js/tools/tool-runtime.js +77 -0
  103. zerochat_runtime/assets/js/ui-composer.js +319 -0
  104. zerochat_runtime/assets/js/ui-conversation.js +655 -0
  105. zerochat_runtime/assets/js/ui-dialogs.js +132 -0
  106. zerochat_runtime/assets/js/ui-generation-status.js +119 -0
  107. zerochat_runtime/assets/js/ui-inspector.js +804 -0
  108. zerochat_runtime/assets/js/ui-mcp.js +604 -0
  109. zerochat_runtime/assets/js/ui-profiles.js +824 -0
  110. zerochat_runtime/assets/js/ui-reasoning.js +146 -0
  111. zerochat_runtime/assets/js/ui-settings.js +825 -0
  112. zerochat_runtime/assets/js/ui-shell.js +215 -0
  113. zerochat_runtime/assets/js/ui-sidebar.js +429 -0
  114. zerochat_runtime/assets/js/ui-telemetry.js +404 -0
  115. zerochat_runtime/assets/js/ui-transfer.js +262 -0
  116. zerochat_runtime/assets/js/utils.js +216 -0
  117. zerochat_runtime/assets/js/vendor/orama.browser.js +11 -0
  118. zerochat_runtime/assets/js/web-browser.js +569 -0
  119. zerochat_runtime/assets/js/web-search.js +519 -0
  120. zerochat_runtime/assets/manifest.webmanifest +20 -0
  121. zerochat_runtime/assets/services/dummy_mcp/dummy_mcp_server.py +47 -0
  122. zerochat_runtime/assets/services/dummy_mcp/service.json +22 -0
  123. zerochat_runtime/assets/services/lsp/installer.json +9 -0
  124. zerochat_runtime/assets/services/lsp/service.json +22 -0
  125. zerochat_runtime/assets/services/memory/installer.json +9 -0
  126. zerochat_runtime/assets/services/memory/service.json +24 -0
  127. zerochat_runtime/assets/services/playwright/installer.json +10 -0
  128. zerochat_runtime/assets/services/playwright/service.json +39 -0
  129. zerochat_runtime/assets/sw.js +164 -0
  130. zerochat_runtime/assets/zerochat.html +671 -0
@@ -0,0 +1,604 @@
1
+ :root {
2
+ --bg-body: #f8fafc;
3
+ --bg-card: #ffffff;
4
+ --bg-card-subtle: #f1f5f9;
5
+ --border-color: #e2e8f0;
6
+ --border-color-subtle: #cbd5e1;
7
+ --text-main: #0f172a;
8
+ --text-muted: #64748b;
9
+ --primary: #2563eb;
10
+ --primary-hover: #1d4ed8;
11
+ --primary-light: #eff6ff;
12
+ --success: #10b981;
13
+ --success-light: #ecfdf5;
14
+ --warning: #f59e0b;
15
+ --warning-light: #fffbeb;
16
+ --info: #0284c7;
17
+ --info-light: #f0f9ff;
18
+ --code-bg: #1e293b;
19
+ --code-text: #f1f5f9;
20
+ --radius: 0.75rem;
21
+ --radius-sm: 0.5rem;
22
+ --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.07), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
23
+ --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.05);
24
+ --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
25
+ --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
26
+ }
27
+
28
+ @media (prefers-color-scheme: dark) {
29
+ :root {
30
+ --bg-body: #0b0f19;
31
+ --bg-card: #151d2f;
32
+ --bg-card-subtle: #1c273e;
33
+ --border-color: #1e293b;
34
+ --border-color-subtle: #334155;
35
+ --text-main: #f8fafc;
36
+ --text-muted: #94a3b8;
37
+ --primary: #60a5fa;
38
+ --primary-hover: #93c5fd;
39
+ --primary-light: rgba(59, 130, 246, 0.15);
40
+ --success: #34d399;
41
+ --success-light: rgba(16, 185, 129, 0.15);
42
+ --warning: #fbbf24;
43
+ --warning-light: rgba(245, 158, 11, 0.15);
44
+ --info: #38bdf8;
45
+ --info-light: rgba(2, 132, 199, 0.15);
46
+ --code-bg: #0d1322;
47
+ --code-text: #e2e8f0;
48
+ --shadow: 0 4px 20px -2px rgba(0, 0, 0, 0.5);
49
+ --shadow-lg: 0 10px 25px -3px rgba(0, 0, 0, 0.6);
50
+ }
51
+ }
52
+
53
+ * { box-sizing: border-box; margin: 0; padding: 0; }
54
+
55
+ body {
56
+ font-family: var(--font);
57
+ background-color: var(--bg-body);
58
+ color: var(--text-main);
59
+ line-height: 1.65;
60
+ padding: 1.5rem 1rem 3rem;
61
+ display: flex;
62
+ justify-content: center;
63
+ }
64
+
65
+ .container {
66
+ max-width: 900px;
67
+ width: 100%;
68
+ }
69
+
70
+ /* Encabezados y navegación superior */
71
+ header {
72
+ margin-bottom: 2rem;
73
+ border-bottom: 1px solid var(--border-color);
74
+ padding-bottom: 1.25rem;
75
+ }
76
+
77
+ .header-top {
78
+ display: flex;
79
+ align-items: center;
80
+ justify-content: space-between;
81
+ flex-wrap: wrap;
82
+ gap: 0.75rem;
83
+ margin-bottom: 0.75rem;
84
+ }
85
+
86
+ .logo-badge {
87
+ display: inline-flex;
88
+ align-items: center;
89
+ gap: 0.4rem;
90
+ background: var(--primary-light);
91
+ color: var(--primary);
92
+ padding: 0.35rem 0.85rem;
93
+ border-radius: 9999px;
94
+ font-size: 0.85rem;
95
+ font-weight: 600;
96
+ text-decoration: none;
97
+ transition: opacity 0.2s ease;
98
+ }
99
+
100
+ .logo-badge:hover {
101
+ opacity: 0.9;
102
+ }
103
+
104
+ .top-nav-link {
105
+ display: inline-flex;
106
+ align-items: center;
107
+ gap: 0.4rem;
108
+ font-size: 0.875rem;
109
+ color: var(--text-muted);
110
+ text-decoration: none;
111
+ font-weight: 500;
112
+ transition: color 0.15s ease;
113
+ }
114
+
115
+ .top-nav-link:hover {
116
+ color: var(--primary);
117
+ }
118
+
119
+ .header-actions {
120
+ display: flex;
121
+ align-items: center;
122
+ gap: 0.75rem;
123
+ flex-wrap: wrap;
124
+ }
125
+
126
+ .lang-switch {
127
+ display: inline-flex;
128
+ align-items: center;
129
+ gap: 0.4rem;
130
+ font-size: 0.85rem;
131
+ background: var(--bg-card-subtle);
132
+ border: 1px solid var(--border-color);
133
+ padding: 0.25rem 0.65rem;
134
+ border-radius: 9999px;
135
+ color: var(--text-muted);
136
+ }
137
+
138
+ .lang-current {
139
+ font-weight: 700;
140
+ color: var(--primary);
141
+ }
142
+
143
+ .lang-link {
144
+ color: var(--text-muted);
145
+ text-decoration: none;
146
+ font-weight: 500;
147
+ transition: color 0.15s ease;
148
+ }
149
+
150
+ .lang-link:hover {
151
+ color: var(--primary);
152
+ text-decoration: underline;
153
+ }
154
+
155
+ h1 {
156
+ font-size: 2rem;
157
+ font-weight: 700;
158
+ letter-spacing: -0.025em;
159
+ margin-bottom: 0.5rem;
160
+ line-height: 1.25;
161
+ }
162
+
163
+ .subtitle {
164
+ color: var(--text-muted);
165
+ font-size: 1.1rem;
166
+ line-height: 1.5;
167
+ }
168
+
169
+ /* Tarjetas */
170
+ .card {
171
+ background: var(--bg-card);
172
+ border: 1px solid var(--border-color);
173
+ border-radius: var(--radius);
174
+ box-shadow: var(--shadow);
175
+ padding: 1.5rem;
176
+ margin-bottom: 1.5rem;
177
+ }
178
+
179
+ h2 {
180
+ font-size: 1.4rem;
181
+ font-weight: 700;
182
+ margin-bottom: 1rem;
183
+ display: flex;
184
+ align-items: center;
185
+ gap: 0.5rem;
186
+ border-bottom: 1px solid var(--border-color);
187
+ padding-bottom: 0.5rem;
188
+ letter-spacing: -0.015em;
189
+ }
190
+
191
+ h3 {
192
+ font-size: 1.15rem;
193
+ font-weight: 600;
194
+ margin: 1.25rem 0 0.5rem;
195
+ }
196
+
197
+ p {
198
+ margin-bottom: 0.9rem;
199
+ }
200
+
201
+ p:last-child {
202
+ margin-bottom: 0;
203
+ }
204
+
205
+ ul, ol {
206
+ margin-left: 1.4rem;
207
+ margin-bottom: 1rem;
208
+ }
209
+
210
+ li {
211
+ margin-bottom: 0.45rem;
212
+ }
213
+
214
+ /* Alertas y avisos */
215
+ .alert {
216
+ padding: 1rem 1.25rem;
217
+ border-radius: var(--radius-sm);
218
+ margin-bottom: 1.25rem;
219
+ border-left: 4px solid;
220
+ font-size: 0.95rem;
221
+ }
222
+
223
+ .alert a {
224
+ color: var(--primary);
225
+ font-weight: 600;
226
+ text-decoration: underline;
227
+ text-underline-offset: 2px;
228
+ }
229
+
230
+ .alert a:hover {
231
+ text-decoration: none;
232
+ }
233
+
234
+ .alert-info {
235
+ background: var(--info-light);
236
+ border-color: var(--info);
237
+ color: var(--text-main);
238
+ }
239
+
240
+ .alert-warning {
241
+ background: var(--warning-light);
242
+ border-color: var(--warning);
243
+ color: var(--text-main);
244
+ }
245
+
246
+ .alert-success {
247
+ background: var(--success-light);
248
+ border-color: var(--success);
249
+ color: var(--text-main);
250
+ }
251
+
252
+ /* Bloque y botón de acceso a la aplicación */
253
+ .download-action-box {
254
+ display: flex;
255
+ flex-direction: column;
256
+ align-items: flex-start;
257
+ gap: 0.5rem;
258
+ margin: 1.25rem 0;
259
+ padding: 1.1rem 1.25rem;
260
+ background: var(--bg-card-subtle);
261
+ border: 1px solid var(--border-color);
262
+ border-radius: var(--radius);
263
+ }
264
+
265
+ .btn-open-app,
266
+ .btn-download-bundle {
267
+ display: inline-flex;
268
+ align-items: center;
269
+ gap: 0.55rem;
270
+ background: var(--primary);
271
+ color: #ffffff;
272
+ font-size: 0.95rem;
273
+ font-weight: 600;
274
+ padding: 0.65rem 1.25rem;
275
+ border-radius: var(--radius-sm);
276
+ text-decoration: none;
277
+ box-shadow: var(--shadow);
278
+ transition: background-color 0.15s ease, transform 0.15s ease, opacity 0.15s ease;
279
+ }
280
+
281
+ .btn-open-app:hover,
282
+ .btn-download-bundle:hover {
283
+ background: var(--primary-hover);
284
+ transform: translateY(-1px);
285
+ color: #ffffff;
286
+ }
287
+
288
+ .btn-open-app:active,
289
+ .btn-download-bundle:active {
290
+ transform: translateY(0);
291
+ }
292
+
293
+ .btn-open-app svg,
294
+ .btn-download-bundle svg {
295
+ flex-shrink: 0;
296
+ }
297
+
298
+ .download-hint {
299
+ font-size: 0.85rem;
300
+ color: var(--text-muted);
301
+ line-height: 1.4;
302
+ }
303
+
304
+ @media (prefers-color-scheme: dark) {
305
+ .btn-open-app,
306
+ .btn-download-bundle {
307
+ color: #0b0f19;
308
+ }
309
+ .btn-open-app:hover,
310
+ .btn-download-bundle:hover {
311
+ color: #0b0f19;
312
+ }
313
+ }
314
+
315
+ /* Cuadrícula de características para el índice */
316
+ .features-grid {
317
+ display: grid;
318
+ grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
319
+ gap: 1.25rem;
320
+ margin-top: 1.5rem;
321
+ margin-bottom: 2rem;
322
+ }
323
+
324
+ .feature-card {
325
+ background: var(--bg-card);
326
+ border: 1px solid var(--border-color);
327
+ border-radius: var(--radius);
328
+ box-shadow: var(--shadow);
329
+ padding: 1.35rem;
330
+ display: flex;
331
+ flex-direction: column;
332
+ justify-content: space-between;
333
+ text-decoration: none;
334
+ color: inherit;
335
+ transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
336
+ }
337
+
338
+ .feature-card:hover {
339
+ transform: translateY(-2px);
340
+ box-shadow: var(--shadow-lg);
341
+ border-color: var(--primary);
342
+ }
343
+
344
+ .feature-icon-wrapper {
345
+ width: 40px;
346
+ height: 40px;
347
+ border-radius: var(--radius-sm);
348
+ background: var(--primary-light);
349
+ color: var(--primary);
350
+ display: flex;
351
+ align-items: center;
352
+ justify-content: center;
353
+ margin-bottom: 1rem;
354
+ }
355
+
356
+ .feature-title {
357
+ font-size: 1.15rem;
358
+ font-weight: 700;
359
+ margin-bottom: 0.5rem;
360
+ color: var(--text-main);
361
+ }
362
+
363
+ .feature-desc {
364
+ font-size: 0.925rem;
365
+ color: var(--text-muted);
366
+ line-height: 1.5;
367
+ margin-bottom: 1rem;
368
+ flex-grow: 1;
369
+ }
370
+
371
+ .feature-link {
372
+ font-size: 0.875rem;
373
+ font-weight: 600;
374
+ color: var(--primary);
375
+ display: inline-flex;
376
+ align-items: center;
377
+ gap: 0.35rem;
378
+ }
379
+
380
+ /* Bloques de código */
381
+ pre {
382
+ background: var(--code-bg);
383
+ color: var(--code-text);
384
+ padding: 1rem;
385
+ border-radius: var(--radius-sm);
386
+ overflow-x: auto;
387
+ font-family: var(--font-mono);
388
+ font-size: 0.875rem;
389
+ margin-bottom: 1rem;
390
+ position: relative;
391
+ }
392
+
393
+ code {
394
+ font-family: var(--font-mono);
395
+ background: var(--bg-card-subtle);
396
+ color: var(--primary);
397
+ padding: 0.15rem 0.4rem;
398
+ border-radius: 4px;
399
+ font-size: 0.875em;
400
+ }
401
+
402
+ pre code {
403
+ background: transparent;
404
+ color: inherit;
405
+ padding: 0;
406
+ font-size: inherit;
407
+ }
408
+
409
+ .code-wrapper {
410
+ position: relative;
411
+ margin-bottom: 1rem;
412
+ }
413
+
414
+ .code-wrapper pre {
415
+ margin-bottom: 0;
416
+ padding-right: 4.5rem;
417
+ }
418
+
419
+ .btn-copy {
420
+ position: absolute;
421
+ top: 0.5rem;
422
+ right: 0.5rem;
423
+ background: rgba(255, 255, 255, 0.15);
424
+ border: 1px solid rgba(255, 255, 255, 0.25);
425
+ color: #fff;
426
+ border-radius: 4px;
427
+ padding: 0.25rem 0.6rem;
428
+ font-size: 0.75rem;
429
+ cursor: pointer;
430
+ transition: all 0.2s ease;
431
+ }
432
+
433
+ .btn-copy:hover {
434
+ background: rgba(255, 255, 255, 0.3);
435
+ }
436
+
437
+ .btn-copy.copied {
438
+ background: var(--success);
439
+ border-color: var(--success);
440
+ }
441
+
442
+ .code-box {
443
+ display: flex;
444
+ align-items: center;
445
+ justify-content: space-between;
446
+ gap: 0.5rem;
447
+ background: var(--code-bg);
448
+ padding: 0.45rem 0.75rem;
449
+ border-radius: var(--radius-sm);
450
+ margin: 0.4rem 0 0.8rem;
451
+ }
452
+
453
+ .code-box code {
454
+ color: var(--code-text);
455
+ background: transparent;
456
+ padding: 0;
457
+ overflow-x: auto;
458
+ }
459
+
460
+ .code-box .btn-copy {
461
+ position: static;
462
+ flex-shrink: 0;
463
+ }
464
+
465
+ kbd {
466
+ font-family: var(--font-mono);
467
+ background: var(--bg-card-subtle);
468
+ border: 1px solid var(--border-color-subtle);
469
+ border-bottom: 2px solid var(--border-color-subtle);
470
+ padding: 0.1rem 0.35rem;
471
+ border-radius: 4px;
472
+ font-size: 0.8em;
473
+ color: var(--text-main);
474
+ }
475
+
476
+ /* Tablas */
477
+ .table-responsive {
478
+ overflow-x: auto;
479
+ margin-bottom: 1.25rem;
480
+ }
481
+
482
+ table {
483
+ width: 100%;
484
+ border-collapse: collapse;
485
+ font-size: 0.925rem;
486
+ }
487
+
488
+ th, td {
489
+ padding: 0.75rem 1rem;
490
+ text-align: left;
491
+ border-bottom: 1px solid var(--border-color);
492
+ }
493
+
494
+ th {
495
+ background: var(--bg-card-subtle);
496
+ font-weight: 600;
497
+ color: var(--text-main);
498
+ }
499
+
500
+ tr:last-child td {
501
+ border-bottom: none;
502
+ }
503
+
504
+ /* Barra de navegación entre páginas (Anterior / Índice / Siguiente) */
505
+ .page-navigation {
506
+ display: grid;
507
+ grid-template-columns: 1fr auto 1fr;
508
+ gap: 1rem;
509
+ margin-top: 2.5rem;
510
+ padding-top: 1.5rem;
511
+ border-top: 1px solid var(--border-color);
512
+ }
513
+
514
+ .nav-button {
515
+ display: flex;
516
+ flex-direction: column;
517
+ padding: 0.9rem 1.15rem;
518
+ border: 1px solid var(--border-color);
519
+ background: var(--bg-card);
520
+ border-radius: var(--radius);
521
+ text-decoration: none;
522
+ color: inherit;
523
+ box-shadow: var(--shadow);
524
+ transition: all 0.2s ease;
525
+ }
526
+
527
+ .nav-button:hover:not(.disabled) {
528
+ border-color: var(--primary);
529
+ transform: translateY(-2px);
530
+ box-shadow: var(--shadow-lg);
531
+ }
532
+
533
+ .nav-button.prev {
534
+ text-align: left;
535
+ }
536
+
537
+ .nav-button.index {
538
+ align-items: center;
539
+ justify-content: center;
540
+ text-align: center;
541
+ min-width: 120px;
542
+ }
543
+
544
+ .nav-button.next {
545
+ text-align: right;
546
+ align-items: flex-end;
547
+ }
548
+
549
+ .nav-direction {
550
+ font-size: 0.775rem;
551
+ text-transform: uppercase;
552
+ letter-spacing: 0.05em;
553
+ color: var(--text-muted);
554
+ margin-bottom: 0.25rem;
555
+ font-weight: 600;
556
+ }
557
+
558
+ .nav-title {
559
+ font-size: 0.95rem;
560
+ font-weight: 600;
561
+ color: var(--primary);
562
+ }
563
+
564
+ .nav-button.disabled {
565
+ opacity: 0.45;
566
+ cursor: not-allowed;
567
+ background: var(--bg-card-subtle);
568
+ box-shadow: none;
569
+ }
570
+
571
+ .nav-button.disabled .nav-title {
572
+ color: var(--text-muted);
573
+ }
574
+
575
+ /* Pie de página */
576
+ footer {
577
+ margin-top: 3rem;
578
+ text-align: center;
579
+ font-size: 0.875rem;
580
+ color: var(--text-muted);
581
+ border-top: 1px solid var(--border-color);
582
+ padding-top: 1.5rem;
583
+ }
584
+
585
+ /* Responsive */
586
+ @media (max-width: 640px) {
587
+ body {
588
+ padding: 1rem 0.75rem 2rem;
589
+ }
590
+ h1 {
591
+ font-size: 1.6rem;
592
+ }
593
+ .features-grid {
594
+ grid-template-columns: 1fr;
595
+ }
596
+ .page-navigation {
597
+ grid-template-columns: 1fr;
598
+ }
599
+ .nav-button.next {
600
+ align-items: flex-start;
601
+ text-align: left;
602
+ }
603
+ }
604
+
@@ -0,0 +1,51 @@
1
+ function copyText(text, btn) {
2
+ if (!navigator.clipboard) {
3
+ const ta = document.createElement('textarea');
4
+ ta.value = text;
5
+ ta.style.position = 'fixed';
6
+ ta.style.opacity = '0';
7
+ document.body.appendChild(ta);
8
+ ta.select();
9
+ try {
10
+ document.execCommand('copy');
11
+ markCopied(btn);
12
+ } catch (_) {}
13
+ document.body.removeChild(ta);
14
+ return;
15
+ }
16
+ navigator.clipboard.writeText(text).then(() => {
17
+ markCopied(btn);
18
+ }).catch(err => {
19
+ console.error('Error al copiar texto:', err);
20
+ });
21
+ }
22
+
23
+ function markCopied(btn) {
24
+ if (!btn) return;
25
+ const originalText = btn.textContent;
26
+ const isEn = document.documentElement.lang === 'en';
27
+ btn.textContent = isEn ? 'Copied!' : '¡Copiado!';
28
+ btn.classList.add('copied');
29
+ setTimeout(() => {
30
+ btn.textContent = originalText;
31
+ btn.classList.remove('copied');
32
+ }, 1800);
33
+ }
34
+
35
+ document.addEventListener('DOMContentLoaded', () => {
36
+ const isEn = document.documentElement.lang === 'en';
37
+ document.querySelectorAll('.code-wrapper').forEach(wrapper => {
38
+ if (wrapper.querySelector('.btn-copy')) return;
39
+ const pre = wrapper.querySelector('pre');
40
+ if (!pre) return;
41
+ const btn = document.createElement('button');
42
+ btn.type = 'button';
43
+ btn.className = 'btn-copy';
44
+ btn.textContent = isEn ? 'Copy' : 'Copiar';
45
+ btn.addEventListener('click', () => {
46
+ copyText(pre.textContent.trim(), btn);
47
+ });
48
+ wrapper.appendChild(btn);
49
+ });
50
+ });
51
+