utn-cli 2.1.54 → 2.1.55

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 (40) hide show
  1. package/package.json +1 -1
  2. package/templates/backend/package.json +3 -3
  3. package/templates/backend/rutas/DatosMiscelaneos.js +50 -0
  4. package/templates/backend/rutas/misc.js +177 -5
  5. package/templates/backend/rutas/rutas.js +2 -0
  6. package/templates/backend/servicios/Nucleo/DatosMiscelaneos.js +36 -0
  7. package/templates/backend/servicios/Nucleo/Miscelaneas.js +192 -25
  8. package/templates/frontend/Dockerfile +1 -0
  9. package/templates/frontend/src/app/Componentes/Nucleo/boton-ayuda/boton-ayuda.component.css +7 -0
  10. package/templates/frontend/src/app/Componentes/Nucleo/boton-ayuda/boton-ayuda.component.html +28 -0
  11. package/templates/frontend/src/app/Componentes/Nucleo/boton-ayuda/boton-ayuda.component.ts +78 -0
  12. package/templates/frontend/src/app/Componentes/Nucleo/estadisticas-del-modulo/estadisticas-del-modulo.component.html +43 -8
  13. package/templates/frontend/src/app/Componentes/Nucleo/estadisticas-del-modulo/estadisticas-del-modulo.component.ts +5 -4
  14. package/templates/frontend/src/app/Componentes/Nucleo/gestion-actividad/gestion-actividad.component.ts +1 -0
  15. package/templates/frontend/src/app/Componentes/Nucleo/mensaje-confirmacion/mensaje-confirmacion.component.css +4 -2
  16. package/templates/frontend/src/app/Componentes/Nucleo/mensaje-institucional/mensaje-institucional.component.html +3 -3
  17. package/templates/frontend/src/app/Componentes/Nucleo/mensaje-institucional/mensaje-institucional.component.ts +1 -1
  18. package/templates/frontend/src/app/Componentes/Nucleo/subir-archivo/subir-archivo.component.ts +1 -1
  19. package/templates/frontend/src/app/Paginas/Nucleo/accesibilidad/accesibilidad.component.css +25 -0
  20. package/templates/frontend/src/app/Paginas/Nucleo/accesibilidad/accesibilidad.component.html +2 -0
  21. package/templates/frontend/src/app/Paginas/Nucleo/accesibilidad/accesibilidad.component.ts +31 -2
  22. package/templates/frontend/src/app/Paginas/Nucleo/acercade/acercade.component.css +67 -18
  23. package/templates/frontend/src/app/Paginas/Nucleo/acercade/acercade.component.html +56 -46
  24. package/templates/frontend/src/app/Paginas/Nucleo/acercade/acercade.component.ts +21 -1
  25. package/templates/frontend/src/app/Paginas/Nucleo/conozcanos/conozcanos.component.css +190 -375
  26. package/templates/frontend/src/app/Paginas/Nucleo/conozcanos/conozcanos.component.html +92 -91
  27. package/templates/frontend/src/app/Paginas/Nucleo/conozcanos/conozcanos.component.ts +19 -2
  28. package/templates/frontend/src/app/Paginas/Nucleo/contenedor-componentes/contenedor-componentes.component.ts +2 -2
  29. package/templates/frontend/src/app/Paginas/Nucleo/declaracion-ia/declaracion-ia.component.css +25 -0
  30. package/templates/frontend/src/app/Paginas/Nucleo/declaracion-ia/declaracion-ia.component.html +2 -0
  31. package/templates/frontend/src/app/Paginas/Nucleo/declaracion-ia/declaracion-ia.component.ts +33 -3
  32. package/templates/frontend/src/app/Paginas/Nucleo/politicas/politicas.component.css +69 -15
  33. package/templates/frontend/src/app/Paginas/Nucleo/politicas/politicas.component.html +129 -107
  34. package/templates/frontend/src/app/Paginas/Nucleo/politicas/politicas.component.ts +51 -9
  35. package/templates/frontend/src/app/Paginas/Nucleo/preguntasFrecuentes/preguntasFrecuentes.component.css +68 -15
  36. package/templates/frontend/src/app/Paginas/Nucleo/preguntasFrecuentes/preguntasFrecuentes.component.html +161 -88
  37. package/templates/frontend/src/app/Paginas/Nucleo/preguntasFrecuentes/preguntasFrecuentes.component.ts +63 -10
  38. package/templates/frontend/src/app/Paginas/Nucleo/sabiasque/sabiasque.component.css +100 -24
  39. package/templates/frontend/src/app/Paginas/Nucleo/sabiasque/sabiasque.component.html +269 -339
  40. package/templates/frontend/src/app/Paginas/Nucleo/sabiasque/sabiasque.component.ts +94 -6
