doctorlinux commited on
Commit
b62cc8d
·
verified ·
1 Parent(s): 79c6ac6

Upload index.html

Browse files
Files changed (1) hide show
  1. index.html +348 -376
index.html CHANGED
@@ -1,384 +1,356 @@
1
  <!DOCTYPE html>
2
  <html lang="es">
3
  <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Informe de Ciberseguridad - Doctor Linux</title>
7
- <style>
8
- :root {
9
- --primary: #1a3a5f;
10
- --secondary: #2c5282;
11
- --accent: #e53e3e;
12
- --success: #38a169;
13
- --warning: #d69e2e;
14
- --danger: #e53e3e;
15
- --light: #f7fafc;
16
- --dark: #2d3748;
17
- --gray: #718096;
18
- }
19
-
20
- * {
21
- margin: 0;
22
- padding: 0;
23
- box-sizing: border-box;
24
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
25
- }
26
-
27
- body {
28
- background-color: #f5f7fa;
29
- color: var(--dark);
30
- line-height: 1.6;
31
- padding: 20px;
32
- }
33
-
34
- .container {
35
- max-width: 1000px;
36
- margin: 0 auto;
37
- background: white;
38
- border-radius: 12px;
39
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
40
- overflow: hidden;
41
- }
42
-
43
- header {
44
- background: linear-gradient(135deg, var(--primary), var(--secondary));
45
- color: white;
46
- padding: 25px 30px;
47
- position: relative;
48
- }
49
-
50
- .logo {
51
- display: flex;
52
- align-items: center;
53
- margin-bottom: 15px;
54
- }
55
-
56
- .logo-icon {
57
- font-size: 24px;
58
- margin-right: 10px;
59
- }
60
-
61
- h1 {
62
- font-size: 24px;
63
- font-weight: 600;
64
- margin-bottom: 5px;
65
- }
66
-
67
- .subtitle {
68
- font-size: 14px;
69
- opacity: 0.9;
70
- }
71
-
72
- .report-meta {
73
- display: flex;
74
- justify-content: space-between;
75
- margin-top: 20px;
76
- flex-wrap: wrap;
77
- gap: 15px;
78
- }
79
-
80
- .score-container {
81
- text-align: center;
82
- background: rgba(255, 255, 255, 0.15);
83
- padding: 15px 25px;
84
- border-radius: 10px;
85
- backdrop-filter: blur(5px);
86
- }
87
-
88
- .global-score {
89
- font-size: 42px;
90
- font-weight: 700;
91
- line-height: 1;
92
- }
93
-
94
- .score-label {
95
- font-size: 14px;
96
- margin-top: 5px;
97
- }
98
-
99
- .date {
100
- display: flex;
101
- align-items: center;
102
- font-size: 16px;
103
- }
104
-
105
- .date-icon {
106
- margin-right: 8px;
107
- }
108
-
109
- main {
110
- padding: 30px;
111
- }
112
-
113
- .section {
114
- margin-bottom: 35px;
115
- }
116
-
117
- h2 {
118
- font-size: 20px;
119
- color: var(--primary);
120
- margin-bottom: 20px;
121
- padding-bottom: 10px;
122
- border-bottom: 1px solid #e2e8f0;
123
- display: flex;
124
- align-items: center;
125
- }
126
-
127
- h2 i {
128
- margin-right: 10px;
129
- }
130
-
131
- .domains-grid {
132
- display: grid;
133
- grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
134
- gap: 20px;
135
- }
136
-
137
- .domain-card {
138
- background: var(--light);
139
- border-radius: 10px;
140
- padding: 20px;
141
- transition: transform 0.3s, box-shadow 0.3s;
142
- }
143
-
144
- .domain-card:hover {
145
- transform: translateY(-5px);
146
- box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
147
- }
148
-
149
- .domain-header {
150
- display: flex;
151
- justify-content: space-between;
152
- align-items: center;
153
- margin-bottom: 15px;
154
- }
155
-
156
- .domain-name {
157
- font-weight: 600;
158
- color: var(--dark);
159
- }
160
-
161
- .domain-score {
162
- font-weight: 700;
163
- font-size: 22px;
164
- }
165
-
166
- .score-100 { color: var(--success); }
167
- .score-83 { color: var(--success); }
168
- .score-50 { color: var(--warning); }
169
- .score-0 { color: var(--danger); }
170
-
171
- .progress-bar {
172
- height: 8px;
173
- background: #e2e8f0;
174
- border-radius: 4px;
175
- overflow: hidden;
176
- }
177
-
178
- .progress-fill {
179
- height: 100%;
180
- border-radius: 4px;
181
- }
182
-
183
- .fill-100 { width: 100%; background: var(--success); }
184
- .fill-83 { width: 83%; background: var(--success); }
185
- .fill-50 { width: 50%; background: var(--warning); }
186
- .fill-0 { width: 0%; background: var(--danger); }
187
-
188
- .recommendations-list {
189
- list-style-type: none;
190
- }
191
-
192
- .recommendation-item {
193
- padding: 15px;
194
- margin-bottom: 12px;
195
- background: #f8f9fa;
196
- border-left: 4px solid var(--secondary);
197
- border-radius: 0 8px 8px 0;
198
- display: flex;
199
- align-items: flex-start;
200
- }
201
-
202
- .recommendation-item i {
203
- color: var(--secondary);
204
- margin-right: 12px;
205
- margin-top: 2px;
206
- }
207
-
208
- .priority-high {
209
- border-left-color: var(--danger);
210
- }
211
-
212
- .priority-high i {
213
- color: var(--danger);
214
- }
215
-
216
- footer {
217
- background: var(--light);
218
- padding: 20px 30px;
219
- text-align: center;
220
- color: var(--gray);
221
- font-size: 14px;
222
- border-top: 1px solid #e2e8f0;
223
- }
224
-
225
- .footer-logo {
226
- font-weight: 700;
227
- color: var(--primary);
228
- }
229
-
230
- @media (max-width: 768px) {
231
- .domains-grid {
232
- grid-template-columns: 1fr;
233
- }
234
-
235
- .report-meta {
236
- flex-direction: column;
237
- }
238
-
239
- .score-container {
240
- order: -1;
241
- margin-bottom: 15px;
242
- }
243
- }
244
- </style>
245
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
246
  </head>
 
