@lluc_llull/ui-lib 0.4.4 → 0.5.0

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 (25) hide show
  1. package/esm2022/lib/components/core/category-progress/category-progress.component.mjs +3 -3
  2. package/esm2022/lib/components/core/header-clear/header-clear.component.mjs +26 -6
  3. package/esm2022/lib/components/core/header-clear/header-clear.interface.mjs +1 -1
  4. package/esm2022/lib/components/core/header-mobile/header-mobile.component.mjs +26 -6
  5. package/esm2022/lib/components/core/header-mobile/header-mobile.interface.mjs +1 -1
  6. package/esm2022/lib/components/core/hero-section/hero-section.component.mjs +3 -3
  7. package/esm2022/lib/components/core/lang-modal/lang-modal.component.mjs +3 -3
  8. package/esm2022/lib/components/core/nav-modal/nav-modal.component.mjs +3 -3
  9. package/esm2022/lib/components/core/section-intro/section-intro.component.mjs +3 -3
  10. package/esm2022/lib/services/index.mjs +2 -1
  11. package/esm2022/lib/services/mapper/component-mappers/header-clear.mapper.mjs +4 -2
  12. package/esm2022/lib/services/theme/index.mjs +2 -0
  13. package/esm2022/lib/services/theme/theme.service.mjs +73 -0
  14. package/fesm2022/lluc_llull-ui-lib.mjs +130 -23
  15. package/fesm2022/lluc_llull-ui-lib.mjs.map +1 -1
  16. package/lib/components/core/header-clear/header-clear.component.d.ts +14 -3
  17. package/lib/components/core/header-clear/header-clear.interface.d.ts +3 -0
  18. package/lib/components/core/header-mobile/header-mobile.component.d.ts +15 -4
  19. package/lib/components/core/header-mobile/header-mobile.interface.d.ts +3 -0
  20. package/lib/services/index.d.ts +1 -0
  21. package/lib/services/theme/index.d.ts +1 -0
  22. package/lib/services/theme/theme.service.d.ts +16 -0
  23. package/package.json +1 -1
  24. package/src/lib/styles/main.css +63 -13
  25. package/styles/main.css +63 -13