@@ -1,109 +1,110 @@
1
- <div class="subtitle">
2
- <p>Conózcanos</p>
3
- </div>
4
- <div class="conozcanos-container">
5
- <div class="conozcanos-content">
6
- <div class="conozcanos-text">
7
- <p>Somos el equipo profesional de TI de la Universidad Técnica Nacional, encargados del desarrollo y codificación
8
- de herramientas que faciliten a toda la comunidad universitaria y al usuario en general que utilicen el sistema.
9
- Somos los encargados del desarrollo de la plataforma SIGU.</p>
10
- <p>Somos la unidad encargada del diseño, desarrollo, mantenimiento y soporte del Sistema Integrado de Gestión
11
- Universitaria (SIGU).</p>
12
- </div>
13
- <div class="conozcanos-image">
14
- <img src="conozcanos1.jpg" alt="Equipo SIGU">
15
- </div>
16
- </div>
17
- <!-- Sección Propósito -->
18
- <div class="proposito-section">
19
- <div class="proposito-header">
20
- <h2 class="proposito-title">Propósito del equipo</h2>
21
- </div>
22
- <div class="proposito-text">
23
- <p>Trabajamos diariamente para asegurar que la plataforma sea una herramienta accesible, segura y eficiente,
24
- facilitando la gestión académica y administrativa en cada una de sus etapas.</p>
25
- <p>Un equipo capacitado y en mejora constante, que realmente se involucra en la calidad y seguridad de cada
26
- sistema desarrollado. Aportando funciones claves como:</p>
27
- </div>
28
- <div class="proposito-grid">
29
- <div class="proposito-card">
30
- <div class="card-header">
31
- <span class="card-icon">+</span>
32
- <h3>Innovación</h3>
33
- </div>
34
- <p>El desarrollo de nuevas herramientas y actualizaciones.</p>
1
+ <div class="ia-layout">
2
+ <main class="ia-main">
3
+
4
+ <header class="ia-encabezado">
5
+ <mat-icon class="ia-icono-header">groups</mat-icon>
6
+ <div>
7
+ <h1>Conózcanos</h1>
35
8
  </div>
36
- <div class="proposito-card">
37
- <div class="card-header">
38
- <span class="card-icon">+</span>
39
- <h3>Soporte técnico y acompañamiento</h3>
9
+ </header>
10
+
11
+ <!-- Intro + Propósito (vista principal) -->
12
+ <div class="conozcanos-intro">
13
+ <div class="conozcanos-content">
14
+ <div class="conozcanos-text">
15
+ <p>Somos la unidad encargada del diseño, desarrollo, mantenimiento y soporte del Sistema Integrado de Gestión
16
+ Universitaria (SIGU).</p>
17
+ <p>El equipo profesional de TI de la Universidad Técnica Nacional tiene como misión desarrollar soluciones
18
+ tecnológicas que mejoren la experiencia de gestión de la comunidad universitaria y del usuario general.</p>
19
+ </div>
20
+ <div class="conozcanos-image">
21
+ <img src="conozcanos1.jpg" alt="Equipo SIGU">
40
22
  </div>
41
- <p>Resolución de problemas técnicos y atención a usuarios.</p>
42
23
  </div>
43
- <div class="proposito-card">
44
- <div class="card-header">
45
- <span class="card-icon">+</span>
46
- <h3>Seguridad</h3>
24
+
25
+ <div class="proposito-section">
26
+ <h2 class="proposito-title">Propósito del equipo</h2>
27
+ <div class="proposito-grid">
28
+ <div class="proposito-card">
29
+ <div class="card-header">
30
+ <span class="card-icon">+</span>
31
+ <h3>Soporte técnico</h3>
32
+ </div>
33
+ <p>Resolución de problemas técnicos y atención a usuarios.</p>
34
+ </div>
35
+ <div class="proposito-card">
36
+ <div class="card-header">
37
+ <span class="card-icon">+</span>
38
+ <h3>Soporte y acompañamiento</h3>
39
+ </div>
40
+ <p>Acompañamiento continuo a los usuarios del sistema.</p>
41
+ </div>
42
+ <div class="proposito-card">
43
+ <div class="card-header">
44
+ <span class="card-icon">+</span>
45
+ <h3>Seguridad</h3>
46
+ </div>
47
+ <p>Garantizamos la seguridad de la información de cada uno de los usuarios.</p>
48
+ </div>
47
49
  </div>