247
  <body>
248
- <div class="container">
249
- <header>
250
- <div class="logo">
251
- <div class="logo-icon"><i class="fas fa-shield-alt"></i></div>
252
- <div>
253
- <h1>INFORME DE CIBERSEGURIDAD</h1>
254
- <div class="subtitle">DOCTOR LINUX</div>
255
- </div>
256
- </div>
257
-
258
- <div class="report-meta">
259
- <div class="date">
260
- <div class="date-icon"><i class="far fa-calendar-alt"></i></div>
261
- <div>13 de Octubre, 2025</div>
262
- </div>
263
-
264
- <div class="score-container">
265
- <div class="global-score">69%</div>
266
- <div class="score-label">Puntaje Global</div>
267
- </div>
268
- </div>
269
- </header>
270
-
271
- <main>
272
- <section class="section">
273
- <h2><i class="fas fa-exclamation-triangle"></i> RESUMEN: MEJORAS NECESARIAS</h2>
274
- <p>El análisis de seguridad ha identificado áreas críticas que requieren atención inmediata para fortalecer la postura de ciberseguridad de la organización.</p>
275
- </section>
276
-
277
- <section class="section">
278
- <h2><i class="fas fa-chart-bar"></i> DETALLE POR DOMINIO</h2>
279
- <div class="domains-grid">
280
- <div class="domain-card">
281
- <div class="domain-header">
282
- <div class="domain-name">Perímetro / Firewall</div>
283
- <div class="domain-score score-100">100%</div>
284
- </div>
285
- <div class="progress-bar">
286
- <div class="progress-fill fill-100"></div>
287
- </div>
288
- </div>
289
-
290
- <div class="domain-card">
291
- <div class="domain-header">
292
- <div class="domain-name">Servidores / Hardening</div>
293
- <div class="domain-score score-100">100%</div>
294
- </div>
295
- <div class="progress-bar">
296
- <div class="progress-fill fill-100"></div>
297
- </div>
298
- </div>
299
-
300
- <div class="domain-card">
301
- <div class="domain-header">
302
- <div class="domain-name">Backups y Recuperación</div>
303
- <div class="domain-score score-100">100%</div>
304
- </div>
305
- <div class="progress-bar">
306
- <div class="progress-fill fill-100"></div>
307
- </div>
308
- </div>
309
-
310
- <div class="domain-card">
311
- <div class="domain-header">
312
- <div class="domain-name">Monitoreo y Alertas</div>
313
- <div class="domain-score score-0">0%</div>
314
- </div>
315
- <div class="progress-bar">
316
- <div class="progress-fill fill-0"></div>
317
- </div>
318
- </div>
319
-
320
- <div class="domain-card">
321
- <div class="domain-header">
322
- <div class="domain-name">Red y Conectividad</div>
323
- <div class="domain-score score-50">50%</div>
324
- </div>
325
- <div class="progress-bar">
326
- <div class="progress-fill fill-50"></div>
327
- </div>
328
- </div>
329
-
330
- <div class="domain-card">
331
- <div class="domain-header">
332
- <div class="domain-name">Usuarios / Estaciones</div>
333
- <div class="domain-score score-50">50%</div>
334
- </div>
335
- <div class="progress-bar">
336
- <div class="progress-fill fill-50"></div>
337
- </div>
338
- </div>
339
-
340
- <div class="domain-card">
341
- <div class="domain-header">
342
- <div class="domain-name">Web y Correo</div>
343
- <div class="domain-score score-83">83%</div>
344
- </div>
345
- <div class="progress-bar">
346
- <div class="progress-fill fill-83"></div>
347
- </div>
348
- </div>
349
- </div>
350
- </section>
351
-
352
- <section class="section">
353
- <h2><i class="fas fa-clipboard-list"></i> RECOMENDACIONES</h2>
354
- <ul class="recommendations-list">
355
- <li class="recommendation-item">
356
- <i class="fas fa-check-circle"></i>
357
- <div>Revisar configuración de firewall y accesos para garantizar la seguridad del perímetro.</div>
358
- </li>
359
- <li class="recommendation-item">
360
- <i class="fas fa-check-circle"></i>
361
- <div>Implementar estrategia de backups 3-2-1 (3 copias, 2 medios diferentes, 1 fuera del sitio).</div>
362
- </li>
363
- <li class="recommendation-item priority-high">
364
- <i class="fas fa-exclamation-circle"></i>
365
- <div>Establecer monitoreo continuo 24/7 con sistema de alertas para detección temprana de incidentes.</div>
366
- </li>
367
- <li class="recommendation-item">
368
- <i class="fas fa-check-circle"></i>
369
- <div>Aplicar hardening en servidores para reducir superficie de ataque.</div>
370
- </li>
371
- <li class="recommendation-item">
372
- <i class="fas fa-check-circle"></i>
373
- <div>Implementar autenticación multifactor (MFA) para todos los usuarios con acceso privilegiado.</div>
374
- </li>
375
- </ul>
376
- </section>
377
- </main>
378
-
379
- <footer>
380
- <div>Generado por <span class="footer-logo">Doctor Linux</span> - www.doctorlinux.com</div>
381
- </footer>
382
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
383
  </body>