@@ -0,0 +1,73 @@
1
+ import { isPlatformBrowser } from '@angular/common';
2
+ import { Inject, Injectable, PLATFORM_ID } from '@angular/core';
3
+ import { BehaviorSubject } from 'rxjs';
4
+ import * as i0 from "@angular/core";
5
+ export class ThemeService {
6
+ constructor(platformId) {
7
+ this.platformId = platformId;
8
+ this.currentThemeSubject = new BehaviorSubject('light');
9
+ this.currentTheme$ = this.currentThemeSubject.asObservable();
10
+ // Aplicar tema por defecto al inicio
11
+ if (isPlatformBrowser(this.platformId)) {
12
+ this.applyTheme('light');
13
+ }
14
+ }
15
+ getCurrentTheme() {
16
+ return this.currentThemeSubject.value;
17
+ }
18
+ setTheme(theme) {
19
+ this.currentThemeSubject.next(theme);
20
+ this.applyTheme(theme);
21
+ // NO guardar automáticamente en localStorage - solo cuando el usuario hace toggle
22
+ }
23
+ toggleTheme() {
24
+ const currentTheme = this.getCurrentTheme();
25
+ const newTheme = currentTheme === 'light' ? 'dark' : 'light';
26
+ // Guardar en localStorage solo cuando el usuario hace toggle
27
+ if (isPlatformBrowser(this.platformId)) {
28
+ localStorage.setItem('theme', newTheme);
29
+ }
30
+ this.setTheme(newTheme);
31
+ }
32
+ resetTheme() {
33
+ if (isPlatformBrowser(this.platformId)) {
34
+ localStorage.removeItem('theme');
35
+ this.currentThemeSubject.next('light');
36
+ this.applyTheme('light');
37
+ }
38
+ }
39
+ // Método para cargar el tema guardado (opcional)
40
+ loadSavedTheme() {
41
+ if (isPlatformBrowser(this.platformId)) {
42
+ const savedTheme = localStorage.getItem('theme');
43
+ if (savedTheme) {
44
+ this.setTheme(savedTheme);
45
+ }
46
+ }
47
+ }
48
+ applyTheme(theme) {
49
+ // Solo aplicar en el navegador
50
+ if (!isPlatformBrowser(this.platformId)) {
51
+ return;
52
+ }
53
+ const root = document.documentElement;
54
+ if (theme === 'dark') {
55
+ root.setAttribute('data-theme', 'dark');
56
+ }
57
+ else {
58
+ root.setAttribute('data-theme', 'light');
59
+ }
60
+ }
61
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ThemeService, deps: [{ token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Injectable }); }
62
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ThemeService, providedIn: 'root' }); }
63
+ }
64
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ThemeService, decorators: [{
65
+ type: Injectable,
66
+ args: [{
67
+ providedIn: 'root'
68
+ }]
69
+ }], ctorParameters: () => [{ type: Object, decorators: [{
70
+ type: Inject,
71
+ args: [PLATFORM_ID]
72
+ }] }] });
73
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGhlbWUuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3VpLWxpYi9zcmMvbGliL3NlcnZpY2VzL3RoZW1lL3RoZW1lLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDcEQsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxNQUFNLENBQUM7O0FBT3ZDLE1BQU0sT0FBTyxZQUFZO0lBSXZCLFlBQXlDLFVBQWtCO1FBQWxCLGVBQVUsR0FBVixVQUFVLENBQVE7UUFIbkQsd0JBQW1CLEdBQUcsSUFBSSxlQUFlLENBQVEsT0FBTyxDQUFDLENBQUM7UUFDM0Qsa0JBQWEsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsWUFBWSxFQUFFLENBQUM7UUFHN0QscUNBQXFDO1FBQ3JDLElBQUksaUJBQWlCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDdkMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMzQixDQUFDO0lBQ0gsQ0FBQztJQUVNLGVBQWU7UUFDcEIsT0FBTyxJQUFJLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDO0lBQ3hDLENBQUM7SUFFTSxRQUFRLENBQUMsS0FBWTtRQUMxQixJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDdkIsa0ZBQWtGO0lBQ3BGLENBQUM7SUFFTSxXQUFXO1FBQ2hCLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUM1QyxNQUFNLFFBQVEsR0FBVSxZQUFZLEtBQUssT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUVwRSw2REFBNkQ7UUFDN0QsSUFBSSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztZQUN2QyxZQUFZLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztRQUMxQyxDQUFDO1FBRUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUMxQixDQUFDO0lBRU0sVUFBVTtRQUNmLElBQUksaUJBQWlCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDdkMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNqQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3ZDLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDM0IsQ0FBQztJQUNILENBQUM7SUFFRCxpREFBaUQ7SUFDMUMsY0FBYztRQUNuQixJQUFJLGlCQUFpQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQ3ZDLE1BQU0sVUFBVSxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFVLENBQUM7WUFDMUQsSUFBSSxVQUFVLEVBQUUsQ0FBQztnQkFDZixJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQzVCLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVPLFVBQVUsQ0FBQyxLQUFZO1FBQzdCLCtCQUErQjtRQUMvQixJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDeEMsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsZUFBZSxDQUFDO1FBRXRDLElBQUksS0FBSyxLQUFLLE1BQU0sRUFBRSxDQUFDO1lBQ3JCLElBQUksQ0FBQyxZQUFZLENBQUMsWUFBWSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQzFDLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLFlBQVksQ0FBQyxZQUFZLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDM0MsQ0FBQztJQUNILENBQUM7K0dBaEVVLFlBQVksa0JBSUgsV0FBVzttSEFKcEIsWUFBWSxjQUZYLE1BQU07OzRGQUVQLFlBQVk7a0JBSHhCLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25COzswQkFLYyxNQUFNOzJCQUFDLFdBQVciLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpc1BsYXRmb3JtQnJvd3NlciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUsIFBMQVRGT1JNX0lEIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QgfSBmcm9tICdyeGpzJztcblxuZXhwb3J0IHR5cGUgVGhlbWUgPSAnbGlnaHQnIHwgJ2RhcmsnO1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBUaGVtZVNlcnZpY2Uge1xuICBwcml2YXRlIGN1cnJlbnRUaGVtZVN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFRoZW1lPignbGlnaHQnKTtcbiAgcHVibGljIGN1cnJlbnRUaGVtZSQgPSB0aGlzLmN1cnJlbnRUaGVtZVN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG5cbiAgY29uc3RydWN0b3IoQEluamVjdChQTEFURk9STV9JRCkgcHJpdmF0ZSBwbGF0Zm9ybUlkOiBPYmplY3QpIHtcbiAgICAvLyBBcGxpY2FyIHRlbWEgcG9yIGRlZmVjdG8gYWwgaW5pY2lvXG4gICAgaWYgKGlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCkpIHtcbiAgICAgIHRoaXMuYXBwbHlUaGVtZSgnbGlnaHQnKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZ2V0Q3VycmVudFRoZW1lKCk6IFRoZW1lIHtcbiAgICByZXR1cm4gdGhpcy5jdXJyZW50VGhlbWVTdWJqZWN0LnZhbHVlO1xuICB9XG5cbiAgcHVibGljIHNldFRoZW1lKHRoZW1lOiBUaGVtZSk6IHZvaWQge1xuICAgIHRoaXMuY3VycmVudFRoZW1lU3ViamVjdC5uZXh0KHRoZW1lKTtcbiAgICB0aGlzLmFwcGx5VGhlbWUodGhlbWUpO1xuICAgIC8vIE5PIGd1YXJkYXIgYXV0b23DoXRpY2FtZW50ZSBlbiBsb2NhbFN0b3JhZ2UgLSBzb2xvIGN1YW5kbyBlbCB1c3VhcmlvIGhhY2UgdG9nZ2xlXG4gIH1cblxuICBwdWJsaWMgdG9nZ2xlVGhlbWUoKTogdm9pZCB7XG4gICAgY29uc3QgY3VycmVudFRoZW1lID0gdGhpcy5nZXRDdXJyZW50VGhlbWUoKTtcbiAgICBjb25zdCBuZXdUaGVtZTogVGhlbWUgPSBjdXJyZW50VGhlbWUgPT09ICdsaWdodCcgPyAnZGFyaycgOiAnbGlnaHQnO1xuICAgIFxuICAgIC8vIEd1YXJkYXIgZW4gbG9jYWxTdG9yYWdlIHNvbG8gY3VhbmRvIGVsIHVzdWFyaW8gaGFjZSB0b2dnbGVcbiAgICBpZiAoaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSkge1xuICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ3RoZW1lJywgbmV3VGhlbWUpO1xuICAgIH1cbiAgICBcbiAgICB0aGlzLnNldFRoZW1lKG5ld1RoZW1lKTtcbiAgfVxuXG4gIHB1YmxpYyByZXNldFRoZW1lKCk6IHZvaWQge1xuICAgIGlmIChpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLnBsYXRmb3JtSWQpKSB7XG4gICAgICBsb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbSgndGhlbWUnKTtcbiAgICAgIHRoaXMuY3VycmVudFRoZW1lU3ViamVjdC5uZXh0KCdsaWdodCcpO1xuICAgICAgdGhpcy5hcHBseVRoZW1lKCdsaWdodCcpO1xuICAgIH1cbiAgfVxuXG4gIC8vIE3DqXRvZG8gcGFyYSBjYXJnYXIgZWwgdGVtYSBndWFyZGFkbyAob3BjaW9uYWwpXG4gIHB1YmxpYyBsb2FkU2F2ZWRUaGVtZSgpOiB2b2lkIHtcbiAgICBpZiAoaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSkge1xuICAgICAgY29uc3Qgc2F2ZWRUaGVtZSA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCd0aGVtZScpIGFzIFRoZW1lO1xuICAgICAgaWYgKHNhdmVkVGhlbWUpIHtcbiAgICAgICAgdGhpcy5zZXRUaGVtZShzYXZlZFRoZW1lKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFwcGx5VGhlbWUodGhlbWU6IFRoZW1lKTogdm9pZCB7XG4gICAgLy8gU29sbyBhcGxpY2FyIGVuIGVsIG5hdmVnYWRvclxuICAgIGlmICghaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHJvb3QgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4gICAgXG4gICAgaWYgKHRoZW1lID09PSAnZGFyaycpIHtcbiAgICAgIHJvb3Quc2V0QXR0cmlidXRlKCdkYXRhLXRoZW1lJywgJ2RhcmsnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcm9vdC5zZXRBdHRyaWJ1dGUoJ2RhdGEtdGhlbWUnLCAnbGlnaHQnKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
@@ -4,7 +4,7 @@ import { EventEmitter, inject, PLATFORM_ID, HostListener, Output, Input, Directi
4
4
  import * as i1 from '@angular/router';
5
5
  import * as i1$1 from '@angular/material/dialog';
6
6
  import { MAT_DIALOG_DATA } from '@angular/material/dialog';
7
- import { fromEvent } from 'rxjs';
7
+ import { BehaviorSubject, fromEvent } from 'rxjs';
8
8
  import { debounceTime, map, distinctUntilChanged, startWith } from 'rxjs/operators';
9
9
 
10
10
  var LinkType;
@@ -118,11 +118,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
118
118
 
119
119
  class HeroSectionComponent {
120
120
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HeroSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
121
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: HeroSectionComponent, isStandalone: true, selector: "lib-hero-section", inputs: { pretitle: "pretitle", title: "title", subtitle: "subtitle", text: "text", buttons: "buttons", highlight: "highlight" }, ngImport: i0, template: "<div class=\"hero-section\">\n @if (pretitle) {\n <h2 class=\"pretitle\">{{ pretitle }}</h2>\n }\n @if (title) {\n <h1 class=\"title\">\n @if (highlight && title.includes(highlight)) {\n {{ title.replace(highlight, '') }}\n <span class=\"highlight-text\">\n {{ highlight }}\n <div class=\"wave-wrapper\">\n <div class=\"wave\"></div>\n </div>\n </span>\n } @else {\n {{ title }}\n }\n </h1>\n }\n @if (subtitle) {\n <h2 class=\"subtitle\">{{ subtitle }}</h2>\n }\n @if (text) {\n <p class=\"text\">{{ text }}</p>\n }\n @if (buttons && buttons.length > 0) {\n <div class=\"buttons\">\n @for (button of buttons; track $index) {\n <a class=\"btn btn-link\" [href]=\"button.url\" [linkType]=\"button.linkType\">\n <span>{{ button.icon }}</span>{{ button.label }}\n </a>\n }\n </div>\n }\n</div>\n", styles: [":host{display:flex;flex:1 1 auto;height:100%}.hero-section{flex:1;display:flex;flex-direction:column;justify-content:center;align-items:center;text-align:center;padding:2rem}.buttons{display:flex;gap:2rem;flex-wrap:wrap;justify-content:center}.title{text-transform:uppercase}.title .highlight-text{cursor:help;display:inline;position:relative;z-index:99}.title .highlight-text .wave-wrapper{position:absolute;top:100%;left:0;width:100%;height:30px;z-index:-1}.title .highlight-text .wave{position:absolute;background-image:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?>%0A<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->%0A<svg version=\"1.1\" id=\"Calque_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"%0A%09 viewBox=\"0 0 27.6 8.4\" style=\"enable-background:new 0 0 27.6 8.4;\" xml:space=\"preserve\">%0A<style type=\"text/css\">%0A%09.st0{fill:none;stroke:%23FFFFFF;stroke-width:2;stroke-miterlimit:10;}%0A<\\/style>%0A<path class=\"st0\" d=\"M0,1c2.7,0,5.2,1.2,6.9,3.2s4.2,3.2,6.9,3.2c2.7,0,5.2-1.2,6.9-3.2S24.9,1,27.6,1\"/>%0A</svg>%0A');background-repeat:repeat-x;background-position-x:0;background-position-y:0;top:-1.2rem;opacity:.5;width:100%;height:50%}.title .highlight-text:hover .wave{animation:moveWave 5s infinite linear}@media (max-width: 768px){.title .highlight-text{display:block;margin-top:.5rem}}@keyframes moveWave{0%{background-position-x:0}to{background-position-x:100%}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: LinkTypeDirective, selector: "[linkType]", inputs: ["linkType", "href"], outputs: ["anchorClicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
121
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: HeroSectionComponent, isStandalone: true, selector: "lib-hero-section", inputs: { pretitle: "pretitle", title: "title", subtitle: "subtitle", text: "text", buttons: "buttons", highlight: "highlight" }, ngImport: i0, template: "<div class=\"hero-section\">\n @if (pretitle) {\n <h2 class=\"pretitle\">{{ pretitle }}</h2>\n }\n @if (title) {\n <h1 class=\"title\">\n @if (highlight && title.includes(highlight)) {\n {{ title.replace(highlight, '') }}\n <span class=\"highlight-text\">\n {{ highlight }}\n <div class=\"wave-wrapper\">\n <div class=\"wave\"></div>\n </div>\n </span>\n } @else {\n {{ title }}\n }\n </h1>\n }\n @if (subtitle) {\n <h2 class=\"subtitle\">{{ subtitle }}</h2>\n }\n @if (text) {\n <p class=\"text\">{{ text }}</p>\n }\n @if (buttons && buttons.length > 0) {\n <div class=\"buttons\">\n @for (button of buttons; track $index) {\n <a class=\"btn btn-link\" [href]=\"button.url\" [linkType]=\"button.linkType\">\n <span>{{ button.icon }}</span>{{ button.label }}\n </a>\n }\n </div>\n }\n</div>\n", styles: [":host{display:flex;flex:1 1 auto;height:100%}.hero-section{flex:1;display:flex;flex-direction:column;justify-content:center;align-items:center;text-align:center;padding:2rem}.buttons{display:flex;flex-wrap:wrap;justify-content:center}.title{text-transform:uppercase}.title .highlight-text{cursor:help;display:inline;position:relative;z-index:99}.title .highlight-text .wave-wrapper{position:absolute;top:100%;left:0;width:100%;height:30px;z-index:-1}.title .highlight-text .wave{position:absolute;background-image:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?>%0A<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->%0A<svg version=\"1.1\" id=\"Calque_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"%0A%09 viewBox=\"0 0 27.6 8.4\" style=\"enable-background:new 0 0 27.6 8.4;\" xml:space=\"preserve\">%0A<style type=\"text/css\">%0A%09.st0{fill:none;stroke:%23FFFFFF;stroke-width:2;stroke-miterlimit:10;}%0A<\\/style>%0A<path class=\"st0\" d=\"M0,1c2.7,0,5.2,1.2,6.9,3.2s4.2,3.2,6.9,3.2c2.7,0,5.2-1.2,6.9-3.2S24.9,1,27.6,1\"/>%0A</svg>%0A');background-repeat:repeat-x;background-position-x:0;background-position-y:0;top:-1.2rem;opacity:.5;width:100%;height:50%}.title .highlight-text:hover .wave{animation:moveWave 5s infinite linear}@media (max-width: 768px){.title .highlight-text{display:block;margin-top:.5rem}}@keyframes moveWave{0%{background-position-x:0}to{background-position-x:100%}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: LinkTypeDirective, selector: "[linkType]", inputs: ["linkType", "href"], outputs: ["anchorClicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
122
122
  }
123
123
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HeroSectionComponent, decorators: [{
124
124
  type: Component,
125
- args: [{ selector: 'lib-hero-section', standalone: true, imports: [CommonModule, LinkTypeDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"hero-section\">\n @if (pretitle) {\n <h2 class=\"pretitle\">{{ pretitle }}</h2>\n }\n @if (title) {\n <h1 class=\"title\">\n @if (highlight && title.includes(highlight)) {\n {{ title.replace(highlight, '') }}\n <span class=\"highlight-text\">\n {{ highlight }}\n <div class=\"wave-wrapper\">\n <div class=\"wave\"></div>\n </div>\n </span>\n } @else {\n {{ title }}\n }\n </h1>\n }\n @if (subtitle) {\n <h2 class=\"subtitle\">{{ subtitle }}</h2>\n }\n @if (text) {\n <p class=\"text\">{{ text }}</p>\n }\n @if (buttons && buttons.length > 0) {\n <div class=\"buttons\">\n @for (button of buttons; track $index) {\n <a class=\"btn btn-link\" [href]=\"button.url\" [linkType]=\"button.linkType\">\n <span>{{ button.icon }}</span>{{ button.label }}\n </a>\n }\n </div>\n }\n</div>\n", styles: [":host{display:flex;flex:1 1 auto;height:100%}.hero-section{flex:1;display:flex;flex-direction:column;justify-content:center;align-items:center;text-align:center;padding:2rem}.buttons{display:flex;gap:2rem;flex-wrap:wrap;justify-content:center}.title{text-transform:uppercase}.title .highlight-text{cursor:help;display:inline;position:relative;z-index:99}.title .highlight-text .wave-wrapper{position:absolute;top:100%;left:0;width:100%;height:30px;z-index:-1}.title .highlight-text .wave{position:absolute;background-image:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?>%0A<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->%0A<svg version=\"1.1\" id=\"Calque_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"%0A%09 viewBox=\"0 0 27.6 8.4\" style=\"enable-background:new 0 0 27.6 8.4;\" xml:space=\"preserve\">%0A<style type=\"text/css\">%0A%09.st0{fill:none;stroke:%23FFFFFF;stroke-width:2;stroke-miterlimit:10;}%0A<\\/style>%0A<path class=\"st0\" d=\"M0,1c2.7,0,5.2,1.2,6.9,3.2s4.2,3.2,6.9,3.2c2.7,0,5.2-1.2,6.9-3.2S24.9,1,27.6,1\"/>%0A</svg>%0A');background-repeat:repeat-x;background-position-x:0;background-position-y:0;top:-1.2rem;opacity:.5;width:100%;height:50%}.title .highlight-text:hover .wave{animation:moveWave 5s infinite linear}@media (max-width: 768px){.title .highlight-text{display:block;margin-top:.5rem}}@keyframes moveWave{0%{background-position-x:0}to{background-position-x:100%}}\n"] }]
125
+ args: [{ selector: 'lib-hero-section', standalone: true, imports: [CommonModule, LinkTypeDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"hero-section\">\n @if (pretitle) {\n <h2 class=\"pretitle\">{{ pretitle }}</h2>\n }\n @if (title) {\n <h1 class=\"title\">\n @if (highlight && title.includes(highlight)) {\n {{ title.replace(highlight, '') }}\n <span class=\"highlight-text\">\n {{ highlight }}\n <div class=\"wave-wrapper\">\n <div class=\"wave\"></div>\n </div>\n </span>\n } @else {\n {{ title }}\n }\n </h1>\n }\n @if (subtitle) {\n <h2 class=\"subtitle\">{{ subtitle }}</h2>\n }\n @if (text) {\n <p class=\"text\">{{ text }}</p>\n }\n @if (buttons && buttons.length > 0) {\n <div class=\"buttons\">\n @for (button of buttons; track $index) {\n <a class=\"btn btn-link\" [href]=\"button.url\" [linkType]=\"button.linkType\">\n <span>{{ button.icon }}</span>{{ button.label }}\n </a>\n }\n </div>\n }\n</div>\n", styles: [":host{display:flex;flex:1 1 auto;height:100%}.hero-section{flex:1;display:flex;flex-direction:column;justify-content:center;align-items:center;text-align:center;padding:2rem}.buttons{display:flex;flex-wrap:wrap;justify-content:center}.title{text-transform:uppercase}.title .highlight-text{cursor:help;display:inline;position:relative;z-index:99}.title .highlight-text .wave-wrapper{position:absolute;top:100%;left:0;width:100%;height:30px;z-index:-1}.title .highlight-text .wave{position:absolute;background-image:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?>%0A<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->%0A<svg version=\"1.1\" id=\"Calque_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"%0A%09 viewBox=\"0 0 27.6 8.4\" style=\"enable-background:new 0 0 27.6 8.4;\" xml:space=\"preserve\">%0A<style type=\"text/css\">%0A%09.st0{fill:none;stroke:%23FFFFFF;stroke-width:2;stroke-miterlimit:10;}%0A<\\/style>%0A<path class=\"st0\" d=\"M0,1c2.7,0,5.2,1.2,6.9,3.2s4.2,3.2,6.9,3.2c2.7,0,5.2-1.2,6.9-3.2S24.9,1,27.6,1\"/>%0A</svg>%0A');background-repeat:repeat-x;background-position-x:0;background-position-y:0;top:-1.2rem;opacity:.5;width:100%;height:50%}.title .highlight-text:hover .wave{animation:moveWave 5s infinite linear}@media (max-width: 768px){.title .highlight-text{display:block;margin-top:.5rem}}@keyframes moveWave{0%{background-position-x:0}to{background-position-x:100%}}\n"] }]
126
126
  }], propDecorators: { pretitle: [{
127
127
  type: Input
128
128
  }], title: [{
@@ -187,11 +187,11 @@ class LangModalComponent {
187
187
  this.dialogRef?.close();
188
188
  }
189
189
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LangModalComponent, deps: [{ token: MAT_DIALOG_DATA, optional: true }, { token: i1$1.MatDialogRef, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
190
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: LangModalComponent, isStandalone: true, selector: "lib-lang-modal", ngImport: i0, template: "<div class=\"modal-content\">\n <button (click)=\"closeModal()\" class=\"close-btn\">\u2715</button>\n @if (langs && langs.length > 0) {\n <ol>\n @for (lang of langs; track $index) {\n <li (click)=\"selectLang(lang)\">\n <span>{{ lang.label }}</span>\n </li>\n }\n </ol>\n }\n</div>\n", styles: [":root{--color-primary: #007bff;--color-secondary: #6c757d;--color-text: #111;--color-bg: #f9f9f9;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem}:host{position:fixed;inset:0;width:100vw;height:100vh;background:var(--color-bg);z-index:1000;display:flex;align-items:center;justify-content:center}.close-btn{position:absolute;top:1rem;right:2rem;background:none;border:none;color:var(--color-text);font-size:1.5rem;font-weight:700;cursor:pointer;z-index:1001}ol{padding:0;margin:0;text-align:center;width:100%;max-width:400px}li{padding:1rem 0;cursor:pointer;text-align:start;text-transform:uppercase}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
190
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: LangModalComponent, isStandalone: true, selector: "lib-lang-modal", ngImport: i0, template: "<div class=\"modal-content\">\n <button (click)=\"closeModal()\" class=\"close-btn\">\u2715</button>\n @if (langs && langs.length > 0) {\n <ol>\n @for (lang of langs; track $index) {\n <li (click)=\"selectLang(lang)\">\n <span class=\"item\">{{ lang.label }}</span>\n </li>\n }\n </ol>\n }\n</div>\n", styles: [":root{--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem}:host{position:fixed;inset:0;width:100vw;height:100vh;background:var(--modal-bg);z-index:1000;display:flex;align-items:center;justify-content:center}.close-btn{position:absolute;top:1rem;right:2rem;background:none;border:none;color:var(--close-btn);font-size:1.5rem;font-weight:700;cursor:pointer;z-index:1001}ol{padding:0;margin:0;text-align:center;width:100%;max-width:400px;list-style:none;counter-reset:item}li{cursor:pointer;text-align:start;text-transform:uppercase;counter-increment:item}li:before{content:counter(item,decimal-leading-zero) \". \"}.item{font-size:3.5rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
191
191
  }
192
192
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LangModalComponent, decorators: [{
193
193
  type: Component,
194
- args: [{ selector: 'lib-lang-modal', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"modal-content\">\n <button (click)=\"closeModal()\" class=\"close-btn\">\u2715</button>\n @if (langs && langs.length > 0) {\n <ol>\n @for (lang of langs; track $index) {\n <li (click)=\"selectLang(lang)\">\n <span>{{ lang.label }}</span>\n </li>\n }\n </ol>\n }\n</div>\n", styles: [":root{--color-primary: #007bff;--color-secondary: #6c757d;--color-text: #111;--color-bg: #f9f9f9;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem}:host{position:fixed;inset:0;width:100vw;height:100vh;background:var(--color-bg);z-index:1000;display:flex;align-items:center;justify-content:center}.close-btn{position:absolute;top:1rem;right:2rem;background:none;border:none;color:var(--color-text);font-size:1.5rem;font-weight:700;cursor:pointer;z-index:1001}ol{padding:0;margin:0;text-align:center;width:100%;max-width:400px}li{padding:1rem 0;cursor:pointer;text-align:start;text-transform:uppercase}\n"] }]
194
+ args: [{ selector: 'lib-lang-modal', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"modal-content\">\n <button (click)=\"closeModal()\" class=\"close-btn\">\u2715</button>\n @if (langs && langs.length > 0) {\n <ol>\n @for (lang of langs; track $index) {\n <li (click)=\"selectLang(lang)\">\n <span class=\"item\">{{ lang.label }}</span>\n </li>\n }\n </ol>\n }\n</div>\n", styles: [":root{--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem}:host{position:fixed;inset:0;width:100vw;height:100vh;background:var(--modal-bg);z-index:1000;display:flex;align-items:center;justify-content:center}.close-btn{position:absolute;top:1rem;right:2rem;background:none;border:none;color:var(--close-btn);font-size:1.5rem;font-weight:700;cursor:pointer;z-index:1001}ol{padding:0;margin:0;text-align:center;width:100%;max-width:400px;list-style:none;counter-reset:item}li{cursor:pointer;text-align:start;text-transform:uppercase;counter-increment:item}li:before{content:counter(item,decimal-leading-zero) \". \"}.item{font-size:3.5rem}\n"] }]
195
195
  }], ctorParameters: () => [{ type: undefined, decorators: [{
196
196
  type: Optional
197
197
  }, {
@@ -209,11 +209,11 @@ class NavModalComponent {
209
209
  this.close.emit();
210
210
  }
211
211
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NavModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
212
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: NavModalComponent, isStandalone: true, selector: "lib-nav-modal", inputs: { navItems: "navItems", socialItems: "socialItems" }, outputs: { close: "close" }, ngImport: i0, template: "<div class=\"modal-content\">\n <button (click)=\"closeModal()\" class=\"close-btn\">\u2715</button>\n @if (navItems && navItems.length > 0) {\n <ol>\n @for (item of navItems; track $index) {\n <a [href]=\"item.url\" [linkType]=\"item.linkType\" (click)=\"closeModal()\">\n <li>\n <span>{{ item.label }}</span>\n </li>\n </a>\n }\n </ol>\n }\n</div>\n", styles: [":root{--color-primary: #007bff;--color-secondary: #6c757d;--color-text: #111;--color-bg: #f9f9f9;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem}:host{position:fixed;inset:0;width:100vw;height:100vh;background:var(--color-bg);z-index:1000;display:flex;align-items:center;justify-content:center}.close-btn{position:absolute;top:1rem;right:2rem;background:none;border:none;color:var(--color-text);font-size:1.5rem;font-weight:700;cursor:pointer;z-index:1001}ol{padding:0;margin:0;text-align:center;width:100%;max-width:400px}li{padding:1rem 0;cursor:pointer;text-align:start}a{text-decoration:none;text-transform:uppercase;color:var(--color-text)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: LinkTypeDirective, selector: "[linkType]", inputs: ["linkType", "href"], outputs: ["anchorClicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
212
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: NavModalComponent, isStandalone: true, selector: "lib-nav-modal", inputs: { navItems: "navItems", socialItems: "socialItems" }, outputs: { close: "close" }, ngImport: i0, template: "<div class=\"modal-content\">\n <button (click)=\"closeModal()\" class=\"close-btn\">\u2715</button>\n @if (navItems && navItems.length > 0) {\n <ol>\n @for (item of navItems; track $index) {\n <a [href]=\"item.url\" [linkType]=\"item.linkType\" (click)=\"closeModal()\">\n <li>\n <span class=\"item\">{{ item.label }}</span>\n </li>\n </a>\n }\n </ol>\n }\n</div>\n", styles: [":root{--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem}:host{position:fixed;inset:0;width:100vw;height:100vh;background:var(--modal-bg);z-index:1000;display:flex;align-items:center;justify-content:center}.close-btn{position:absolute;top:1rem;right:2rem;background:none;border:none;color:var(--close-btn);font-size:1.5rem;font-weight:700;cursor:pointer;z-index:1001}ol{padding:0;margin:0;text-align:center;width:100%;max-width:400px;list-style:none;counter-reset:item}li{cursor:pointer;text-align:start;counter-increment:item}a{text-decoration:none;text-transform:uppercase;color:var(--item-color)}li:before{content:counter(item,decimal-leading-zero) \". \"}.item{font-size:3.5rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: LinkTypeDirective, selector: "[linkType]", inputs: ["linkType", "href"], outputs: ["anchorClicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
213
213
  }
214
214
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NavModalComponent, decorators: [{
215
215
  type: Component,
216
- args: [{ selector: 'lib-nav-modal', standalone: true, imports: [CommonModule, LinkTypeDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"modal-content\">\n <button (click)=\"closeModal()\" class=\"close-btn\">\u2715</button>\n @if (navItems && navItems.length > 0) {\n <ol>\n @for (item of navItems; track $index) {\n <a [href]=\"item.url\" [linkType]=\"item.linkType\" (click)=\"closeModal()\">\n <li>\n <span>{{ item.label }}</span>\n </li>\n </a>\n }\n </ol>\n }\n</div>\n", styles: [":root{--color-primary: #007bff;--color-secondary: #6c757d;--color-text: #111;--color-bg: #f9f9f9;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem}:host{position:fixed;inset:0;width:100vw;height:100vh;background:var(--color-bg);z-index:1000;display:flex;align-items:center;justify-content:center}.close-btn{position:absolute;top:1rem;right:2rem;background:none;border:none;color:var(--color-text);font-size:1.5rem;font-weight:700;cursor:pointer;z-index:1001}ol{padding:0;margin:0;text-align:center;width:100%;max-width:400px}li{padding:1rem 0;cursor:pointer;text-align:start}a{text-decoration:none;text-transform:uppercase;color:var(--color-text)}\n"] }]
216
+ args: [{ selector: 'lib-nav-modal', standalone: true, imports: [CommonModule, LinkTypeDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"modal-content\">\n <button (click)=\"closeModal()\" class=\"close-btn\">\u2715</button>\n @if (navItems && navItems.length > 0) {\n <ol>\n @for (item of navItems; track $index) {\n <a [href]=\"item.url\" [linkType]=\"item.linkType\" (click)=\"closeModal()\">\n <li>\n <span class=\"item\">{{ item.label }}</span>\n </li>\n </a>\n }\n </ol>\n }\n</div>\n", styles: [":root{--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem}:host{position:fixed;inset:0;width:100vw;height:100vh;background:var(--modal-bg);z-index:1000;display:flex;align-items:center;justify-content:center}.close-btn{position:absolute;top:1rem;right:2rem;background:none;border:none;color:var(--close-btn);font-size:1.5rem;font-weight:700;cursor:pointer;z-index:1001}ol{padding:0;margin:0;text-align:center;width:100%;max-width:400px;list-style:none;counter-reset:item}li{cursor:pointer;text-align:start;counter-increment:item}a{text-decoration:none;text-transform:uppercase;color:var(--item-color)}li:before{content:counter(item,decimal-leading-zero) \". \"}.item{font-size:3.5rem}\n"] }]
217
217
  }], propDecorators: { navItems: [{
218
218
  type: Input
219
219
  }], socialItems: [{
@@ -222,33 +222,120 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
222
222
  type: Output
223
223
  }] } });
224
224
 
225
+ class ThemeService {
226
+ constructor(platformId) {
227
+ this.platformId = platformId;
228
+ this.currentThemeSubject = new BehaviorSubject('light');
229
+ this.currentTheme$ = this.currentThemeSubject.asObservable();
230
+ // Aplicar tema por defecto al inicio
231
+ if (isPlatformBrowser(this.platformId)) {
232
+ this.applyTheme('light');
233
+ }
234
+ }
235
+ getCurrentTheme() {
236
+ return this.currentThemeSubject.value;
237
+ }
238
+ setTheme(theme) {
239
+ this.currentThemeSubject.next(theme);
240
+ this.applyTheme(theme);
241
+ // NO guardar automáticamente en localStorage - solo cuando el usuario hace toggle
242
+ }
243
+ toggleTheme() {
244
+ const currentTheme = this.getCurrentTheme();
245
+ const newTheme = currentTheme === 'light' ? 'dark' : 'light';
246
+ // Guardar en localStorage solo cuando el usuario hace toggle
247
+ if (isPlatformBrowser(this.platformId)) {
248
+ localStorage.setItem('theme', newTheme);
249
+ }
250
+ this.setTheme(newTheme);
251
+ }
252
+ resetTheme() {
253
+ if (isPlatformBrowser(this.platformId)) {
254
+ localStorage.removeItem('theme');
255
+ this.currentThemeSubject.next('light');
256
+ this.applyTheme('light');
257
+ }
258
+ }
259
+ // Método para cargar el tema guardado (opcional)
260
+ loadSavedTheme() {
261
+ if (isPlatformBrowser(this.platformId)) {
262
+ const savedTheme = localStorage.getItem('theme');
263
+ if (savedTheme) {
264
+ this.setTheme(savedTheme);
265
+ }
266
+ }
267
+ }
268
+ applyTheme(theme) {
269
+ // Solo aplicar en el navegador
270
+ if (!isPlatformBrowser(this.platformId)) {
271
+ return;
272
+ }
273
+ const root = document.documentElement;
274
+ if (theme === 'dark') {
275
+ root.setAttribute('data-theme', 'dark');
276
+ }
277
+ else {
278
+ root.setAttribute('data-theme', 'light');
279
+ }
280
+ }
281
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ThemeService, deps: [{ token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Injectable }); }
282
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ThemeService, providedIn: 'root' }); }
283
+ }
284
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ThemeService, decorators: [{
285
+ type: Injectable,
286
+ args: [{
287
+ providedIn: 'root'
288
+ }]
289
+ }], ctorParameters: () => [{ type: Object, decorators: [{
290
+ type: Inject,
291
+ args: [PLATFORM_ID]
292
+ }] }] });
293
+
225
294
  class HeaderClearComponent {
226
- constructor() {
295
+ constructor(themeService) {
296
+ this.themeService = themeService;
227
297
  this.isMenuOpen = false;
298
+ this.currentTheme = 'light';
228
299
  this.langModal = new EventEmitter();
229
300
  this.theme = new EventEmitter();
230
301
  }
302
+ ngOnInit() {
303
+ this.themeSubscription = this.themeService.currentTheme$.subscribe(theme => {
304
+ this.currentTheme = theme;
305
+ });
306
+ }
307
+ ngOnDestroy() {
308
+ this.themeSubscription?.unsubscribe();
309
+ }
231
310
  openLanguagesModal() {
232
311
  this.langModal.emit();
233
312
  }
234
313
  toggleTheme() {
314
+ this.themeService.toggleTheme();
235
315
  this.theme.emit();
236
316
  }
237
317
  toggleMenu() {
238
318
  this.isMenuOpen = !this.isMenuOpen;
239
319
  }
240
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HeaderClearComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
241
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: HeaderClearComponent, isStandalone: true, selector: "lib-header-clear", inputs: { logo: "logo", lang: "lang", navItems: "navItems" }, outputs: { langModal: "langModal", theme: "theme" }, ngImport: i0, template: "<header class=\"header-clear\">\n <div class=\"header-logo\">\n <!-- Logo -->\n <img [src]=\"logo?.url\" [alt]=\"logo?.alt\" />\n <span>LLUC LLULL</span>\n </div>\n\n <div class=\"header-actions\">\n <!-- Idioma -->\n <button class=\"btn btn-primary\" (click)=\"openLanguagesModal()\">\n <span class=\"lang\">{{lang}}</span>\n </button>\n\n <!-- Icono de recarga -->\n <button class=\"btn btn-primary\" (click)=\"toggleTheme()\">\n <span>\uD83C\uDF19</span>\n </button>\n\n <!-- Icono de men\u00FA -->\n <button class=\"btn btn-primary\" (click)=\"toggleMenu()\">\n <span>\u2630</span>\n </button>\n </div>\n</header>\n\n@if(isMenuOpen && navItems && navItems.length > 0) {\n <lib-nav-modal\n [navItems]=\"navItems\"\n (close)=\"isMenuOpen = false\"\n ></lib-nav-modal>\n}\n", styles: [".header-clear{display:flex;justify-content:space-between;align-items:center;padding:1rem 2rem;border-radius:0;position:sticky;top:0;z-index:100}.header-logo{display:flex;align-items:center;gap:.5rem}.header-logo img{width:36px;height:36px;object-fit:contain;object-position:center}.header-actions{display:flex;align-items:center;gap:1rem}.lang{text-transform:uppercase}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: NavModalComponent, selector: "lib-nav-modal", inputs: ["navItems", "socialItems"], outputs: ["close"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
320
+ getThemeIcon() {
321
+ return this.currentTheme === 'light' ? '🌙' : '☀️';
322
+ }
323
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HeaderClearComponent, deps: [{ token: ThemeService }], target: i0.ɵɵFactoryTarget.Component }); }
324
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: HeaderClearComponent, isStandalone: true, selector: "lib-header-clear", inputs: { logo: "logo", logoDark: "logoDark", lang: "lang", navItems: "navItems", homeLink: "homeLink" }, outputs: { langModal: "langModal", theme: "theme" }, ngImport: i0, template: "<header class=\"header-clear\">\n <a [href]=\"homeLink?.url\" [linkType]=\"homeLink?.linkType\">\n <div class=\"header-logo\">\n <!-- Logo -->\n <img [src]=\"currentTheme === 'dark' ? logoDark?.url : logo?.url\" [alt]=\"currentTheme === 'dark' ? logoDark?.alt : logo?.alt\" />\n <span>LLUC LLULL</span>\n </div>\n </a>\n\n <div class=\"header-actions\">\n <!-- Idioma -->\n <button class=\"btn btn-primary\" (click)=\"openLanguagesModal()\">\n <span class=\"lang\">{{lang}}</span>\n </button>\n\n <!-- Icono de tema -->\n <button class=\"btn btn-primary\" (click)=\"toggleTheme()\">\n <span>{{getThemeIcon()}}</span>\n </button>\n\n <!-- Icono de men\u00FA -->\n <button class=\"btn btn-primary\" (click)=\"toggleMenu()\">\n <span>\u2630</span>\n </button>\n </div>\n</header>\n\n@if(isMenuOpen && navItems && navItems.length > 0) {\n <lib-nav-modal\n [navItems]=\"navItems\"\n (close)=\"isMenuOpen = false\"\n ></lib-nav-modal>\n}\n", styles: [".header-clear{display:flex;justify-content:space-between;align-items:center;padding:1rem 2rem;border-radius:0;position:sticky;top:0;z-index:100}.header-logo{display:flex;align-items:center;gap:.5rem;color:var(--header-logo-text)}.header-logo img{width:36px;height:36px;object-fit:contain;object-position:center}.header-actions{display:flex;align-items:center;gap:1rem}.lang{text-transform:uppercase}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: NavModalComponent, selector: "lib-nav-modal", inputs: ["navItems", "socialItems"], outputs: ["close"] }, { kind: "directive", type: LinkTypeDirective, selector: "[linkType]", inputs: ["linkType", "href"], outputs: ["anchorClicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
242
325
  }
243
326
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HeaderClearComponent, decorators: [{
244
327
  type: Component,
245
- args: [{ selector: 'lib-header-clear', standalone: true, imports: [CommonModule, LangModalComponent, NavModalComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<header class=\"header-clear\">\n <div class=\"header-logo\">\n <!-- Logo -->\n <img [src]=\"logo?.url\" [alt]=\"logo?.alt\" />\n <span>LLUC LLULL</span>\n </div>\n\n <div class=\"header-actions\">\n <!-- Idioma -->\n <button class=\"btn btn-primary\" (click)=\"openLanguagesModal()\">\n <span class=\"lang\">{{lang}}</span>\n </button>\n\n <!-- Icono de recarga -->\n <button class=\"btn btn-primary\" (click)=\"toggleTheme()\">\n <span>\uD83C\uDF19</span>\n </button>\n\n <!-- Icono de men\u00FA -->\n <button class=\"btn btn-primary\" (click)=\"toggleMenu()\">\n <span>\u2630</span>\n </button>\n </div>\n</header>\n\n@if(isMenuOpen && navItems && navItems.length > 0) {\n <lib-nav-modal\n [navItems]=\"navItems\"\n (close)=\"isMenuOpen = false\"\n ></lib-nav-modal>\n}\n", styles: [".header-clear{display:flex;justify-content:space-between;align-items:center;padding:1rem 2rem;border-radius:0;position:sticky;top:0;z-index:100}.header-logo{display:flex;align-items:center;gap:.5rem}.header-logo img{width:36px;height:36px;object-fit:contain;object-position:center}.header-actions{display:flex;align-items:center;gap:1rem}.lang{text-transform:uppercase}\n"] }]
246
- }], propDecorators: { logo: [{
328
+ args: [{ selector: 'lib-header-clear', standalone: true, imports: [CommonModule, LangModalComponent, NavModalComponent, LinkTypeDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<header class=\"header-clear\">\n <a [href]=\"homeLink?.url\" [linkType]=\"homeLink?.linkType\">\n <div class=\"header-logo\">\n <!-- Logo -->\n <img [src]=\"currentTheme === 'dark' ? logoDark?.url : logo?.url\" [alt]=\"currentTheme === 'dark' ? logoDark?.alt : logo?.alt\" />\n <span>LLUC LLULL</span>\n </div>\n </a>\n\n <div class=\"header-actions\">\n <!-- Idioma -->\n <button class=\"btn btn-primary\" (click)=\"openLanguagesModal()\">\n <span class=\"lang\">{{lang}}</span>\n </button>\n\n <!-- Icono de tema -->\n <button class=\"btn btn-primary\" (click)=\"toggleTheme()\">\n <span>{{getThemeIcon()}}</span>\n </button>\n\n <!-- Icono de men\u00FA -->\n <button class=\"btn btn-primary\" (click)=\"toggleMenu()\">\n <span>\u2630</span>\n </button>\n </div>\n</header>\n\n@if(isMenuOpen && navItems && navItems.length > 0) {\n <lib-nav-modal\n [navItems]=\"navItems\"\n (close)=\"isMenuOpen = false\"\n ></lib-nav-modal>\n}\n", styles: [".header-clear{display:flex;justify-content:space-between;align-items:center;padding:1rem 2rem;border-radius:0;position:sticky;top:0;z-index:100}.header-logo{display:flex;align-items:center;gap:.5rem;color:var(--header-logo-text)}.header-logo img{width:36px;height:36px;object-fit:contain;object-position:center}.header-actions{display:flex;align-items:center;gap:1rem}.lang{text-transform:uppercase}\n"] }]
329
+ }], ctorParameters: () => [{ type: ThemeService }], propDecorators: { logo: [{
330
+ type: Input
331
+ }], logoDark: [{
247
332
  type: Input
248
333
  }], lang: [{
249
334
  type: Input
250
335
  }], navItems: [{
251
336
  type: Input
337
+ }], homeLink: [{
338
+ type: Input
252
339
  }], langModal: [{
253
340
  type: Output
254
341
  }], theme: [{
@@ -256,32 +343,50 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
256
343
  }] } });
257
344
 
258
345
  class HeaderMobileComponent {
259
- constructor() {
346
+ constructor(themeService) {
347
+ this.themeService = themeService;
260
348
  this.isMenuOpen = false;
349
+ this.currentTheme = 'light';
261
350
  this.langModal = new EventEmitter();
262
351
  this.theme = new EventEmitter();
263
352
  }
353
+ ngOnInit() {
354
+ this.themeSubscription = this.themeService.currentTheme$.subscribe(theme => {
355
+ this.currentTheme = theme;
356
+ });
357
+ }
358
+ ngOnDestroy() {
359
+ this.themeSubscription?.unsubscribe();
360
+ }
264
361
  openLanguagesModal() {
265
362
  this.langModal.emit();
266
363
  }
267
364
  toggleTheme() {
365
+ this.themeService.toggleTheme();
268
366
  this.theme.emit();
269
367
  }
270
368
  toggleMenu() {
271
369
  this.isMenuOpen = !this.isMenuOpen;
272
370
  }
273
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HeaderMobileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
274
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: HeaderMobileComponent, isStandalone: true, selector: "lib-header-mobile", inputs: { logo: "logo", lang: "lang", navItems: "navItems" }, outputs: { langModal: "langModal", theme: "theme" }, ngImport: i0, template: "<header class=\"header-mobile\">\n <div class=\"header-logo\">\n <!-- Logo -->\n <img [src]=\"logo?.url\" [alt]=\"logo?.alt\" />\n <span>LLUC LLULL</span>\n </div>\n</header>\n\n<div class=\"header-actions\">\n <!-- Idioma -->\n <div class=\"left\">\n <button class=\"btn btn-primary\" (click)=\"openLanguagesModal()\">\n <span class=\"lang\">{{ lang }}</span>\n </button>\n </div>\n\n <!-- Icono de recarga -->\n <div class=\"center\">\n <button class=\"btn btn-primary\" (click)=\"toggleTheme()\">\n <span>\uD83C\uDF19</span>\n </button>\n </div>\n\n <!-- Icono de men\u00FA -->\n <div class=\"right\">\n <button class=\"btn btn-primary\" (click)=\"toggleMenu()\">\n <span>\u2630</span>\n </button>\n </div>\n</div>\n\n\n@if(isMenuOpen && navItems && navItems.length > 0) {\n <lib-nav-modal\n [navItems]=\"navItems\"\n (close)=\"isMenuOpen = false\"\n ></lib-nav-modal>\n}\n\n", styles: [":root{--color-primary: #007bff;--color-secondary: #6c757d;--color-text: #111;--color-bg: #f9f9f9;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem}.header-mobile{display:flex;justify-content:center;align-items:center;padding:1rem 0;border-radius:0;position:fixed;top:0;z-index:100;background-color:var(--color-secondary);width:100vw}.header-logo{display:flex;align-items:center;gap:.5rem}.header-logo img{width:36px;height:36px;object-fit:contain;object-position:center}.header-actions{position:fixed;bottom:0;left:0;right:0;display:flex;align-items:center;justify-content:space-between;padding:.5rem 1rem;background-color:var(--color-secondary);z-index:100;box-sizing:border-box}.header-actions .center{margin:0 auto}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: NavModalComponent, selector: "lib-nav-modal", inputs: ["navItems", "socialItems"], outputs: ["close"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
371
+ getThemeIcon() {
372
+ return this.currentTheme === 'light' ? '🌙' : '☀️';
373
+ }
374
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HeaderMobileComponent, deps: [{ token: ThemeService }], target: i0.ɵɵFactoryTarget.Component }); }
375
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: HeaderMobileComponent, isStandalone: true, selector: "lib-header-mobile", inputs: { logo: "logo", logoDark: "logoDark", lang: "lang", navItems: "navItems", homeLink: "homeLink" }, outputs: { langModal: "langModal", theme: "theme" }, ngImport: i0, template: "<header class=\"header-mobile\">\n <a [href]=\"homeLink?.url\" [linkType]=\"homeLink?.linkType\">\n <div class=\"header-logo\">\n <!-- Logo -->\n <img [src]=\"currentTheme === 'dark' ? logoDark?.url : logo?.url\" [alt]=\"currentTheme === 'dark' ? logoDark?.alt : logo?.alt\" />\n <span>LLUC LLULL</span>\n </div>\n </a>\n</header>\n\n<div class=\"header-actions\">\n <!-- Idioma -->\n <div class=\"left\">\n <button class=\"btn btn-primary\" (click)=\"openLanguagesModal()\">\n <span class=\"lang\">{{ lang }}</span>\n </button>\n </div>\n\n <!-- Icono de tema -->\n <div class=\"center\">\n <button class=\"btn btn-primary\" (click)=\"toggleTheme()\">\n <span>{{getThemeIcon()}}</span>\n </button>\n </div>\n\n <!-- Icono de men\u00FA -->\n <div class=\"right\">\n <button class=\"btn btn-primary\" (click)=\"toggleMenu()\">\n <span>\u2630</span>\n </button>\n </div>\n</div>\n\n\n@if(isMenuOpen && navItems && navItems.length > 0) {\n <lib-nav-modal\n [navItems]=\"navItems\"\n (close)=\"isMenuOpen = false\"\n ></lib-nav-modal>\n}\n\n", styles: [":root{--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem}.header-mobile{display:flex;justify-content:center;align-items:center;padding:1rem 0;border-radius:0;position:fixed;top:0;z-index:100;background-color:var(--header-mobile-bg);width:100vw}.header-logo{display:flex;align-items:center;gap:.5rem;color:var(--header-logo-text)}.header-logo img{width:36px;height:36px;object-fit:contain;object-position:center}.header-actions{position:fixed;bottom:0;left:0;right:0;display:flex;align-items:center;justify-content:space-between;padding:.5rem 1rem;background-color:var(--header-mobile-bg);z-index:100;box-sizing:border-box}.header-actions .center{margin:0 auto}.lang{text-transform:uppercase}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: NavModalComponent, selector: "lib-nav-modal", inputs: ["navItems", "socialItems"], outputs: ["close"] }, { kind: "directive", type: LinkTypeDirective, selector: "[linkType]", inputs: ["linkType", "href"], outputs: ["anchorClicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
275
376
  }
276
377
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HeaderMobileComponent, decorators: [{
277
378
  type: Component,
278
- args: [{ selector: 'lib-header-mobile', standalone: true, imports: [CommonModule, LangModalComponent, NavModalComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<header class=\"header-mobile\">\n <div class=\"header-logo\">\n <!-- Logo -->\n <img [src]=\"logo?.url\" [alt]=\"logo?.alt\" />\n <span>LLUC LLULL</span>\n </div>\n</header>\n\n<div class=\"header-actions\">\n <!-- Idioma -->\n <div class=\"left\">\n <button class=\"btn btn-primary\" (click)=\"openLanguagesModal()\">\n <span class=\"lang\">{{ lang }}</span>\n </button>\n </div>\n\n <!-- Icono de recarga -->\n <div class=\"center\">\n <button class=\"btn btn-primary\" (click)=\"toggleTheme()\">\n <span>\uD83C\uDF19</span>\n </button>\n </div>\n\n <!-- Icono de men\u00FA -->\n <div class=\"right\">\n <button class=\"btn btn-primary\" (click)=\"toggleMenu()\">\n <span>\u2630</span>\n </button>\n </div>\n</div>\n\n\n@if(isMenuOpen && navItems && navItems.length > 0) {\n <lib-nav-modal\n [navItems]=\"navItems\"\n (close)=\"isMenuOpen = false\"\n ></lib-nav-modal>\n}\n\n", styles: [":root{--color-primary: #007bff;--color-secondary: #6c757d;--color-text: #111;--color-bg: #f9f9f9;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem}.header-mobile{display:flex;justify-content:center;align-items:center;padding:1rem 0;border-radius:0;position:fixed;top:0;z-index:100;background-color:var(--color-secondary);width:100vw}.header-logo{display:flex;align-items:center;gap:.5rem}.header-logo img{width:36px;height:36px;object-fit:contain;object-position:center}.header-actions{position:fixed;bottom:0;left:0;right:0;display:flex;align-items:center;justify-content:space-between;padding:.5rem 1rem;background-color:var(--color-secondary);z-index:100;box-sizing:border-box}.header-actions .center{margin:0 auto}\n"] }]
279
- }], propDecorators: { logo: [{
379
+ args: [{ selector: 'lib-header-mobile', standalone: true, imports: [CommonModule, LangModalComponent, NavModalComponent, LinkTypeDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<header class=\"header-mobile\">\n <a [href]=\"homeLink?.url\" [linkType]=\"homeLink?.linkType\">\n <div class=\"header-logo\">\n <!-- Logo -->\n <img [src]=\"currentTheme === 'dark' ? logoDark?.url : logo?.url\" [alt]=\"currentTheme === 'dark' ? logoDark?.alt : logo?.alt\" />\n <span>LLUC LLULL</span>\n </div>\n </a>\n</header>\n\n<div class=\"header-actions\">\n <!-- Idioma -->\n <div class=\"left\">\n <button class=\"btn btn-primary\" (click)=\"openLanguagesModal()\">\n <span class=\"lang\">{{ lang }}</span>\n </button>\n </div>\n\n <!-- Icono de tema -->\n <div class=\"center\">\n <button class=\"btn btn-primary\" (click)=\"toggleTheme()\">\n <span>{{getThemeIcon()}}</span>\n </button>\n </div>\n\n <!-- Icono de men\u00FA -->\n <div class=\"right\">\n <button class=\"btn btn-primary\" (click)=\"toggleMenu()\">\n <span>\u2630</span>\n </button>\n </div>\n</div>\n\n\n@if(isMenuOpen && navItems && navItems.length > 0) {\n <lib-nav-modal\n [navItems]=\"navItems\"\n (close)=\"isMenuOpen = false\"\n ></lib-nav-modal>\n}\n\n", styles: [":root{--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem}.header-mobile{display:flex;justify-content:center;align-items:center;padding:1rem 0;border-radius:0;position:fixed;top:0;z-index:100;background-color:var(--header-mobile-bg);width:100vw}.header-logo{display:flex;align-items:center;gap:.5rem;color:var(--header-logo-text)}.header-logo img{width:36px;height:36px;object-fit:contain;object-position:center}.header-actions{position:fixed;bottom:0;left:0;right:0;display:flex;align-items:center;justify-content:space-between;padding:.5rem 1rem;background-color:var(--header-mobile-bg);z-index:100;box-sizing:border-box}.header-actions .center{margin:0 auto}.lang{text-transform:uppercase}\n"] }]
380
+ }], ctorParameters: () => [{ type: ThemeService }], propDecorators: { logo: [{
381
+ type: Input
382
+ }], logoDark: [{
280
383
  type: Input
281
384
  }], lang: [{
282
385
  type: Input
283
386
  }], navItems: [{
284
387
  type: Input
388
+ }], homeLink: [{
389
+ type: Input
285
390
  }], langModal: [{
286
391
  type: Output
287
392
  }], theme: [{
@@ -290,11 +395,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
290
395
 
291
396
  class SectionIntroComponent {
292
397
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SectionIntroComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
293
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: SectionIntroComponent, isStandalone: true, selector: "lib-section-intro", inputs: { pretitle: "pretitle", title: "title", subtitle: "subtitle", text: "text", button: "button" }, ngImport: i0, template: "<div class=\"section-intro\">\n @if(pretitle){\n <h2 class=\"pretitle\">{{pretitle}}</h2>\n }\n @if(title){\n <h1 class=\"title\">{{title}}</h1>\n }\n @if(subtitle){\n <h2 class=\"subtitle\">{{subtitle}}</h2>\n }\n @if(text){\n <p class=\"text\">{{text}}</p>\n }\n @if(button){\n <a\n [href]=\"button.url\"\n [linkType]=\"button.linkType\"\n class=\"btn btn-link\"\n >\n {{button.label}} \n </a>\n }\n</div>\n", styles: [":root{--color-primary: #007bff;--color-secondary: #6c757d;--color-text: #111;--color-bg: #f9f9f9;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem}.section-intro{text-align:start;padding:2rem 10rem;align-items:start}@media (max-width: 768px){.section-intro{padding:2rem 4rem}}.title,.subtitle{text-transform:uppercase}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: LinkTypeDirective, selector: "[linkType]", inputs: ["linkType", "href"], outputs: ["anchorClicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
398
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: SectionIntroComponent, isStandalone: true, selector: "lib-section-intro", inputs: { pretitle: "pretitle", title: "title", subtitle: "subtitle", text: "text", button: "button" }, ngImport: i0, template: "<div class=\"section-intro\">\n @if(pretitle){\n <h2 class=\"pretitle\">{{pretitle}}</h2>\n }\n @if(title){\n <h1 class=\"title\">{{title}}</h1>\n }\n @if(subtitle){\n <h2 class=\"subtitle\">{{subtitle}}</h2>\n }\n @if(text){\n <p class=\"text\">{{text}}</p>\n }\n @if(button){\n <a\n [href]=\"button.url\"\n [linkType]=\"button.linkType\"\n class=\"btn btn-link\"\n >\n {{button.label}} \n </a>\n }\n</div>\n", styles: [":root{--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem}.section-intro{text-align:start;padding:2rem 10rem;align-items:start}@media (max-width: 768px){.section-intro{padding:2rem 4rem}}.title,.subtitle{text-transform:uppercase}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: LinkTypeDirective, selector: "[linkType]", inputs: ["linkType", "href"], outputs: ["anchorClicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
294
399
  }
295
400
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SectionIntroComponent, decorators: [{
296
401
  type: Component,
297
- args: [{ selector: 'lib-section-intro', standalone: true, imports: [CommonModule, LinkTypeDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"section-intro\">\n @if(pretitle){\n <h2 class=\"pretitle\">{{pretitle}}</h2>\n }\n @if(title){\n <h1 class=\"title\">{{title}}</h1>\n }\n @if(subtitle){\n <h2 class=\"subtitle\">{{subtitle}}</h2>\n }\n @if(text){\n <p class=\"text\">{{text}}</p>\n }\n @if(button){\n <a\n [href]=\"button.url\"\n [linkType]=\"button.linkType\"\n class=\"btn btn-link\"\n >\n {{button.label}} \n </a>\n }\n</div>\n", styles: [":root{--color-primary: #007bff;--color-secondary: #6c757d;--color-text: #111;--color-bg: #f9f9f9;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem}.section-intro{text-align:start;padding:2rem 10rem;align-items:start}@media (max-width: 768px){.section-intro{padding:2rem 4rem}}.title,.subtitle{text-transform:uppercase}\n"] }]
402
+ args: [{ selector: 'lib-section-intro', standalone: true, imports: [CommonModule, LinkTypeDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"section-intro\">\n @if(pretitle){\n <h2 class=\"pretitle\">{{pretitle}}</h2>\n }\n @if(title){\n <h1 class=\"title\">{{title}}</h1>\n }\n @if(subtitle){\n <h2 class=\"subtitle\">{{subtitle}}</h2>\n }\n @if(text){\n <p class=\"text\">{{text}}</p>\n }\n @if(button){\n <a\n [href]=\"button.url\"\n [linkType]=\"button.linkType\"\n class=\"btn btn-link\"\n >\n {{button.label}} \n </a>\n }\n</div>\n", styles: [":root{--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem}.section-intro{text-align:start;padding:2rem 10rem;align-items:start}@media (max-width: 768px){.section-intro{padding:2rem 4rem}}.title,.subtitle{text-transform:uppercase}\n"] }]
298
403
  }], propDecorators: { pretitle: [{
299
404
  type: Input
300
405
  }], title: [{
@@ -309,11 +414,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
309
414
 
310
415
  class CategoryProgressComponent {
311
416
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CategoryProgressComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
312
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: CategoryProgressComponent, isStandalone: true, selector: "lib-category-progress", inputs: { pretitle: "pretitle", title: "title", categories: "categories" }, ngImport: i0, template: "<div class=\"category-progress\">\n @if (pretitle){\n <h3 class=\"pretitle\">{{pretitle}}</h3>\n }\n @if (title){\n <h2 class=\"title\">{{title}}</h2>\n }\n <div class=\"progress-grid\">\n @for (category of categories; track $index) {\n <div class=\"category\">\n <h3 class=\"subtitle\">{{ category.title }}</h3>\n \n @for (item of category.items; track $index){\n <div class=\"item\">\n <span class=\"label\">{{ item.label }}</span>\n <div class=\"bar\">\n <div class=\"fill\" [style.width.%]=\"item.value\"></div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n \n</div>\n", styles: [":root{--color-primary: #007bff;--color-secondary: #6c757d;--color-text: #111;--color-bg: #f9f9f9;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem}.category-progress{text-align:start;padding:2rem 10rem;align-items:start}@media (max-width: 768px){.category-progress{padding:2rem 4rem}}.title{text-transform:uppercase}.progress-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:2rem}.category{display:flex;flex-direction:column;gap:1.5rem}.category-title{font-weight:600;font-size:1.1rem}.item .label{font-size:.9rem;margin-bottom:.3rem;display:block}.item .bar{background-color:#ccc;height:6px;border-radius:3px;overflow:hidden}.item .bar .fill{background-color:#000;height:100%;width:0;transition:width .3s ease}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
417
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: CategoryProgressComponent, isStandalone: true, selector: "lib-category-progress", inputs: { pretitle: "pretitle", title: "title", categories: "categories" }, ngImport: i0, template: "<div class=\"category-progress\">\n @if (pretitle){\n <h3 class=\"pretitle\">{{pretitle}}</h3>\n }\n @if (title){\n <h2 class=\"title\">{{title}}</h2>\n }\n <div class=\"progress-grid\">\n @for (category of categories; track $index) {\n <div class=\"category\">\n <h3 class=\"subtitle\">{{ category.title }}</h3>\n \n @for (item of category.items; track $index){\n <div class=\"item\">\n <span class=\"label\">{{ item.label }}</span>\n <div class=\"bar\">\n <div class=\"fill\" [style.width.%]=\"item.value\"></div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n \n</div>\n", styles: [":root{--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem}.category-progress{text-align:start;padding:2rem 10rem;align-items:start}@media (max-width: 768px){.category-progress{padding:2rem 4rem}}.title{text-transform:uppercase}.progress-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:2rem}.category{display:flex;flex-direction:column;gap:1.5rem}.category-title{font-weight:600;font-size:1.1rem}.item .label{font-size:.9rem;margin-bottom:.3rem;display:block}.item .bar{background-color:var(--progress-bg);height:6px;border-radius:3px;overflow:hidden}.item .bar .fill{background-color:var(--progress-color);height:100%;width:0;transition:width .3s ease}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
313
418
  }
314
419
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CategoryProgressComponent, decorators: [{
315
420
  type: Component,
316
- args: [{ selector: 'lib-category-progress', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"category-progress\">\n @if (pretitle){\n <h3 class=\"pretitle\">{{pretitle}}</h3>\n }\n @if (title){\n <h2 class=\"title\">{{title}}</h2>\n }\n <div class=\"progress-grid\">\n @for (category of categories; track $index) {\n <div class=\"category\">\n <h3 class=\"subtitle\">{{ category.title }}</h3>\n \n @for (item of category.items; track $index){\n <div class=\"item\">\n <span class=\"label\">{{ item.label }}</span>\n <div class=\"bar\">\n <div class=\"fill\" [style.width.%]=\"item.value\"></div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n \n</div>\n", styles: [":root{--color-primary: #007bff;--color-secondary: #6c757d;--color-text: #111;--color-bg: #f9f9f9;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem}.category-progress{text-align:start;padding:2rem 10rem;align-items:start}@media (max-width: 768px){.category-progress{padding:2rem 4rem}}.title{text-transform:uppercase}.progress-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:2rem}.category{display:flex;flex-direction:column;gap:1.5rem}.category-title{font-weight:600;font-size:1.1rem}.item .label{font-size:.9rem;margin-bottom:.3rem;display:block}.item .bar{background-color:#ccc;height:6px;border-radius:3px;overflow:hidden}.item .bar .fill{background-color:#000;height:100%;width:0;transition:width .3s ease}\n"] }]
421
+ args: [{ selector: 'lib-category-progress', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"category-progress\">\n @if (pretitle){\n <h3 class=\"pretitle\">{{pretitle}}</h3>\n }\n @if (title){\n <h2 class=\"title\">{{title}}</h2>\n }\n <div class=\"progress-grid\">\n @for (category of categories; track $index) {\n <div class=\"category\">\n <h3 class=\"subtitle\">{{ category.title }}</h3>\n \n @for (item of category.items; track $index){\n <div class=\"item\">\n <span class=\"label\">{{ item.label }}</span>\n <div class=\"bar\">\n <div class=\"fill\" [style.width.%]=\"item.value\"></div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n \n</div>\n", styles: [":root{--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem}.category-progress{text-align:start;padding:2rem 10rem;align-items:start}@media (max-width: 768px){.category-progress{padding:2rem 4rem}}.title{text-transform:uppercase}.progress-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:2rem}.category{display:flex;flex-direction:column;gap:1.5rem}.category-title{font-weight:600;font-size:1.1rem}.item .label{font-size:.9rem;margin-bottom:.3rem;display:block}.item .bar{background-color:var(--progress-bg);height:6px;border-radius:3px;overflow:hidden}.item .bar .fill{background-color:var(--progress-color);height:100%;width:0;transition:width .3s ease}\n"] }]
317
422
  }], propDecorators: { pretitle: [{
318
423
  type: Input
319
424
  }], title: [{
@@ -408,8 +513,10 @@ const mapHeaderClear = (props) => {
408
513
  const navItems = mapNavModalWithLang(props?.['nav-modal']?.navLinks || [], currentLang);
409
514
  return {
410
515
  logo: mapImage(props?.logo),
516
+ logoDark: mapImage(props?.logoDark),
411
517
  lang: currentLang,
412
- navItems: navItems
518
+ navItems: navItems,
519
+ homeLink: navItems[0]
413
520
  };
414
521
  };
415
522
 
@@ -552,5 +659,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
552
659
  * Generated bundle index. Do not edit.
553
660
  */
554
661
 
555
- export { CategoryProgressComponent, Default, HeaderClearComponent, HeaderMobileComponent, HeroSectionComponent, LangModalComponent, LinkType, LinkTypeDirective, MapperService, NavModalComponent, ScreenSizerService, SectionIntroComponent, componentMappers, mapButtons, mapImage, mapImageOrGallery };
662
+ export { CategoryProgressComponent, Default, HeaderClearComponent, HeaderMobileComponent, HeroSectionComponent, LangModalComponent, LinkType, LinkTypeDirective, MapperService, NavModalComponent, ScreenSizerService, SectionIntroComponent, ThemeService, componentMappers, mapButtons, mapImage, mapImageOrGallery };
556
663
  //# sourceMappingURL=lluc_llull-ui-lib.mjs.map