48
- <p>Garantizamos la seguridad de la información de cada uno de los usuarios.</p>
49
50
  </div>
50
51
  </div>
51
- </div>
52
52
 
53
- <div class="Liderazgo-container" *ngIf="desarrolladorLider">
54
- <div class="Liderazgo-content">
53
+ <!-- Equipo de trabajo (contenedor separado, scroll) -->
54
+ <div class="team-wrapper">
55
55
 
56
- <div class="Liderazgo-header">
57
- <h2 class="Liderazgo-title">Dirección y liderazgo técnico</h2>
58
- </div>
59
-
60
- <div class="Liderazgo-body">
61
- <div class="Liderazgo-image">
62
- <img [src]="desarrolladorLider.FotoURL || 'conozcanos2.png'" [alt]="desarrolladorLider.NombreCompleto">
56
+ <div class="Liderazgo-content" *ngIf="desarrolladorLider">
57
+ <div class="Liderazgo-header">
58
+ <h2 class="Liderazgo-title">Dirección y liderazgo técnico</h2>
63
59
  </div>
64
-
65
- <div class="Liderazgo-text">
66
- <p class="name">{{ desarrolladorLider.NombreCompleto }}</p>
67
- <p class="cargo">Líder del equipo técnico</p>
68
- <p>{{desarrolladorLider.Biografia}}</p>
60
+ <div class="Liderazgo-body">
61
+ <div class="Liderazgo-image">
62
+ <img [src]="desarrolladorLider.FotoURL || 'conozcanos2.png'" [alt]="desarrolladorLider.NombreCompleto">
63
+ </div>
64
+ <div class="Liderazgo-text">
65
+ <p class="name">{{ desarrolladorLider.NombreCompleto }}</p>
66
+ <p class="cargo">Líder del equipo técnico</p>
67
+ <p>{{desarrolladorLider.Biografia}}</p>
68
+ </div>
69
69
  </div>
70
70
  </div>
71
- </div>
72
- </div>
73
71
 
74
- <!-- Team work -->
75
- <div class="team-section">
76
- <div class="team-header">
77
- <h2 class="team-title">Equipo de trabajo</h2>
78
- </div>
79
- <div class="team-text">
80
- <p>Nuestro equipo de trabajo y de desarrollo del SIGU es un grupo pequeño pero capacitado que garantiza la
81
- evolución, creación y seguridad. A continuación se muestra nuestro equipo.</p>
82
- </div>
83
-
84
- <div class="team-grid">
85
- <div *ngFor="let desarrollador of datosDesarrolladores; let i = index" class="team-card">
86
- <div class="team-card-inner">
87
- <div class="team-front">
88
- <div class="team-photo">
89
- <img [src]="desarrollador.FotoURL || 'Avatar=45.png'"
90
- [alt]="desarrollador.NombreCompleto || 'Miembro del equipo'">
72
+ <div class="team-section">
73
+ <div class="team-header">
74
+ <h2 class="team-title">Equipo de trabajo</h2>
75
+ </div>
76
+ <div class="team-text">
77
+ <p>Nuestro equipo de trabajo y de desarrollo del SIGU es un grupo pequeño pero capacitado que garantiza la
78
+ evolución, creación y seguridad. A continuación se muestra nuestro equipo.</p>
79
+ </div>
80
+ <div class="team-grid">
81
+ <div *ngFor="let desarrollador of datosDesarrolladores; let i = index" class="team-card">
82
+ <div class="team-card-inner">
83
+ <div class="team-front">
84
+ <div class="team-photo">
85
+ <img [src]="desarrollador.FotoURL || 'Avatar=45.png'"
86
+ [alt]="desarrollador.NombreCompleto || 'Miembro del equipo'">
87
+ </div>
88
+ <h3 class="team-name">{{ desarrollador.NombreCompleto || 'Miembro ' + (i+1) }}</h3>
89
+ <p class="team-position">{{ desarrollador.Perfil }}</p>
90
+ <button class="team-btn" (click)="flipCard($event)">
91
+ Ver más
92
+ </button>
93
+ </div>
94
+ <div class="team-back">
95
+ <p>{{ desarrollador.Biografia || 'Sin biografía disponible.' }}</p>
96
+ <button class="team-btn" (click)="flipCard($event)">
97
+ Volver
98
+ </button>
99
+ </div>
91
100
  </div>