384
  </html>
 
1
  <!DOCTYPE html>
2
  <html lang="es">
3
  <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Autoevaluación de Ciberseguridad Operativa - Doctor Linux</title>
7
+ <style>
8
+ body{font-family:system-ui,-apple-system,Segoe UI,Roboto,Inter,Arial,sans-serif;background:#f5f6f5;margin:0;padding:0}
9
+ .dlx-wrap{max-width:960px;margin:auto;padding:16px}
10
+ .dlx-card{background:#fff;border:1px solid #e6ebef;border-radius:16px;box-shadow:0 6px 24px rgba(0,0,0,.06);padding:22px;margin:14px 0}
11
+ .dlx-title{font-size:28px;margin:0 0 4px;color:#214424}
12
+ .dlx-sub{color:#5c6b5f;margin-bottom:16px}
13
+ .dlx-progress{height:10px;background:#eff4f0;border-radius:999px;overflow:hidden;margin:10px 0 18px}
14
+ .dlx-bar{height:100%;width:0;background:#7fbf7f;transition:width .3s}
15
+ .dlx-q h4{margin:0 0 6px;font-size:18px}
16
+ .dlx-options{display:flex;gap:10px;flex-wrap:wrap;margin:6px 0 12px}
17
+ .dlx-pill{border:1px solid #d7e1d9;padding:8px 12px;border-radius:999px;cursor:pointer}
18
+ .dlx-pill input{display:none}
19
+ .dlx-pill.active{background:#214424;color:#fff;border-color:#214424}
20
+ .dlx-nav{display:flex;gap:10px;justify-content:space-between;margin-top:8px}
21
+ .dlx-btn{background:#214424;color:#fff;border:none;border-radius:10px;padding:12px 16px;cursor:pointer;transition:all 0.3s}
22
+ .dlx-btn:hover{background:#1a361c}
23
+ .dlx-btn[disabled]{opacity:.5;cursor:not-allowed}
24
+ .dlx-meter{display:grid;grid-template-columns:1fr auto;gap:6px 10px;margin:8px 0}
25
+ .dlx-badge{font-weight:600}
26
+ .dlx-tag{display:inline-block;background:#eff4f0;border:1px solid #dfe9e2;border-radius:8px;padding:6px 10px;margin:6px 6px 0 0}
27
+ .dlx-note{color:#6a786d}
28
+ .dlx-score{font-size:40px;font-weight:800;color:#214424}
29
+ .dlx-muted{color:#7b8b7f}
30
+ </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  </head>
32
+
33
  <body>
34
+ <div class="dlx-wrap" id="dlxApp">
35
+ <div class="dlx-card">
36
+ <h2 class="dlx-title">Autoevaluación de Ciberseguridad Operativa</h2>
37
+ <div class="dlx-sub">Responde con honestidad. Obtendrás tu <b>puntaje</b>, los <b>riesgos clave</b> y un plan sugerido de mejora.</div>
38
+ <div class="dlx-progress"><div class="dlx-bar" id="dlxBar"></div></div>
39
+ <div class="dlx-note dlx-muted" id="dlxStepNote"></div>
40
+ </div>
41
+
42
+ <div id="dlxSteps"></div>
43
+
44
+ <div class="dlx-card" id="dlxNavBox">
45
+ <div class="dlx-nav">
46
+ <button class="dlx-btn" id="prevBtn">← Anterior</button>
47
+ <button class="dlx-btn" id="nextBtn">Siguiente →</button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  </div>
49
+ </div>
50
+
51
+ <div class="dlx-card" id="dlxResult" style="display:none">
52
+ <h3 class="dlx-title">Tu diagnóstico</h3>
53
+ <div class="dlx-sub">Este resultado es orientativo. Si quieres un informe firmado por ingeniería, solicita el <b>diagnóstico gratuito</b>.</div>
54
+ <div style="display:flex;gap:24px;align-items:center;flex-wrap:wrap">
55
+ <div>
56
+ <div class="dlx-muted">Puntaje global</div>
57
+ <div class="dlx-score" id="dlxScore">—%</div>
58
+ <div class="dlx-tag" id="dlxLabel">—</div>
59
+ </div>
60
+ <div style="flex:1;min-width:260px">
61
+ <div class="dlx-progress"><div class="dlx-bar" id="dlxBarFinal" style="background:#3aa655"></div></div>
62
+ <div class="dlx-note">≈ Mayor a 80%: postura sólida. 60–79%: revisar. Menor a 60%: riesgo elevado.</div>
63
+ </div>
64
+ </div>
65
+
66
+ <div class="dlx-card" style="margin-top:16px">
67
+ <h4 style="margin:0 0 8px">Detalle por dominio</h4>
68
+ <div id="dlxBreakdown" class="dlx-meter"></div>
69
+ </div>
70
+
71
+ <div class="dlx-card">
72
+ <h4 style="margin:0 0 8px">Recomendaciones inmediatas</h4>
73
+ <div id="dlxRecs"></div>
74
+ <div class="dlx-note" style="margin-top:8px">Tip: prioriza los dominios con menor puntaje. Podemos ayudarte a cerrar brechas con <b>hardening, firewalls, backups 3-2-1 y monitoreo 24/7</b>.</div>
75
+ </div>
76
+
77
+ <!-- BOTONES DE ACCIÓN -->
78
+ <div class="dlx-nav" style="margin-top:25px">
79
+ <button class="dlx-btn" onclick="window.location.reload()">🔄 Nueva Evaluación</button>
80
+ <button class="dlx-btn" id="analyzeBtn">🤖 Análisis con IA</button>
81
+ <button class="dlx-btn" onclick="downloadReport()" style="background:#3aa655">📄 Descargar Informe</button>
82
+ </div>
83
+
84
+ <div id="iaBox" class="dlx-card" style="display:none;margin-top:16px">
85
+ <h4>Análisis generado por IA</h4>
86
+ <pre id="iaOutput" style="white-space:pre-wrap;"></pre>
87
+ </div>
88
+ </div>
89
+ </div>
90
+
91
+ <script>
92
+ /* === CONFIGURACIÓN INICIAL === */
93
+ const DOMAINS = [
94
+ { id:'perimetro', name:'Perímetro / Firewall', qs:[
95
+ '¿Usas un firewall dedicado (Mikrotik/OPNsense/etc.) con reglas mínimas por servicio?',
96
+ '¿Tienes listas de acceso/geo-bloqueo/IPS/DoS activas?',
97
+ '¿Los servicios expuestos están detrás de NAT o Port-Forward controlado?',
98
+ '¿Hay políticas VPN de acceso remoto con 2FA?'
99
+ ]},
100
+ { id:'servers', name:'Servidores / Hardening', qs:[
101
+ '¿Cuentas con hardening básico (SSH seguro, usuarios/roles, auditoría)?',
102
+ '¿Actualizaciones y parches aplicados regularmente?',
103
+ '¿Servicios innecesarios deshabilitados/controlados?'
104
+ ]},
105
+ { id:'backups', name:'Backups y Recuperación', qs:[
106
+ '¿Aplicas la regla 3-2-1 (3 copias, 2 medios, 1 offsite)?',
107
+ '¿Pruebas de restauración realizadas en los últimos 6 meses?',
108
+ '¿Backups protegidos contra ransomware (inmutables/air-gap)?'
109
+ ]},
110
+ { id:'monitor', name:'Monitoreo y Alertas', qs:[
111
+ '¿Monitoreo centralizado (Zabbix/PRTG/Grafana) con alertas 24/7?',
112
+ '¿Métricas revisadas mensualmente?',
113
+ '¿Alertas integradas con soporte?'
114
+ ]},
115
+ { id:'network', name:'Red y Conectividad', qs:[
116
+ '¿Segmentación VLANs para aislar servicios críticos?',
117
+ '¿Control de ancho de banda/Proxy/filtrado de contenidos?',
118
+ '¿Wi-Fi empresarial con WPA2-Enterprise?'
119
+ ]},
120
+ { id:'endpoints', name:'Usuarios / Estaciones', qs:[
121
+ '¿Antimalware/EDR y políticas de actualización?',
122
+ '¿Gestión de contraseñas y MFA?',
123
+ '¿Políticas de mínimo privilegio + bloqueo de USB?'
124
+ ]},
125
+ { id:'webmail', name:'Web y Correo', qs:[
126
+ '¿Sitios con HTTPS válido y cabeceras seguras?',
127
+ '¿Correo con SPF, DKIM y DMARC publicados?',
128
+ '¿WAF/antispam/antiphishing activos?'
129
+ ]}
130
+ ];
131
+
132
+ const SCALE = [
133
+ {label:'No',score:0},
134
+ {label:'Parcial',score:50},
135
+ {label:'Sí',score:100},
136
+ {label:'No sé',score:null}
137
+ ];
138
+
139
+ const RECS = {
140
+ perimetro:'Endurecer perímetro: reglas mínimo necesario, VPN 2FA, IDS/IPS y protección DoS.',
141
+ servers:'Aplicar hardening, cuentas/roles y mantener parches al día.',
142
+ backups:'Implementar 3-2-1 con pruebas de restauración y backups inmutables.',
143
+ monitor:'Centralizar monitoreo (Zabbix/PRTG) y definir umbrales.',
144
+ network:'Segregar VLANs, reforzar proxy y aislar Wi-Fi invitados.',
145
+ endpoints:'Mínimo privilegio, EDR/antimalware y MFA.',
146
+ webmail:'Forzar HTTPS, cabeceras OWASP, SPF+DKIM+DMARC y WAF.'
147
+ };
148
+
149
+ let current = 0, answers = {};
150
+ const steps = document.getElementById('dlxSteps'),
151
+ bar = document.getElementById('dlxBar'),
152
+ note = document.getElementById('dlxStepNote'),
153
+ prev = document.getElementById('prevBtn'),
154
+ next = document.getElementById('nextBtn'),
155
+ result = document.getElementById('dlxResult'),
156
+ nav = document.getElementById('dlxNavBox');
157
+
158
+ /* === FUNCIONES PRINCIPALES === */
159
+ function render() {
160
+ steps.innerHTML = '';
161
+ const d = DOMAINS[current];
162
+ note.innerHTML = `<b>${current+1}/${DOMAINS.length}</b> · ${d.name}`;
163
+ const card = document.createElement('div');
164
+ card.className = 'dlx-card';
165
+ card.innerHTML = `<h3 class="dlx-title">${d.name}</h3>`;
166
+ d.qs.forEach((q, i) => {
167
+ const b = document.createElement('div');
168
+ b.className = 'dlx-q';
169
+ b.innerHTML = `<h4>${q}</h4>`;
170
+ const row = document.createElement('div');
171
+ row.className = 'dlx-options';
172
+ SCALE.forEach(opt => {
173
+ const lbl = document.createElement('label');
174
+ lbl.className = 'dlx-pill';
175
+ lbl.textContent = opt.label;
176
+ lbl.onclick = () => {
177
+ row.querySelectorAll('.dlx-pill').forEach(p => p.classList.remove('active'));
178
+ lbl.classList.add('active');
179
+ if (!answers[d.id]) answers[d.id] = [];
180
+ answers[d.id][i] = opt.score;
181
+ updateButtons();
182
+ };
183
+ if (answers[d.id] && answers[d.id][i] === opt.score) lbl.classList.add('active');
184
+ row.appendChild(lbl);
185
+ });
186
+ b.appendChild(row);
187
+ card.appendChild(b);
188
+ });
189
+ steps.appendChild(card);
190
+ bar.style.width = Math.round(current / DOMAINS.length * 100) + '%';
191
+ updateButtons();
192
+ }
193
+
194
+ function allAnswered(i) {
195
+ const d = DOMAINS[i];
196
+ return answers[d.id] && answers[d.id].length === d.qs.length && answers[d.id].every(v => v !== undefined);
197
+ }
198
+
199
+ function avg(a) {
200
+ const nums = a.filter(v => typeof v === 'number' && isFinite(v));
201
+ if (nums.length === 0) return 0;
202
+ return nums.reduce((x, y) => x + y, 0) / nums.length;
203
+ }
204
+
205
+ function updateButtons() {
206
+ prev.disabled = current === 0;
207
+ const last = current === DOMAINS.length - 1;
208
+ next.textContent = last ? 'Ver resultado →' : 'Siguiente →';
209
+ next.disabled = !allAnswered(current);
210
+ }
211
+
212
+ prev.onclick = () => { if (current > 0) { current--; render(); } };
213
+ next.onclick = () => {
214
+ if (current < DOMAINS.length - 1) {
215
+ if (!allAnswered(current)) return;
216
+ current++; render();
217
+ } else {
218
+ if (!allAnswered(current)) return;
219
+ showResult();
220
+ }
221
+ };
222
+
223
+ function showResult() {
224
+ bar.style.width = '100%';
225
+ nav.style.display = 'none';
226
+ steps.style.display = 'none';
227
+ note.style.display = 'none';
228
+ result.style.display = 'block';
229
+ let weighted = 0, total = 0;
230
+ const breakdown = document.getElementById('dlxBreakdown'),
231
+ recs = document.getElementById('dlxRecs');
232
+ breakdown.innerHTML = '';
233
+ recs.innerHTML = '';
234
+ DOMAINS.forEach(d => {
235
+ const a = answers[d.id] ? avg(answers[d.id]) : 0;
236
+ weighted += a; total += 100;
237
+ const pct = Math.round(a);
238
+ breakdown.innerHTML += `<div>${d.name}</div><div><b>${pct}%</b></div>`;
239
+ if (pct < 75) { recs.innerHTML += `<div class="dlx-tag">• ${RECS[d.id]}</div>`; }
240
+ });
241
+ const global = Math.round(weighted / DOMAINS.length);
242
+ document.getElementById('dlxScore').textContent = global + '%';
243
+ document.getElementById('dlxBarFinal').style.width = global + '%';
244
+ const label = document.getElementById('dlxLabel');
245
+ if (global >= 80) { label.textContent = 'Nivel Sólido'; label.style.background = '#e7f7e7'; }
246
+ else if (global >= 60) { label.textContent = 'Nivel Medio (revisar)'; label.style.background = '#fff6e1'; }
247
+ else { label.textContent = 'Riesgo Alto'; label.style.background = '#ffe9e9'; }
248
+
249
+ // Guardar datos para el análisis IA
250
+ window.finalData = {
251
+ overall: global,
252
+ domains: DOMAINS.map(d => ({
253
+ name: d.name,
254
+ score: Math.round(avg(answers[d.id]))
255
+ }))
256
+ };
257
+ }
258
+
259
+ /* === DESCARGAR INFORME MEJORADO === */
260
+ function downloadReport() {
261
+ const global = window.finalData.overall;
262
+ const date = new Date().toLocaleDateString('es-ES');
263
+
264
+ // Crear contenido con formato profesional
265
+ const content = `
266
+ ╔══════════════════════════════════════════════════╗
267
+ ║ INFORME DE CIBERSEGURIDAD ║
268
+ ║ DOCTOR LINUX ║
269
+ ╚══════════════════════════════════════════════════╝
270
+
271
+ 📅 Fecha de evaluación: ${date}
272
+ 🎯 Puntaje Global: ${global}%
273
+
274
+ ${global >= 80 ? '✅ POSTURA SÓLIDA - Controles robustos implementados' :
275
+ global >= 60 ? '⚠️ MEJORAS NECESARIAS - Se requieren ajustes en controles' :
276
+ '🚨 RIESGO ELEVADO - Atención inmediata requerida'}
277
+
278
+ 📊 DETALLE POR DOMINIO TÉCNICO:
279
+ ${window.finalData.domains.map(d => {
280
+ const icon = d.score >= 80 ? '✅' : d.score >= 60 ? '⚠️ ' : '🚨';
281
+ return `${icon} ${d.name}: ${d.score}%`;
282
+ }).join('\n')}
283
+
284
+ 🛠️ RECOMENDACIONES PRIORITARIAS:
285
+ 1. Revisar y endurecer configuración de firewall
286
+ 2. Implementar estrategia de backups 3-2-1 con pruebas
287
+ 3. Establecer monitoreo centralizado 24/7
288
+ 4. Aplicar hardening en servidores y estaciones
289
+ 5. Implementar autenticación multifactor (MFA)
290
+
291
+ 📈 PLAN DE ACCIÓN SUGERIDO:
292
+ • SEMANA 1: Contención de riesgos críticos
293
+ • SEMANA 2-4: Implementación controles básicos
294
+ • MES 2-3: Mejora de madurez operacional
295
+ • MES 4-6: Optimización y automatización
296
+
297
+ ──────────────────────────────────────────────────
298
+ Este es un informe automático generado por la
299
+ herramienta de autodiagnóstico de Doctor Linux.
300
+
301
+ Para un análisis técnico detallado y personalizado,
302
+ contacte a nuestros especialistas:
303
+
304
+ 🌐 www.doctorlinux.com
305
+ 📧 gerencia@doctorlinux.com
306
+ 📞 +57 300 123 4567
307
+ ──────────────────────────────────────────────────
308
+ `;
309
+
310
+ // Crear y descargar archivo
311
+ const blob = new Blob([content], { type: 'text/plain; charset=utf-8' });
312
+ const url = URL.createObjectURL(blob);
313
+ const a = document.createElement('a');
314
+ a.href = url;
315
+ a.download = `informe-ciberseguridad-doctor-linux-${date.replace(/\//g, '-')}.txt`;
316
+ document.body.appendChild(a);
317
+ a.click();
318
+ document.body.removeChild(a);
319
+ URL.revokeObjectURL(url);
320
+ }
321
+
322
+ /* === ANÁLISIS CON IA === */
323
+ document.getElementById('analyzeBtn').onclick = async function() {
324
+ const box = document.getElementById('iaBox');
325
+ const out = document.getElementById('iaOutput');
326
+ const btn = this;
327
+
328
+ box.style.display = 'block';
329
+ out.textContent = 'Generando análisis detallado...';
330
+ btn.disabled = true;
331
+
332
+ try {
333
+ const res = await fetch('/analyze', {
334
+ method: 'POST',
335
+ headers: {'Content-Type': 'application/json'},
336
+ body: JSON.stringify(window.finalData)
337
+ });
338
+
339
+ if (res.ok) {
340
+ const data = await res.json();
341
+ out.textContent = data.analysis || 'Análisis completado.';
342
+ } else {
343
+ throw new Error('Error del servidor');
344
+ }
345
+ } catch (error) {
346
+ out.textContent = 'El análisis detallado no está disponible en este momento.\n\nPuntaje: ' + window.finalData.overall + '%\n\nPara un diagnóstico completo, contacta a Doctor Linux.';
347
+ } finally {
348
+ btn.disabled = false;
349
+ }
350
+ };
351
+
352
+ // Inicializar aplicación
353
+ render();
354
+ </script>
355
  </body>
356
  </html>