92
- <h3 class="team-name">{{ desarrollador.NombreCompleto || 'Miembro ' + (i+1) }}</h3>
93
- <p class="team-position">Desarrollador</p>
94
- <button class="team-btn" (click)="flipCard($event)">
95
- Ver más
96
- </button>
97
- </div>
98
- <div class="team-back">
99
- <p>{{ desarrollador.Biografia || 'Sin biografía disponible.' }}</p>
100
- <button class="team-btn" (click)="flipCard($event)">
101
- Volver
102
- </button>
103
101
  </div>
104
102
  </div>
105
103
  </div>
104
+
106
105
  </div>
107
106
 
108
- </div>
109
- </div>
107
+ <button *ngIf="mostrarBotonInicio" class="btn-volver-arriba" (click)="irAlInicio()" title="Volver arriba">↑ Volver arriba</button>
108
+
109
+ </main>
110
+ </div>
@@ -17,6 +17,8 @@ export class ConozcanosComponent implements OnInit {
17
17
  public cargando: boolean = true;
18
18
  public desarrolladorLider: any = null;
19
19
  private _destroy$ = new Subject<void>();
20
+ mostrarBotonInicio = false;
21
+ private _scrollListener?: EventListener;
20
22
 
21
23
  constructor(private http: HttpClient, private datosGlobalesService: DatosGlobalesService) { }
22
24
 
@@ -24,14 +26,24 @@ export class ConozcanosComponent implements OnInit {
24
26
  ngOnInit(): void {
25
27
  this.http.get(`${this.datosGlobalesService.ObtenerURL()}misc/VistaDeConozcanos`).pipe(takeUntil(this._destroy$)).subscribe({ error: () => { } });
26
28
  this.obtenerDesarrolladores();
29
+ setTimeout(() => {
30
+ const c = document.querySelector('.zona-scrollable');
31
+ if (c) {
32
+ this._scrollListener = () => { this.mostrarBotonInicio = (c as HTMLElement).scrollTop > 200; };
33
+ c.addEventListener('scroll', this._scrollListener);
34
+ }
35
+ }, 0);
36
+ }
37
+
38
+ ngOnDestroy(): void {
39
+ this._destroy$.next(); this._destroy$.complete();
40
+ if (this._scrollListener) { document.querySelector('.zona-scrollable')?.removeEventListener('scroll', this._scrollListener); }
27
41
  }
28
42
 
29
43
  obtenerDesarrolladores(): void {
30
44
  this.cargando = true;
31
45
  this.http.get(`${this.datosGlobalesService.ObtenerURL()}misc/obtenerEquipoDeDesarrolladores`).subscribe({
32
46
  next: (respuesta: any) => {
33
- console.log('Respuesta equipo:', respuesta);
34
-
35
47
  if (respuesta.error) {
36
48
  console.error('Problemas:', respuesta.error);
37
49
  this.cargando = false;
@@ -59,5 +71,10 @@ export class ConozcanosComponent implements OnInit {
59
71
  card.classList.toggle('flipped');
60
72
  }
61
73
  }
74
+ irAlInicio(): void {
75
+ const contenedor = document.querySelector('.zona-scrollable');
76
+ if (contenedor) { contenedor.scrollTo({ top: 0, behavior: 'smooth' }); this.mostrarBotonInicio = false; }
77
+ else { window.scrollTo({ top: 0, behavior: 'smooth' }); }
78
+ }
62
79
  }
63
80
 
@@ -56,7 +56,7 @@ export class ContenedorComponentesComponent implements OnInit, OnDestroy, AfterV
56
56
  return this.itemsDeMenu.filter(i => !i.requierePermiso || this.TienePermiso);
57
57
  }
58
58
 
59
- get esDashboard(): boolean { return window.location.hostname.includes('portalv2-frontend'); }
59
+ get esDashboard(): boolean { return window.location.pathname === '/'; }
60
60
 
61
61
  toggleSidebar(): void {
62
62
  const abriendo = !this.datosGlobalesService.sidebarVisible$.value;
@@ -104,7 +104,7 @@ export class ContenedorComponentesComponent implements OnInit, OnDestroy, AfterV
104
104
  { id: 'nav_estadisticas', etiqueta: 'Estadísticas del módulo', icono: 'bar_chart', accion: () => this.irAEstadisticasDelModulo(), requierePermiso: true, posicion: 30 },
105
105
  { id: 'nav_accesibilidad', etiqueta: 'Accesibilidad', icono: 'accessibility', accion: () => this.irAAccesibilidad(), requierePermiso: false, posicion: 40 },
106
106
  { id: 'nav_declaracion_ia', etiqueta: 'Declaración de IA', icono: 'smart_toy', accion: () => this.irADeclaracionIA(), requierePermiso: false, posicion: 50 },
107
- { id: 'nav_politicas', etiqueta: 'Políticas de seguridad', icono: 'security', accion: () => this.irAPoliticas(), requierePermiso: false, posicion: 50 },
107
+ { id: 'nav_politicas', etiqueta: 'Política de seguridad', icono: 'security', accion: () => this.irAPoliticas(), requierePermiso: false, posicion: 50 },
108
108
  { id: 'nav_acercade', etiqueta: 'Acerca de', icono: 'info', accion: () => this.irAAcercaDe(), requierePermiso: false, posicion: 50 },
109
109
  { id: 'nav_conozcanos', etiqueta: 'Conózcanos', icono: 'groups', accion: () => this.irAConozcanos(), requierePermiso: false, posicion: 50 },
110
110
  { id: 'nav_sabias_que', etiqueta: 'Sabías qué', icono: 'lightbulb', accion: () => this.irASabiasQue(), requierePermiso: false, posicion: 50 },
@@ -147,3 +147,28 @@
147
147
  gap: 10px;
148
148
  }
149
149
  }
150
+
151
+
152
+ /* Botón volver arriba */
153
+ .btn-volver-arriba {
154
+ display: none;
155
+ }
156
+
157
+ @media (max-width: 768px) {
158
+ .btn-volver-arriba {
159
+ display: flex;
160
+ align-items: center;
161
+ justify-content: center;
162
+ margin: 2rem auto 1rem;
163
+ padding: 0.6rem 1.4rem;
164
+ background: linear-gradient(90deg, rgba(1, 33, 105, 1) 0%, rgba(63, 97, 171, 1) 100%);
165
+ color: white;
166
+ border: none;
167
+ border-radius: 24px;
168
+ font-family: 'Roboto', sans-serif;
169
+ font-size: 0.9rem;
170
+ font-weight: 500;
171
+ cursor: pointer;
172
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
173
+ }
174
+ }
@@ -65,5 +65,7 @@
65
65
  <span>Declaración vigente a partir del 19 de mayo de 2026. Universidad Técnica Nacional.</span>
66
66
  </footer>
67
67
 
68
+ <button *ngIf="mostrarBotonInicio" class="btn-volver-arriba" (click)="irAlInicio()" title="Volver arriba">↑ Volver arriba</button>
69
+
68
70
  </main>
69
71
  </div>
@@ -1,11 +1,41 @@
1
- import { Component } from '@angular/core';
1
+ import { Component, OnInit } from '@angular/core';
2
2
  import { MatIconModule } from '@angular/material/icon';
3
+ import { CommonModule } from '@angular/common';
4
+ import { HttpClient } from '@angular/common/http';
5
+ import { DatosGlobalesService } from '../../../datos-globales.service';
6
+ import { Subject } from 'rxjs';
7
+ import { takeUntil } from 'rxjs/operators';
3
8
 
4
9
  @Component({
5
10
  selector: 'app-declaracion-ia',
6
11
  standalone: true,
7
- imports: [MatIconModule],
12
+ imports: [MatIconModule, CommonModule],
8
13
  templateUrl: './declaracion-ia.component.html',
9
14
  styleUrl: './declaracion-ia.component.css'
10
15
  })
11
- export class DeclaracionIaComponent { }
16
+ export class DeclaracionIaComponent implements OnInit {
17
+ private _destroy$ = new Subject<void>();
18
+ mostrarBotonInicio = false;
19
+ private _scrollListener?: EventListener;
20
+
21
+ constructor(private http: HttpClient, private datosGlobalesService: DatosGlobalesService) { }
22
+ ngOnInit(): void {
23
+ this.http.get(`${this.datosGlobalesService.ObtenerURL()}misc/VistaDeDeclaracionIA`).pipe(takeUntil(this._destroy$)).subscribe({ error: () => { } });
24
+ setTimeout(() => {
25
+ const c = document.querySelector('.zona-scrollable');
26
+ if (c) {
27
+ this._scrollListener = () => { this.mostrarBotonInicio = (c as HTMLElement).scrollTop > 200; };
28
+ c.addEventListener('scroll', this._scrollListener);
29
+ }
30
+ }, 0);
31
+ }
32
+ ngOnDestroy(): void {
33
+ this._destroy$.next(); this._destroy$.complete();
34
+ if (this._scrollListener) { document.querySelector('.zona-scrollable')?.removeEventListener('scroll', this._scrollListener); }
35
+ }
36
+ irAlInicio(): void {
37
+ const contenedor = document.querySelector('.zona-scrollable');
38
+ if (contenedor) { contenedor.scrollTo({ top: 0, behavior: 'smooth' }); this.mostrarBotonInicio = false; }
39
+ else { window.scrollTo({ top: 0, behavior: 'smooth' }); }
40
+ }
41
+ }
@@ -1,22 +1,52 @@
1
- .politicas-container {
2
- max-width: 1000px;
3
- padding-bottom: 20px;
4
- font-family: 'Roboto', sans-serif;
5
- background-color: white;
6
- text-align: left;
1
+ .ia-layout {
2
+ max-width: 820px;
7
3
  margin: 0 auto;
4
+ padding: 24px 16px;
5
+ font-family: 'Roboto', sans-serif;
6
+ }
7
+
8
+ .ia-main {
9
+ display: flex;
10
+ flex-direction: column;
11
+ gap: 28px;
8
12
  }
9
13
 
10
- .subtitle {
11
- background-color: #0b4794;
12
- font-size: 25px;
14
+ .ia-encabezado {
15
+ display: flex;
16
+ align-items: center;
17
+ gap: 14px;
18
+ padding: 20px 24px;
19
+ background: linear-gradient(90deg, rgba(1, 33, 105, 1) 0%, rgba(63, 97, 171, 1) 100%);
13
20
  color: white;
14
- padding: 18px;
15
- margin: 20px 0;
16
- text-align: center;
21
+ border-radius: 12px;
22
+ }
23
+
24
+ .ia-icono-header {
25
+ font-size: 40px !important;
26
+ width: 40px !important;
27
+ height: 40px !important;
28
+ flex-shrink: 0;
29
+ opacity: 0.9;
17
30
  }
18
- .subtitle p {
19
- margin: 5px 0;
31
+
32
+ .ia-encabezado h1 {
33
+ margin: 0;
34
+ font-size: 22px;
35
+ font-weight: 700;
36
+ line-height: 1.2;
37
+ }
38
+
39
+ .ia-seccion {
40
+ background: white;
41
+ border: 1px solid #d0daea;
42
+ border-radius: 10px;
43
+ padding: 20px 24px;
44
+ }
45
+
46
+ .ia-seccion .tree-container {
47
+ padding-left: 0;
48
+ padding-right: 0;
49
+ margin-top: 0;
20
50
  }
21
51
  .description {
22
52
  width: 100%;
@@ -155,4 +185,28 @@
155
185
  .tree-content li{
156
186
  font-size: 14px;
157
187
  }
158
- }
188
+ }
189
+
190
+ /* Botón volver arriba */
191
+ .btn-volver-arriba {
192
+ display: none;
193
+ }
194
+
195
+ @media (max-width: 768px) {
196
+ .btn-volver-arriba {
197
+ display: flex;
198
+ align-items: center;
199
+ justify-content: center;
200
+ margin: 2rem auto 1rem;
201
+ padding: 0.6rem 1.4rem;
202
+ background: linear-gradient(90deg, rgba(1, 33, 105, 1) 0%, rgba(63, 97, 171, 1) 100%);
203
+ color: white;
204
+ border: none;
205
+ border-radius: 24px;
206
+ font-family: 'Roboto', sans-serif;
207
+ font-size: 0.9rem;
208
+ font-weight: 500;
209
+ cursor: pointer;
210
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
211
+ }
212
+ }