@lluc_llull/ui-lib 0.15.1 → 0.16.1

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 (137) hide show
  1. package/{lib/components/core/content → content}/hero-section/hero-section.component.d.ts +1 -1
  2. package/{lib/components/core/content → content}/hero-section/hero-section.interface.d.ts +1 -1
  3. package/{lib/components/core/content → content}/section-intro/section-intro.component.d.ts +1 -1
  4. package/{lib/directives → directives}/link-type.directive.d.ts +1 -1
  5. package/{lib/components/core/feedback → feedback}/404/404.component.d.ts +1 -1
  6. package/{lib/components/core/feedback → feedback}/404/404.inteface.d.ts +1 -1
  7. package/fesm2022/lluc_llull-ui-lib-content.mjs +104 -0
  8. package/fesm2022/lluc_llull-ui-lib-content.mjs.map +1 -0
  9. package/fesm2022/lluc_llull-ui-lib-directives.mjs +121 -0
  10. package/fesm2022/lluc_llull-ui-lib-directives.mjs.map +1 -0
  11. package/fesm2022/{lluc_llull-ui-lib-src-lib-effects.mjs → lluc_llull-ui-lib-effects.mjs} +1 -1
  12. package/fesm2022/lluc_llull-ui-lib-effects.mjs.map +1 -0
  13. package/fesm2022/lluc_llull-ui-lib-enums.mjs +15 -0
  14. package/fesm2022/lluc_llull-ui-lib-enums.mjs.map +1 -0
  15. package/fesm2022/lluc_llull-ui-lib-feedback.mjs +32 -0
  16. package/fesm2022/lluc_llull-ui-lib-feedback.mjs.map +1 -0
  17. package/fesm2022/lluc_llull-ui-lib-footers.mjs +101 -0
  18. package/fesm2022/lluc_llull-ui-lib-footers.mjs.map +1 -0
  19. package/fesm2022/lluc_llull-ui-lib-headers.mjs +148 -0
  20. package/fesm2022/lluc_llull-ui-lib-headers.mjs.map +1 -0
  21. package/fesm2022/lluc_llull-ui-lib-interfaces.mjs +4 -0
  22. package/fesm2022/lluc_llull-ui-lib-interfaces.mjs.map +1 -0
  23. package/fesm2022/lluc_llull-ui-lib-mapper.mjs +188 -0
  24. package/fesm2022/lluc_llull-ui-lib-mapper.mjs.map +1 -0
  25. package/fesm2022/lluc_llull-ui-lib-modals.mjs +65 -0
  26. package/fesm2022/lluc_llull-ui-lib-modals.mjs.map +1 -0
  27. package/fesm2022/lluc_llull-ui-lib-screen-sizer.mjs +91 -0
  28. package/fesm2022/lluc_llull-ui-lib-screen-sizer.mjs.map +1 -0
  29. package/fesm2022/lluc_llull-ui-lib-shared.mjs +70 -0
  30. package/fesm2022/lluc_llull-ui-lib-shared.mjs.map +1 -0
  31. package/fesm2022/{lluc_llull-ui-lib-src-lib-sliders.mjs → lluc_llull-ui-lib-sliders.mjs} +1 -1
  32. package/fesm2022/lluc_llull-ui-lib-sliders.mjs.map +1 -0
  33. package/fesm2022/lluc_llull-ui-lib-theme.mjs +81 -0
  34. package/fesm2022/lluc_llull-ui-lib-theme.mjs.map +1 -0
  35. package/fesm2022/lluc_llull-ui-lib-utils.mjs +43 -0
  36. package/fesm2022/lluc_llull-ui-lib-utils.mjs.map +1 -0
  37. package/fesm2022/lluc_llull-ui-lib.mjs +14 -1110
  38. package/fesm2022/lluc_llull-ui-lib.mjs.map +1 -1
  39. package/{lib/components/core/footers → footers}/legal-footer/legal-footer.component.d.ts +1 -1
  40. package/{lib/components/core/footers → footers}/legal-footer/legal-footer.interface.d.ts +1 -1
  41. package/{lib/components/core/footers → footers}/links-footer/links-footer.component.d.ts +1 -1
  42. package/footers/links-footer/links-footer.interface.d.ts +4 -0
  43. package/{lib/components/core/footers → footers}/social-footer/social-footer.component.d.ts +1 -1
  44. package/{lib/components/core/footers → footers}/social-footer/social-footer.interface.d.ts +1 -1
  45. package/{lib/components/core/footers → footers}/visual-footer/visual-footer.component.d.ts +1 -1
  46. package/{lib/components/core/footers → footers}/visual-footer/visual-footer.interface.d.ts +1 -1
  47. package/{lib/components/core/headers → headers}/header-clear/header-clear.component.d.ts +2 -2
  48. package/{lib/components/core/headers → headers}/header-clear/header-clear.interface.d.ts +1 -1
  49. package/{lib/components/core/headers → headers}/header-mobile/header-mobile.component.d.ts +2 -4
  50. package/{lib/components/core/headers → headers}/header-mobile/header-mobile.interface.d.ts +1 -1
  51. package/{lib/interfaces → interfaces}/ui-lib-button.interface.d.ts +1 -1
  52. package/{lib/interfaces → interfaces}/ui-lib-nav-items.interface.d.ts +1 -1
  53. package/lib/ui-lib.component.d.ts +5 -0
  54. package/mapper/component-mappers/index.d.ts +12 -0
  55. package/{lib/services/mapper → mapper}/component-mappers/lang-modal.mapper.d.ts +1 -1
  56. package/{lib/services/mapper → mapper}/component-mappers/nav-modal.mapper.d.ts +1 -1
  57. package/{lib/services/mapper → mapper}/mapper.service.d.ts +1 -1
  58. package/{lib/components/core/modals → modals}/lang-modal/lang-modal.component.d.ts +1 -1
  59. package/{lib/components/core/modals → modals}/nav-modal/nav-modal.component.d.ts +1 -1
  60. package/{lib/components/core/modals → modals}/nav-modal/nav-modal.interface.d.ts +1 -1
  61. package/package.json +59 -7
  62. package/public-api.d.ts +1 -8
  63. package/{lib/utils → utils}/utils.d.ts +1 -2
  64. package/fesm2022/lluc_llull-ui-lib-src-lib-effects.mjs.map +0 -1
  65. package/fesm2022/lluc_llull-ui-lib-src-lib-sliders.mjs.map +0 -1
  66. package/lib/components/core/footers/links-footer/links-footer.interface.d.ts +0 -4
  67. package/lib/components/core/index.d.ts +0 -5
  68. package/lib/services/index.d.ts +0 -3
  69. package/lib/services/mapper/component-mappers/index.d.ts +0 -1
  70. package/src/lib/effects/dynamic-background/dynamic-background.component.d.ts +0 -26
  71. package/src/lib/effects/dynamic-background/effects/dynamic-effect.interface.d.ts +0 -6
  72. package/src/lib/effects/dynamic-background/effects/effect-registry.d.ts +0 -3
  73. package/src/lib/effects/dynamic-background/effects/sphere-deform/sphere-deform.effect.d.ts +0 -13
  74. package/src/lib/effects/dynamic-background/index.d.ts +0 -1
  75. package/src/lib/effects/index.d.ts +0 -1
  76. package/src/lib/sliders/swiper.directive.d.ts +0 -12
  77. /package/{lib/components/core/content → content}/category-progress/category-progress.component.d.ts +0 -0
  78. /package/{lib/components/core/content → content}/category-progress/category-progress.interface.d.ts +0 -0
  79. /package/{lib/components/core/content → content}/category-progress/index.d.ts +0 -0
  80. /package/{lib/components/core/content → content}/hero-section/hero-section.stories.d.ts +0 -0
  81. /package/{lib/components/core/content → content}/hero-section/index.d.ts +0 -0
  82. /package/{lib/components/core/content → content}/index.d.ts +0 -0
  83. /package/{lib/components/core/content → content}/section-intro/index.d.ts +0 -0
  84. /package/{lib/components/core/content → content}/section-intro/section-intro.interface.d.ts +0 -0
  85. /package/{lib/directives → directives}/index.d.ts +0 -0
  86. /package/{lib/effects → effects}/dynamic-background/dynamic-background.component.d.ts +0 -0
  87. /package/{lib/effects → effects}/dynamic-background/effects/dynamic-effect.interface.d.ts +0 -0
  88. /package/{lib/effects → effects}/dynamic-background/effects/effect-registry.d.ts +0 -0
  89. /package/{lib/effects → effects}/dynamic-background/effects/sphere-deform/sphere-deform.effect.d.ts +0 -0
  90. /package/{lib/effects → effects}/dynamic-background/index.d.ts +0 -0
  91. /package/{lib/effects → effects}/index.d.ts +0 -0
  92. /package/{lib/Enum → enums}/index.d.ts +0 -0
  93. /package/{lib/Enum → enums}/link-type.enum.d.ts +0 -0
  94. /package/{lib/components/core/feedback → feedback}/404/index.d.ts +0 -0
  95. /package/{lib/components/core/feedback → feedback}/index.d.ts +0 -0
  96. /package/{lib/components/core/footers → footers}/index.d.ts +0 -0
  97. /package/{lib/components/core/footers → footers}/legal-footer/index.d.ts +0 -0
  98. /package/{lib/components/core/footers → footers}/links-footer/index.d.ts +0 -0
  99. /package/{lib/components/core/footers → footers}/social-footer/index.d.ts +0 -0
  100. /package/{lib/components/core/footers → footers}/visual-footer/index.d.ts +0 -0
  101. /package/{lib/components/core/headers → headers}/header-clear/index.d.ts +0 -0
  102. /package/{lib/components/core/headers → headers}/header-mobile/index.d.ts +0 -0
  103. /package/{lib/components/core/headers → headers}/index.d.ts +0 -0
  104. /package/{lib/interfaces → interfaces}/index.d.ts +0 -0
  105. /package/{lib/interfaces → interfaces}/page-config.interface.d.ts +0 -0
  106. /package/{lib/interfaces → interfaces}/site-config.interface.d.ts +0 -0
  107. /package/{lib/interfaces → interfaces}/ui-lib-address.interface.d.ts +0 -0
  108. /package/{lib/interfaces → interfaces}/ui-lib-image.interface.d.ts +0 -0
  109. /package/{lib/interfaces → interfaces}/ui-lib-lang-item.interface.d.ts +0 -0
  110. /package/{lib/services/mapper → mapper}/cdn.token.d.ts +0 -0
  111. /package/{lib/services/mapper → mapper}/component-mappers/404.mapper.d.ts +0 -0
  112. /package/{lib/services/mapper → mapper}/component-mappers/category-progress.mapper.d.ts +0 -0
  113. /package/{lib/services/mapper → mapper}/component-mappers/header-clear.mapper.d.ts +0 -0
  114. /package/{lib/services/mapper → mapper}/component-mappers/hero-section.mapper.d.ts +0 -0
  115. /package/{lib/services/mapper → mapper}/component-mappers/legal-footer.mapper.d.ts +0 -0
  116. /package/{lib/services/mapper → mapper}/component-mappers/links-footer.mapper.d.ts +0 -0
  117. /package/{lib/services/mapper → mapper}/component-mappers/section-intro.mapper.d.ts +0 -0
  118. /package/{lib/services/mapper → mapper}/component-mappers/social-footer.mapper.d.ts +0 -0
  119. /package/{lib/services/mapper → mapper}/component-mappers/types.d.ts +0 -0
  120. /package/{lib/services/mapper → mapper}/component-mappers/visual-footer.mapper.d.ts +0 -0
  121. /package/{lib/services/mapper → mapper}/index.d.ts +0 -0
  122. /package/{lib/components/core/modals → modals}/index.d.ts +0 -0
  123. /package/{lib/components/core/modals → modals}/lang-modal/index.d.ts +0 -0
  124. /package/{lib/components/core/modals → modals}/lang-modal/lang-modal.interface.d.ts +0 -0
  125. /package/{lib/components/core/modals → modals}/nav-modal/index.d.ts +0 -0
  126. /package/{lib/services/screen-sizer → screen-sizer}/index.d.ts +0 -0
  127. /package/{lib/services/screen-sizer → screen-sizer}/screen-sizer.service.d.ts +0 -0
  128. /package/{lib/components/shared → shared}/index.d.ts +0 -0
  129. /package/{lib/components/shared → shared}/ui-icon/index.d.ts +0 -0
  130. /package/{lib/components/shared → shared}/ui-icon/ui-icon.component.d.ts +0 -0
  131. /package/{lib/components/shared → shared}/ui-icon/ui-icon.interface.d.ts +0 -0
  132. /package/{lib/components/shared → shared}/ui-icon/ui-icon.mock.d.ts +0 -0
  133. /package/{src/lib/sliders → sliders}/index.d.ts +0 -0
  134. /package/{lib/sliders → sliders}/swiper.directive.d.ts +0 -0
  135. /package/{lib/services/theme → theme}/index.d.ts +0 -0
  136. /package/{lib/services/theme → theme}/theme.service.d.ts +0 -0
  137. /package/{lib/utils → utils}/index.d.ts +0 -0
@@ -1,1126 +1,30 @@
1
- import * as i1$1 from '@angular/common';
2
- import { CommonModule, isPlatformBrowser } from '@angular/common';
3
1
  import * as i0 from '@angular/core';
4
- import { Input, ChangeDetectionStrategy, Component, EventEmitter, inject, PLATFORM_ID, HostListener, Output, Directive, Optional, Inject, Injectable, ViewChild, InjectionToken, signal } from '@angular/core';
5
- import * as i1 from '@angular/router';
6
- import * as simpleIcons from 'simple-icons';
7
- import * as i2 from 'lucide-angular';
8
- import { LucideAngularModule } from 'lucide-angular';
9
- import Swiper from 'swiper';
10
- import { Navigation, Pagination, Autoplay } from 'swiper/modules';
11
- import * as i1$2 from '@angular/material/dialog';
12
- import { MAT_DIALOG_DATA } from '@angular/material/dialog';
13
- import { BehaviorSubject, fromEvent } from 'rxjs';
14
- import * as THREE from 'three';
15
- import { debounceTime, map, distinctUntilChanged, startWith } from 'rxjs/operators';
2
+ import { Component } from '@angular/core';
16
3
 
17
- class CategoryProgressComponent {
18
- pretitle;
19
- title;
20
- categories;
21
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: CategoryProgressComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
22
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.19", 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</div>\n", styles: [":root{--font-titles: \"Bebas Neue\", system-ui, sans-serif;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem;--border-radius: 8px}.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 });
4
+ class UiLibComponent {
5
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: UiLibComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.19", type: UiLibComponent, isStandalone: true, selector: "lib-ui-lib", ngImport: i0, template: `
7
+ <p>ui-lib works!</p>
8
+ `, isInline: true, styles: [""] });
23
9
  }
24
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: CategoryProgressComponent, decorators: [{
10
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: UiLibComponent, decorators: [{
25
11
  type: Component,
26
- 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</div>\n", styles: [":root{--font-titles: \"Bebas Neue\", system-ui, sans-serif;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem;--border-radius: 8px}.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"] }]
27
- }], propDecorators: { pretitle: [{
28
- type: Input
29
- }], title: [{
30
- type: Input
31
- }], categories: [{
32
- type: Input
33
- }] } });
34
-
35
- var LinkType;
36
- (function (LinkType) {
37
- LinkType["Internal"] = "internal";
38
- LinkType["External"] = "external";
39
- LinkType["Anchor"] = "anchor";
40
- LinkType["Pdf"] = "pdf";
41
- LinkType["NoLink"] = "nolink";
42
- })(LinkType || (LinkType = {}));
43
-
44
- class LinkTypeDirective {
45
- router;
46
- elRef;
47
- linkType;
48
- href;
49
- anchorClicked = new EventEmitter();
50
- platformId = inject(PLATFORM_ID);
51
- isBrowser = isPlatformBrowser(this.platformId);
52
- constructor(router, elRef) {
53
- this.router = router;
54
- this.elRef = elRef;
55
- }
56
- ngOnInit() {
57
- this.setupAttributes();
58
- }
59
- onClick(event) {
60
- if (!this.linkType || !this.href)
61
- return;
62
- switch (this.linkType) {
63
- case 'internal':
64
- event.preventDefault();
65
- this.navigateInternal(this.href);
66
- break;
67
- case 'anchor':
68
- event.preventDefault();
69
- this.scrollToAnchor(this.href);
70
- break;
71
- case 'nolink':
72
- event.preventDefault();
73
- break;
74
- case 'external':
75
- case 'pdf':
76
- default:
77
- break;
78
- }
79
- }
80
- setupAttributes() {
81
- const element = this.elRef.nativeElement;
82
- const resolvedHref = this.resolveHref();
83
- if (!resolvedHref)
84
- return;
85
- element.setAttribute('href', resolvedHref);
86
- if (this.linkType === 'external' || this.linkType === 'pdf') {
87
- element.setAttribute('target', '_blank');
88
- element.setAttribute('rel', 'noopener noreferrer nofollow');
89
- }
90
- }
91
- resolveHref() {
92
- if (!this.href)
93
- return '';
94
- // si ya es absoluta, no tocarla
95
- if (this.href.startsWith('/')) {
96
- return this.href;
97
- }
98
- if (this.linkType === 'internal') {
99
- const lang = this.getCurrentLang();
100
- return `/${lang}/${this.href}`;
101
- }
102
- return this.href;
103
- }
104
- navigateInternal(url) {
105
- // si ya es absoluta, navega directamente
106
- if (url.startsWith('/')) {
107
- this.router.navigateByUrl(url);
108
- return;
109
- }
110
- const lang = this.getCurrentLang();
111
- this.anchorClicked.emit();
112
- this.router.navigate(['/', lang, url]);
113
- }
114
- getCurrentLang() {
115
- const firstSegment = this.router.url.split('?')[0].split('#')[0].split('/')[1];
116
- return firstSegment || 'es';
117
- }
118
- scrollToAnchor(id) {
119
- if (!this.isBrowser)
120
- return;
121
- const cleanId = id.replace(/^#/, '');
122
- const el = document.getElementById(cleanId);
123
- if (!el)
124
- return;
125
- const yOffset = -160;
126
- const y = el.getBoundingClientRect().top + window.scrollY + yOffset;
127
- window.scrollTo({
128
- top: y,
129
- behavior: 'smooth',
130
- });
131
- this.anchorClicked.emit();
132
- }
133
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: LinkTypeDirective, deps: [{ token: i1.Router }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
134
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.19", type: LinkTypeDirective, isStandalone: true, selector: "[linkType]", inputs: { linkType: "linkType", href: "href" }, outputs: { anchorClicked: "anchorClicked" }, host: { listeners: { "click": "onClick($event)" } }, ngImport: i0 });
135
- }
136
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: LinkTypeDirective, decorators: [{
137
- type: Directive,
138
- args: [{
139
- selector: '[linkType]',
140
- standalone: true,
141
- }]
142
- }], ctorParameters: () => [{ type: i1.Router }, { type: i0.ElementRef }], propDecorators: { linkType: [{
143
- type: Input
144
- }], href: [{
145
- type: Input
146
- }], anchorClicked: [{
147
- type: Output
148
- }], onClick: [{
149
- type: HostListener,
150
- args: ['click', ['$event']]
151
- }] } });
152
-
153
- class HeroSectionComponent {
154
- pretitle;
155
- title;
156
- subtitle;
157
- text;
158
- buttons;
159
- highlight;
160
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: HeroSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
161
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.19", 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>\n {{ 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;font-size:4.5rem}.title .highlight-text{cursor:help;display:inline;position:relative;z-index:99}.title .highlight-text .wave-wrapper{position:absolute;top:90%;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 });
162
- }
163
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: HeroSectionComponent, decorators: [{
164
- type: Component,
165
- 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>\n {{ 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;font-size:4.5rem}.title .highlight-text{cursor:help;display:inline;position:relative;z-index:99}.title .highlight-text .wave-wrapper{position:absolute;top:90%;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"] }]
166
- }], propDecorators: { pretitle: [{
167
- type: Input
168
- }], title: [{
169
- type: Input
170
- }], subtitle: [{
171
- type: Input
172
- }], text: [{
173
- type: Input
174
- }], buttons: [{
175
- type: Input
176
- }], highlight: [{
177
- type: Input
178
- }] } });
179
-
180
- var heroSection_stories = {
181
- title: 'Core/Content/HeroSection',
182
- component: HeroSectionComponent,
183
- tags: ['autodocs'],
184
- argTypes: {
185
- title: { control: 'text' },
186
- subtitle: { control: 'text' },
187
- text: { control: 'text' },
188
- buttons: { control: 'object' },
189
- },
190
- };
191
- const Default = {
192
- args: {
193
- title: 'Título de ejemplo',
194
- subtitle: 'Subtítulo de ejemplo',
195
- text: 'Texto descriptivo de ejemplo para el Hero Section.',
196
- buttons: [
197
- { label: 'Botón 1', url: 'https://www.google.com', linkType: LinkType.External },
198
- { label: 'Botón 2', url: 'https://www.google.com', linkType: LinkType.External },
199
- ],
200
- },
201
- };
202
-
203
- class SectionIntroComponent {
204
- pretitle;
205
- title;
206
- subtitle;
207
- text;
208
- button;
209
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: SectionIntroComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
210
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.19", 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 [href]=\"button.url\" [linkType]=\"button.linkType\" class=\"btn btn-link\">\n {{ button.label }}\n </a>\n }\n</div>\n", styles: [":root{--font-titles: \"Bebas Neue\", system-ui, sans-serif;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem;--border-radius: 8px}.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 });
211
- }
212
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: SectionIntroComponent, decorators: [{
213
- type: Component,
214
- 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 [href]=\"button.url\" [linkType]=\"button.linkType\" class=\"btn btn-link\">\n {{ button.label }}\n </a>\n }\n</div>\n", styles: [":root{--font-titles: \"Bebas Neue\", system-ui, sans-serif;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem;--border-radius: 8px}.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"] }]
215
- }], propDecorators: { pretitle: [{
216
- type: Input
217
- }], title: [{
218
- type: Input
219
- }], subtitle: [{
220
- type: Input
221
- }], text: [{
222
- type: Input
223
- }], button: [{
224
- type: Input
225
- }] } });
226
-
227
- class LegalFooterComponent {
228
- year;
229
- brand;
230
- credits;
231
- links;
232
- variant = 'simple';
233
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: LegalFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
234
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.19", type: LegalFooterComponent, isStandalone: true, selector: "lib-legal-footer", inputs: { year: "year", brand: "brand", credits: "credits", links: "links", variant: "variant" }, ngImport: i0, template: "<div class=\"legal-footer\" [ngClass]=\"variant\">\n <!-- Variante simple -->\n @if (variant === 'simple') {\n <div class=\"legal-footer__simple\">\n <span class=\"legal-footer__simple-brand\">\n <b>{{ brand }} \u00A9 {{ year }}</b>\n </span>\n <span class=\"legal-footer__simple-credits\">{{ credits }}</span>\n </div>\n }\n\n <!-- Variante extendida -->\n @if (variant === 'extended') {\n <div class=\"legal-footer__extended\">\n <span class=\"legal-footer__year\">\n <b>{{ brand }} \u00A9 {{ year }}</b>\n </span>\n\n <div class=\"legal-footer__right\">\n @if (links?.length) {\n <ul class=\"legal-footer__links\">\n @for (link of links; track $index) {\n <li>\n <a [href]=\"link.url\">{{ link.label }}</a>\n </li>\n }\n <li class=\"legal-footer__credits\">{{ credits }}</li>\n </ul>\n }\n </div>\n </div>\n }\n</div>\n", styles: [":root[data-theme=dark]{color-scheme:dark;--color-primary: #007bff;--color-secondary: #8a94a1;--color-text: #f3f4f6;--color-bg: #0f0f10;--button-primary-bg: #007bff;--button-primary-text: #f9f9f9;--button-primary-bg-hover: #033468;--button-primary-text-hover: #f9f9f9;--button-primary-outline-border: #020202;--button-primary-outline-text: #020202;--button-primary-outline-bg-hover: #007bff;--button-primary-outline-text-hover: #f9f9f9;--button-secondary-bg: #2b3035;--button-secondary-text: #f9f9f9;--button-secondary-bg-hover: #1c1e20;--button-secondary-text-hover: #f9f9f9;--button-link-text: #f3f4f6;--button-link-text-hover: #79b6ff;--header-clear-bg: #0f0f10;--header-mobile-bg: #0f0f10;--header-logo-text: #f9f9f9;--modal-bg: #17181a;--close-btn: #f3f4f6;--item-text: #f3f4f6;--progress-color: #f9f9f9;--progress-bg: #79b6ff;--footer-bg: #0f0f10;--footer-text: #f3f4f6;--footer-text-hover: #79b6ff;--footer-links: #f3f4f6;--footer-links-hover: #79b6ff;--footer-arrows: #fff;--footer-arrows-hover: #0f0f10;--footer-arrows-bg: #dddddd;--footer-arrows-bg-hover: #f3f3f3}:root,:root[data-theme=light]{color-scheme:light;--color-primary: #007bff;--color-secondary: #6c757d;--color-text: #111111;--color-bg: #f9f9f9;--button-primary-bg: #007bff;--button-primary-text: #f9f9f9;--button-primary-bg-hover: #033468;--button-primary-text-hover: #f9f9f9;--button-primary-outline-border: #020202;--button-primary-outline-text: #020202;--button-primary-outline-bg-hover: #007bff;--button-primary-outline-text-hover: #f9f9f9;--button-secondary-bg: #6c757d;--button-secondary-text: #f9f9f9;--button-secondary-bg-hover: #1c1e20;--button-secondary-text-hover: #f9f9f9;--button-link-text: #111111;--button-link-text-hover: #007bff;--header-clear-bg: #007bff;--header-mobile-bg: #007bff;--header-logo-text: #f9f9f9;--modal-bg: #f9f9f9;--close-btn: #111111;--item-text: #111111;--progress-color: #79b6ff;--progress-bg: #dde8f5;--footer-bg: #dadada;--footer-text: #000;--footer-text-hover: #79b6ff;--footer-links: #000;--footer-links-hover: #79b6ff;--footer-arrows: #fff;--footer-arrows-hover: #fff;--footer-arrows-bg: #b6b6b6;--footer-arrows-bg-hover: #8b8a8a}:root{--font-titles: \"Bebas Neue\", system-ui, sans-serif;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem;--border-radius: 8px}.legal-footer{font-size:var(--font-size-base);padding:1rem 0;text-align:center;background-color:var(--footer-bg)}.legal-footer__simple{display:flex;justify-content:space-between;gap:1rem;color:var(--footer-text)}.legal-footer__simple-brand{margin-left:3rem}.legal-footer__simple-credits{margin-right:3rem}.legal-footer__extended{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap}@media (max-width: 480px){.legal-footer__extended{flex-direction:column;align-items:flex-start;width:100%}.legal-footer__extended .legal-footer__right{display:block!important;width:100%}.legal-footer__extended .legal-footer__links{display:block;width:100%;gap:0!important}.legal-footer__extended .legal-footer__links li{width:80%;padding:1rem;margin:0 2rem;border-bottom:1px solid var(--footer-links)}.legal-footer__extended .legal-footer__links li a{display:block;width:100%;text-align:left}.legal-footer__extended .legal-footer__year,.legal-footer__extended .legal-footer__credits{width:80%;padding:1rem;margin:0 2rem;border-bottom:1px solid var(--footer-links);display:grid;justify-content:flex-start}.legal-footer__extended .legal-footer__credits{border-bottom:none}}@media (min-width: 768px){.legal-footer__extended{flex-direction:column;align-items:flex-start;width:100%}.legal-footer__extended .legal-footer__right{display:block!important;width:100%}.legal-footer__extended .legal-footer__links{display:grid;grid-template-columns:1fr 1fr;gap:0 1rem!important;width:100%}.legal-footer__extended .legal-footer__links li{width:75%;padding:1rem 0;margin:0 3rem;border-bottom:1px solid var(--footer-links)}.legal-footer__extended .legal-footer__links li a{display:block;width:100%;text-align:left}.legal-footer__extended .legal-footer__year{width:37%;padding:1rem 0;margin:0 3rem;border-bottom:1px solid var(--footer-links);display:grid;justify-content:flex-start}.legal-footer__extended .legal-footer__credits{display:grid;justify-content:flex-start}}@media (min-width: 1024px){.legal-footer__extended{flex-direction:row;justify-content:space-between;align-items:center}.legal-footer__extended .legal-footer__year{border:none;margin-left:3rem;padding:0;width:auto}.legal-footer__extended .legal-footer__right{display:flex;align-items:center;gap:2rem;width:auto}.legal-footer__extended .legal-footer__links{display:flex;gap:1.5rem;margin:0;padding:0;list-style:none;justify-content:right}.legal-footer__extended .legal-footer__links li{border:none;margin:0;padding:0;width:auto}.legal-footer__extended .legal-footer__links li a{text-align:left;padding:0}.legal-footer__extended .legal-footer__credits{margin-right:3rem!important;padding:0}}.legal-footer .legal-footer__right{display:flex;align-items:center;gap:1.5rem;flex:1}.legal-footer .legal-footer__links{list-style:none;margin:0;padding:0}.legal-footer .legal-footer__links a{text-decoration:none;color:var(--footer-links)}.legal-footer .legal-footer__links a:hover{color:var(--footer-links-hover);text-decoration:underline;text-underline-offset:2px;text-decoration-thickness:1px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
235
- }
236
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: LegalFooterComponent, decorators: [{
237
- type: Component,
238
- args: [{ selector: 'lib-legal-footer', standalone: true, imports: [CommonModule, LinkTypeDirective], template: "<div class=\"legal-footer\" [ngClass]=\"variant\">\n <!-- Variante simple -->\n @if (variant === 'simple') {\n <div class=\"legal-footer__simple\">\n <span class=\"legal-footer__simple-brand\">\n <b>{{ brand }} \u00A9 {{ year }}</b>\n </span>\n <span class=\"legal-footer__simple-credits\">{{ credits }}</span>\n </div>\n }\n\n <!-- Variante extendida -->\n @if (variant === 'extended') {\n <div class=\"legal-footer__extended\">\n <span class=\"legal-footer__year\">\n <b>{{ brand }} \u00A9 {{ year }}</b>\n </span>\n\n <div class=\"legal-footer__right\">\n @if (links?.length) {\n <ul class=\"legal-footer__links\">\n @for (link of links; track $index) {\n <li>\n <a [href]=\"link.url\">{{ link.label }}</a>\n </li>\n }\n <li class=\"legal-footer__credits\">{{ credits }}</li>\n </ul>\n }\n </div>\n </div>\n }\n</div>\n", styles: [":root[data-theme=dark]{color-scheme:dark;--color-primary: #007bff;--color-secondary: #8a94a1;--color-text: #f3f4f6;--color-bg: #0f0f10;--button-primary-bg: #007bff;--button-primary-text: #f9f9f9;--button-primary-bg-hover: #033468;--button-primary-text-hover: #f9f9f9;--button-primary-outline-border: #020202;--button-primary-outline-text: #020202;--button-primary-outline-bg-hover: #007bff;--button-primary-outline-text-hover: #f9f9f9;--button-secondary-bg: #2b3035;--button-secondary-text: #f9f9f9;--button-secondary-bg-hover: #1c1e20;--button-secondary-text-hover: #f9f9f9;--button-link-text: #f3f4f6;--button-link-text-hover: #79b6ff;--header-clear-bg: #0f0f10;--header-mobile-bg: #0f0f10;--header-logo-text: #f9f9f9;--modal-bg: #17181a;--close-btn: #f3f4f6;--item-text: #f3f4f6;--progress-color: #f9f9f9;--progress-bg: #79b6ff;--footer-bg: #0f0f10;--footer-text: #f3f4f6;--footer-text-hover: #79b6ff;--footer-links: #f3f4f6;--footer-links-hover: #79b6ff;--footer-arrows: #fff;--footer-arrows-hover: #0f0f10;--footer-arrows-bg: #dddddd;--footer-arrows-bg-hover: #f3f3f3}:root,:root[data-theme=light]{color-scheme:light;--color-primary: #007bff;--color-secondary: #6c757d;--color-text: #111111;--color-bg: #f9f9f9;--button-primary-bg: #007bff;--button-primary-text: #f9f9f9;--button-primary-bg-hover: #033468;--button-primary-text-hover: #f9f9f9;--button-primary-outline-border: #020202;--button-primary-outline-text: #020202;--button-primary-outline-bg-hover: #007bff;--button-primary-outline-text-hover: #f9f9f9;--button-secondary-bg: #6c757d;--button-secondary-text: #f9f9f9;--button-secondary-bg-hover: #1c1e20;--button-secondary-text-hover: #f9f9f9;--button-link-text: #111111;--button-link-text-hover: #007bff;--header-clear-bg: #007bff;--header-mobile-bg: #007bff;--header-logo-text: #f9f9f9;--modal-bg: #f9f9f9;--close-btn: #111111;--item-text: #111111;--progress-color: #79b6ff;--progress-bg: #dde8f5;--footer-bg: #dadada;--footer-text: #000;--footer-text-hover: #79b6ff;--footer-links: #000;--footer-links-hover: #79b6ff;--footer-arrows: #fff;--footer-arrows-hover: #fff;--footer-arrows-bg: #b6b6b6;--footer-arrows-bg-hover: #8b8a8a}:root{--font-titles: \"Bebas Neue\", system-ui, sans-serif;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem;--border-radius: 8px}.legal-footer{font-size:var(--font-size-base);padding:1rem 0;text-align:center;background-color:var(--footer-bg)}.legal-footer__simple{display:flex;justify-content:space-between;gap:1rem;color:var(--footer-text)}.legal-footer__simple-brand{margin-left:3rem}.legal-footer__simple-credits{margin-right:3rem}.legal-footer__extended{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap}@media (max-width: 480px){.legal-footer__extended{flex-direction:column;align-items:flex-start;width:100%}.legal-footer__extended .legal-footer__right{display:block!important;width:100%}.legal-footer__extended .legal-footer__links{display:block;width:100%;gap:0!important}.legal-footer__extended .legal-footer__links li{width:80%;padding:1rem;margin:0 2rem;border-bottom:1px solid var(--footer-links)}.legal-footer__extended .legal-footer__links li a{display:block;width:100%;text-align:left}.legal-footer__extended .legal-footer__year,.legal-footer__extended .legal-footer__credits{width:80%;padding:1rem;margin:0 2rem;border-bottom:1px solid var(--footer-links);display:grid;justify-content:flex-start}.legal-footer__extended .legal-footer__credits{border-bottom:none}}@media (min-width: 768px){.legal-footer__extended{flex-direction:column;align-items:flex-start;width:100%}.legal-footer__extended .legal-footer__right{display:block!important;width:100%}.legal-footer__extended .legal-footer__links{display:grid;grid-template-columns:1fr 1fr;gap:0 1rem!important;width:100%}.legal-footer__extended .legal-footer__links li{width:75%;padding:1rem 0;margin:0 3rem;border-bottom:1px solid var(--footer-links)}.legal-footer__extended .legal-footer__links li a{display:block;width:100%;text-align:left}.legal-footer__extended .legal-footer__year{width:37%;padding:1rem 0;margin:0 3rem;border-bottom:1px solid var(--footer-links);display:grid;justify-content:flex-start}.legal-footer__extended .legal-footer__credits{display:grid;justify-content:flex-start}}@media (min-width: 1024px){.legal-footer__extended{flex-direction:row;justify-content:space-between;align-items:center}.legal-footer__extended .legal-footer__year{border:none;margin-left:3rem;padding:0;width:auto}.legal-footer__extended .legal-footer__right{display:flex;align-items:center;gap:2rem;width:auto}.legal-footer__extended .legal-footer__links{display:flex;gap:1.5rem;margin:0;padding:0;list-style:none;justify-content:right}.legal-footer__extended .legal-footer__links li{border:none;margin:0;padding:0;width:auto}.legal-footer__extended .legal-footer__links li a{text-align:left;padding:0}.legal-footer__extended .legal-footer__credits{margin-right:3rem!important;padding:0}}.legal-footer .legal-footer__right{display:flex;align-items:center;gap:1.5rem;flex:1}.legal-footer .legal-footer__links{list-style:none;margin:0;padding:0}.legal-footer .legal-footer__links a{text-decoration:none;color:var(--footer-links)}.legal-footer .legal-footer__links a:hover{color:var(--footer-links-hover);text-decoration:underline;text-underline-offset:2px;text-decoration-thickness:1px}\n"] }]
239
- }], propDecorators: { year: [{
240
- type: Input
241
- }], brand: [{
242
- type: Input
243
- }], credits: [{
244
- type: Input
245
- }], links: [{
246
- type: Input
247
- }], variant: [{
248
- type: Input
249
- }] } });
250
-
251
- class LinksFooterComponent {
252
- links;
253
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: LinksFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
254
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.19", type: LinksFooterComponent, isStandalone: true, selector: "lib-links-footer", inputs: { links: "links" }, ngImport: i0, template: "@if (links) {\n <div class=\"links-footer\">\n <ul>\n @for (link of links; track $index) {\n <li>\n <a [href]=\"link.url\" [linkType]=\"link.linkType\" class=\"btn btn-link\">\n {{ link.label }}\n </a>\n </li>\n }\n </ul>\n </div>\n}\n", styles: [":root{--font-titles: \"Bebas Neue\", system-ui, sans-serif;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem;--border-radius: 8px}.links-footer ul{display:flex;gap:.5rem;list-style:none;padding:0;margin:0;justify-content:center;flex-wrap:wrap}.links-footer ul li{position:relative}.links-footer ul li:before{content:\"\";position:absolute;display:block;height:15px;width:1px;background-color:var(--button-link-text);left:0;top:50%;transform:translateY(-50%)}.links-footer ul li:first-child:before{content:none}.links-footer a.btn-link{font-weight:400;font-size:.9rem;text-decoration:none;color:var(--button-link-text)}.links-footer a.btn-link:after{content:none!important}.links-footer a.btn-link:hover{color:var(--button-link-text-hover);text-decoration:underline;text-underline-offset:2px;text-decoration-thickness:1px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: LinkTypeDirective, selector: "[linkType]", inputs: ["linkType", "href"], outputs: ["anchorClicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
255
- }
256
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: LinksFooterComponent, decorators: [{
257
- type: Component,
258
- args: [{ selector: 'lib-links-footer', standalone: true, imports: [CommonModule, LinkTypeDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (links) {\n <div class=\"links-footer\">\n <ul>\n @for (link of links; track $index) {\n <li>\n <a [href]=\"link.url\" [linkType]=\"link.linkType\" class=\"btn btn-link\">\n {{ link.label }}\n </a>\n </li>\n }\n </ul>\n </div>\n}\n", styles: [":root{--font-titles: \"Bebas Neue\", system-ui, sans-serif;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem;--border-radius: 8px}.links-footer ul{display:flex;gap:.5rem;list-style:none;padding:0;margin:0;justify-content:center;flex-wrap:wrap}.links-footer ul li{position:relative}.links-footer ul li:before{content:\"\";position:absolute;display:block;height:15px;width:1px;background-color:var(--button-link-text);left:0;top:50%;transform:translateY(-50%)}.links-footer ul li:first-child:before{content:none}.links-footer a.btn-link{font-weight:400;font-size:.9rem;text-decoration:none;color:var(--button-link-text)}.links-footer a.btn-link:after{content:none!important}.links-footer a.btn-link:hover{color:var(--button-link-text-hover);text-decoration:underline;text-underline-offset:2px;text-decoration-thickness:1px}\n"] }]
259
- }], propDecorators: { links: [{
260
- type: Input
261
- }] } });
262
-
263
- class UiIconComponent {
264
- name;
265
- size = 24;
266
- color = 'currentColor';
267
- icon;
268
- ngOnChanges() {
269
- this.icon = this.resolveBrandIcon();
270
- }
271
- get isBrandIcon() {
272
- return !!this.icon;
273
- }
274
- get brandIcon() {
275
- return this.icon ?? null;
276
- }
277
- resolveBrandIcon() {
278
- if (!this.name)
279
- return null;
280
- const key = 'si' + this.name.replace(/[^a-z0-9]/gi, '').replace(/^\w/, (c) => c.toUpperCase());
281
- return simpleIcons[key] ?? null;
282
- }
283
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: UiIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
284
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.19", type: UiIconComponent, isStandalone: true, selector: "ui-icon", inputs: { name: "name", size: "size", color: "color" }, usesOnChanges: true, ngImport: i0, template: "<!-- SimpleIcons -->\n<ng-container *ngIf=\"isBrandIcon; else lucideIcon\">\n <svg\n class=\"ui-icon ui-icon--brand\"\n [attr.width]=\"size\"\n [attr.height]=\"size\"\n [attr.fill]=\"color\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path [attr.d]=\"brandIcon?.path\"></path>\n </svg>\n</ng-container>\n\n<!-- Lucide -->\n<ng-template #lucideIcon>\n <lucide-icon\n class=\"ui-icon ui-icon--lucide\"\n [name]=\"name\"\n [size]=\"size\"\n [color]=\"color\"\n ></lucide-icon>\n</ng-template>\n", styles: [".ui-icon{display:inline-flex;align-items:center;justify-content:center;line-height:0;flex-shrink:0}.ui-icon--brand svg{display:block;width:100%!important;height:100%!important}.ui-icon--lucide{display:inline-flex}.ui-icon--lucide svg{display:block;width:100%!important;height:100%!important;min-width:1em;min-height:1em}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i2.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }] });
285
- }
286
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: UiIconComponent, decorators: [{
287
- type: Component,
288
- args: [{ selector: 'ui-icon', standalone: true, imports: [CommonModule, LucideAngularModule], template: "<!-- SimpleIcons -->\n<ng-container *ngIf=\"isBrandIcon; else lucideIcon\">\n <svg\n class=\"ui-icon ui-icon--brand\"\n [attr.width]=\"size\"\n [attr.height]=\"size\"\n [attr.fill]=\"color\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path [attr.d]=\"brandIcon?.path\"></path>\n </svg>\n</ng-container>\n\n<!-- Lucide -->\n<ng-template #lucideIcon>\n <lucide-icon\n class=\"ui-icon ui-icon--lucide\"\n [name]=\"name\"\n [size]=\"size\"\n [color]=\"color\"\n ></lucide-icon>\n</ng-template>\n", styles: [".ui-icon{display:inline-flex;align-items:center;justify-content:center;line-height:0;flex-shrink:0}.ui-icon--brand svg{display:block;width:100%!important;height:100%!important}.ui-icon--lucide{display:inline-flex}.ui-icon--lucide svg{display:block;width:100%!important;height:100%!important;min-width:1em;min-height:1em}\n"] }]
289
- }], propDecorators: { name: [{
290
- type: Input
291
- }], size: [{
292
- type: Input
293
- }], color: [{
294
- type: Input
295
- }] } });
296
-
297
- class MockUiIconComponent {
298
- name;
299
- size = 24;
300
- color = 'currentColor';
301
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: MockUiIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
302
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.19", type: MockUiIconComponent, isStandalone: true, selector: "ui-icon", inputs: { name: "name", size: "size", color: "color" }, ngImport: i0, template: '', isInline: true });
303
- }
304
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: MockUiIconComponent, decorators: [{
305
- type: Component,
306
- args: [{
307
- selector: 'ui-icon',
308
- standalone: true,
309
- template: '',
310
- }]
311
- }], propDecorators: { name: [{
312
- type: Input
313
- }], size: [{
314
- type: Input
315
- }], color: [{
316
- type: Input
317
- }] } });
318
-
319
- Swiper.use([Navigation, Pagination, Autoplay]);
320
- class SwiperDirective {
321
- el;
322
- swiperConfig;
323
- swiperInstance;
324
- constructor(el) {
325
- this.el = el;
326
- }
327
- ngAfterViewInit() {
328
- this.swiperInstance = new Swiper(this.el.nativeElement, {
329
- spaceBetween: 16,
330
- navigation: {
331
- nextEl: '.swiper-button-next',
332
- prevEl: '.swiper-button-prev',
333
- },
334
- pagination: { clickable: true },
335
- breakpoints: {
336
- 0: { slidesPerView: 1 }, // móviles
337
- 480: { slidesPerView: 1 }, // small tablets
338
- 768: { slidesPerView: 3 }, // tablets
339
- 1024: { slidesPerView: 4 }, // laptops
340
- 1280: { slidesPerView: 7 }, // desktop → máximo 7
341
- },
342
- ...this.swiperConfig,
343
- });
344
- }
345
- ngOnDestroy() {
346
- this.swiperInstance?.destroy(true, true);
347
- }
348
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: SwiperDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
349
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.19", type: SwiperDirective, isStandalone: true, selector: "[appSwiper]", inputs: { swiperConfig: "swiperConfig" }, ngImport: i0 });
350
- }
351
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: SwiperDirective, decorators: [{
352
- type: Directive,
353
- args: [{
354
- selector: '[appSwiper]',
355
- standalone: true,
356
- }]
357
- }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { swiperConfig: [{
358
- type: Input
359
- }] } });
360
-
361
- class SocialFooterComponent {
362
- images;
363
- socials;
364
- hashtag;
365
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: SocialFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
366
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.19", type: SocialFooterComponent, isStandalone: true, selector: "lib-social-footer", inputs: { images: "images", socials: "socials", hashtag: "hashtag" }, ngImport: i0, template: "<div class=\"social-footer\">\n <div class=\"social-footer__slider-images swiper\" appSwiper>\n <div class=\"swiper-wrapper\">\n @for (image of images; track $index) {\n <div class=\"swiper-slide\">\n <img [src]=\"image?.url\" [alt]=\"image?.alt || ''\" />\n </div>\n }\n </div>\n <div class=\"swiper-button-prev\">\n <ui-icon name=\"arrow-left\" [size]=\"18\" color=\"#fff\"></ui-icon>\n </div>\n <div class=\"swiper-button-next\">\n <ui-icon name=\"arrow-right\" [size]=\"18\" color=\"#fff\"></ui-icon>\n </div>\n </div>\n\n <div class=\"social-footer__bottom-section\">\n @if (hashtag) {\n <div class=\"social-footer__hashtag\">\n <span>{{ hashtag }}</span>\n </div>\n }\n @if (socials) {\n <div class=\"social-footer__socials\">\n @for (social of socials; track $index) {\n <a [href]=\"social.url\" [attr.aria-label]=\"social.label\" [linkType]=\"social.linkType\">\n @if (social.icon) {\n <ui-icon [name]=\"social.icon\" [size]=\"28\"></ui-icon>\n }\n </a>\n }\n </div>\n }\n </div>\n</div>\n", styles: [":root[data-theme=dark]{color-scheme:dark;--color-primary: #007bff;--color-secondary: #8a94a1;--color-text: #f3f4f6;--color-bg: #0f0f10;--button-primary-bg: #007bff;--button-primary-text: #f9f9f9;--button-primary-bg-hover: #033468;--button-primary-text-hover: #f9f9f9;--button-primary-outline-border: #020202;--button-primary-outline-text: #020202;--button-primary-outline-bg-hover: #007bff;--button-primary-outline-text-hover: #f9f9f9;--button-secondary-bg: #2b3035;--button-secondary-text: #f9f9f9;--button-secondary-bg-hover: #1c1e20;--button-secondary-text-hover: #f9f9f9;--button-link-text: #f3f4f6;--button-link-text-hover: #79b6ff;--header-clear-bg: #0f0f10;--header-mobile-bg: #0f0f10;--header-logo-text: #f9f9f9;--modal-bg: #17181a;--close-btn: #f3f4f6;--item-text: #f3f4f6;--progress-color: #f9f9f9;--progress-bg: #79b6ff;--footer-bg: #0f0f10;--footer-text: #f3f4f6;--footer-text-hover: #79b6ff;--footer-links: #f3f4f6;--footer-links-hover: #79b6ff;--footer-arrows: #fff;--footer-arrows-hover: #0f0f10;--footer-arrows-bg: #dddddd;--footer-arrows-bg-hover: #f3f3f3}:root,:root[data-theme=light]{color-scheme:light;--color-primary: #007bff;--color-secondary: #6c757d;--color-text: #111111;--color-bg: #f9f9f9;--button-primary-bg: #007bff;--button-primary-text: #f9f9f9;--button-primary-bg-hover: #033468;--button-primary-text-hover: #f9f9f9;--button-primary-outline-border: #020202;--button-primary-outline-text: #020202;--button-primary-outline-bg-hover: #007bff;--button-primary-outline-text-hover: #f9f9f9;--button-secondary-bg: #6c757d;--button-secondary-text: #f9f9f9;--button-secondary-bg-hover: #1c1e20;--button-secondary-text-hover: #f9f9f9;--button-link-text: #111111;--button-link-text-hover: #007bff;--header-clear-bg: #007bff;--header-mobile-bg: #007bff;--header-logo-text: #f9f9f9;--modal-bg: #f9f9f9;--close-btn: #111111;--item-text: #111111;--progress-color: #79b6ff;--progress-bg: #dde8f5;--footer-bg: #dadada;--footer-text: #000;--footer-text-hover: #79b6ff;--footer-links: #000;--footer-links-hover: #79b6ff;--footer-arrows: #fff;--footer-arrows-hover: #fff;--footer-arrows-bg: #b6b6b6;--footer-arrows-bg-hover: #8b8a8a}:root{--font-titles: \"Bebas Neue\", system-ui, sans-serif;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem;--border-radius: 8px}.social-footer{padding:2rem 1rem;text-align:center}.social-footer__slider-images{margin:0 4rem 2rem;position:relative}.social-footer__slider-images .swiper-wrapper{display:flex;align-items:center}.social-footer__slider-images .swiper-slide{flex:0 0 auto;width:auto}.social-footer__slider-images .swiper-slide img{display:block;border-radius:.75rem;width:160px;height:auto;object-fit:cover}.social-footer__slider-images .swiper-button-prev,.social-footer__slider-images .swiper-button-next{display:flex;align-items:center;justify-content:center;position:absolute;top:50%;transform:translateY(-50%);z-index:10;width:32px;height:32px;border-radius:50%;background:var(--footer-arrows-bg);color:var(--footer-arrows)}.social-footer__slider-images .swiper-button-prev ui-icon,.social-footer__slider-images .swiper-button-prev lucide-icon,.social-footer__slider-images .swiper-button-prev svg,.social-footer__slider-images .swiper-button-next ui-icon,.social-footer__slider-images .swiper-button-next lucide-icon,.social-footer__slider-images .swiper-button-next svg{display:block;width:18px;height:18px}.social-footer__slider-images .swiper-button-prev:hover,.social-footer__slider-images .swiper-button-next:hover{background:var(--footer-arrows-bg-hover);color:var(--footer-arrows-hover)}.social-footer__slider-images .swiper-button-prev{left:-40px}.social-footer__slider-images .swiper-button-next{right:-40px}.social-footer__slider-images .swiper-button-prev:after,.social-footer__slider-images .swiper-button-next:after{content:none!important}.social-footer__bottom-section{display:flex;justify-content:space-between;align-items:flex-end;flex-wrap:wrap;gap:1rem;margin-inline:4rem}@media (max-width: 768px){.social-footer__bottom-section{flex-direction:column;align-items:center;text-align:center}}.social-footer__hashtag{font-size:2rem;font-weight:700}.social-footer__socials{display:flex;gap:1.5rem}.social-footer__socials a{font-size:1.25rem;color:var(--footer-text, #999);transition:color .3s ease}.social-footer__socials a:hover{color:var(--footer-link-hover, #000)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: LinkTypeDirective, selector: "[linkType]", inputs: ["linkType", "href"], outputs: ["anchorClicked"] }, { kind: "directive", type: SwiperDirective, selector: "[appSwiper]", inputs: ["swiperConfig"] }, { kind: "component", type: UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
367
- }
368
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: SocialFooterComponent, decorators: [{
369
- type: Component,
370
- args: [{ selector: 'lib-social-footer', standalone: true, imports: [CommonModule, LinkTypeDirective, SwiperDirective, UiIconComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"social-footer\">\n <div class=\"social-footer__slider-images swiper\" appSwiper>\n <div class=\"swiper-wrapper\">\n @for (image of images; track $index) {\n <div class=\"swiper-slide\">\n <img [src]=\"image?.url\" [alt]=\"image?.alt || ''\" />\n </div>\n }\n </div>\n <div class=\"swiper-button-prev\">\n <ui-icon name=\"arrow-left\" [size]=\"18\" color=\"#fff\"></ui-icon>\n </div>\n <div class=\"swiper-button-next\">\n <ui-icon name=\"arrow-right\" [size]=\"18\" color=\"#fff\"></ui-icon>\n </div>\n </div>\n\n <div class=\"social-footer__bottom-section\">\n @if (hashtag) {\n <div class=\"social-footer__hashtag\">\n <span>{{ hashtag }}</span>\n </div>\n }\n @if (socials) {\n <div class=\"social-footer__socials\">\n @for (social of socials; track $index) {\n <a [href]=\"social.url\" [attr.aria-label]=\"social.label\" [linkType]=\"social.linkType\">\n @if (social.icon) {\n <ui-icon [name]=\"social.icon\" [size]=\"28\"></ui-icon>\n }\n </a>\n }\n </div>\n }\n </div>\n</div>\n", styles: [":root[data-theme=dark]{color-scheme:dark;--color-primary: #007bff;--color-secondary: #8a94a1;--color-text: #f3f4f6;--color-bg: #0f0f10;--button-primary-bg: #007bff;--button-primary-text: #f9f9f9;--button-primary-bg-hover: #033468;--button-primary-text-hover: #f9f9f9;--button-primary-outline-border: #020202;--button-primary-outline-text: #020202;--button-primary-outline-bg-hover: #007bff;--button-primary-outline-text-hover: #f9f9f9;--button-secondary-bg: #2b3035;--button-secondary-text: #f9f9f9;--button-secondary-bg-hover: #1c1e20;--button-secondary-text-hover: #f9f9f9;--button-link-text: #f3f4f6;--button-link-text-hover: #79b6ff;--header-clear-bg: #0f0f10;--header-mobile-bg: #0f0f10;--header-logo-text: #f9f9f9;--modal-bg: #17181a;--close-btn: #f3f4f6;--item-text: #f3f4f6;--progress-color: #f9f9f9;--progress-bg: #79b6ff;--footer-bg: #0f0f10;--footer-text: #f3f4f6;--footer-text-hover: #79b6ff;--footer-links: #f3f4f6;--footer-links-hover: #79b6ff;--footer-arrows: #fff;--footer-arrows-hover: #0f0f10;--footer-arrows-bg: #dddddd;--footer-arrows-bg-hover: #f3f3f3}:root,:root[data-theme=light]{color-scheme:light;--color-primary: #007bff;--color-secondary: #6c757d;--color-text: #111111;--color-bg: #f9f9f9;--button-primary-bg: #007bff;--button-primary-text: #f9f9f9;--button-primary-bg-hover: #033468;--button-primary-text-hover: #f9f9f9;--button-primary-outline-border: #020202;--button-primary-outline-text: #020202;--button-primary-outline-bg-hover: #007bff;--button-primary-outline-text-hover: #f9f9f9;--button-secondary-bg: #6c757d;--button-secondary-text: #f9f9f9;--button-secondary-bg-hover: #1c1e20;--button-secondary-text-hover: #f9f9f9;--button-link-text: #111111;--button-link-text-hover: #007bff;--header-clear-bg: #007bff;--header-mobile-bg: #007bff;--header-logo-text: #f9f9f9;--modal-bg: #f9f9f9;--close-btn: #111111;--item-text: #111111;--progress-color: #79b6ff;--progress-bg: #dde8f5;--footer-bg: #dadada;--footer-text: #000;--footer-text-hover: #79b6ff;--footer-links: #000;--footer-links-hover: #79b6ff;--footer-arrows: #fff;--footer-arrows-hover: #fff;--footer-arrows-bg: #b6b6b6;--footer-arrows-bg-hover: #8b8a8a}:root{--font-titles: \"Bebas Neue\", system-ui, sans-serif;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem;--border-radius: 8px}.social-footer{padding:2rem 1rem;text-align:center}.social-footer__slider-images{margin:0 4rem 2rem;position:relative}.social-footer__slider-images .swiper-wrapper{display:flex;align-items:center}.social-footer__slider-images .swiper-slide{flex:0 0 auto;width:auto}.social-footer__slider-images .swiper-slide img{display:block;border-radius:.75rem;width:160px;height:auto;object-fit:cover}.social-footer__slider-images .swiper-button-prev,.social-footer__slider-images .swiper-button-next{display:flex;align-items:center;justify-content:center;position:absolute;top:50%;transform:translateY(-50%);z-index:10;width:32px;height:32px;border-radius:50%;background:var(--footer-arrows-bg);color:var(--footer-arrows)}.social-footer__slider-images .swiper-button-prev ui-icon,.social-footer__slider-images .swiper-button-prev lucide-icon,.social-footer__slider-images .swiper-button-prev svg,.social-footer__slider-images .swiper-button-next ui-icon,.social-footer__slider-images .swiper-button-next lucide-icon,.social-footer__slider-images .swiper-button-next svg{display:block;width:18px;height:18px}.social-footer__slider-images .swiper-button-prev:hover,.social-footer__slider-images .swiper-button-next:hover{background:var(--footer-arrows-bg-hover);color:var(--footer-arrows-hover)}.social-footer__slider-images .swiper-button-prev{left:-40px}.social-footer__slider-images .swiper-button-next{right:-40px}.social-footer__slider-images .swiper-button-prev:after,.social-footer__slider-images .swiper-button-next:after{content:none!important}.social-footer__bottom-section{display:flex;justify-content:space-between;align-items:flex-end;flex-wrap:wrap;gap:1rem;margin-inline:4rem}@media (max-width: 768px){.social-footer__bottom-section{flex-direction:column;align-items:center;text-align:center}}.social-footer__hashtag{font-size:2rem;font-weight:700}.social-footer__socials{display:flex;gap:1.5rem}.social-footer__socials a{font-size:1.25rem;color:var(--footer-text, #999);transition:color .3s ease}.social-footer__socials a:hover{color:var(--footer-link-hover, #000)}\n"] }]
371
- }], propDecorators: { images: [{
372
- type: Input
373
- }], socials: [{
374
- type: Input
375
- }], hashtag: [{
376
- type: Input
377
- }] } });
378
-
379
- class VisualFooterComponent {
380
- contactTitle;
381
- contactPhone;
382
- contactEmail;
383
- addressTitle;
384
- address;
385
- socialsTitle;
386
- socials;
387
- image;
388
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: VisualFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
389
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.19", type: VisualFooterComponent, isStandalone: true, selector: "lib-visual-footer", inputs: { contactTitle: "contactTitle", contactPhone: "contactPhone", contactEmail: "contactEmail", addressTitle: "addressTitle", address: "address", socialsTitle: "socialsTitle", socials: "socials", image: "image" }, ngImport: i0, template: "<div class=\"visual-footer\">\n <div class=\"visual-footer__texts\">\n <div class=\"visual-footer__contact\">\n @if (contactTitle) {\n <h2 class=\"title\">{{ contactTitle }}</h2>\n }\n @if (contactPhone) {\n <a [href]=\"contactPhone.url\" [linkType]=\"contactPhone.linkType\" class=\"btn btn-link\">\n <span>{{ contactPhone.label }}</span>\n </a>\n }\n @if (contactEmail) {\n <a [href]=\"contactEmail.url\" [linkType]=\"contactEmail.linkType\" class=\"btn btn-link\">\n <span>{{ contactEmail.label }}</span>\n </a>\n }\n </div>\n <div class=\"visual-footer__address\">\n @if (addressTitle) {\n <h2 class=\"title\">{{ addressTitle }}</h2>\n }\n <p class=\"text\">\n <span>{{ address?.address }}</span>\n <span>{{ address?.cp }} {{ address?.city }}</span>\n <span>{{ address?.province }} {{ address?.country }}</span>\n </p>\n </div>\n <div class=\"visual-footer__socials\">\n @if (socialsTitle) {\n <h2 class=\"title\">{{ socialsTitle }}</h2>\n }\n @if (socials) {\n @for (social of socials; track $index) {\n <a [href]=\"social.url\" [linkType]=\"social.linkType\" class=\"btn btn-link\">\n <span>{{ social.label }}</span>\n </a>\n }\n }\n </div>\n </div>\n <div class=\"visual-footer__image\">\n @if (image) {\n <img [src]=\"image.url\" [alt]=\"image.alt\" loading=\"lazy\" />\n }\n </div>\n</div>\n", styles: [":root{--font-titles: \"Bebas Neue\", system-ui, sans-serif;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem;--border-radius: 8px}:root[data-theme=dark]{color-scheme:dark;--color-primary: #007bff;--color-secondary: #8a94a1;--color-text: #f3f4f6;--color-bg: #0f0f10;--button-primary-bg: #007bff;--button-primary-text: #f9f9f9;--button-primary-bg-hover: #033468;--button-primary-text-hover: #f9f9f9;--button-primary-outline-border: #020202;--button-primary-outline-text: #020202;--button-primary-outline-bg-hover: #007bff;--button-primary-outline-text-hover: #f9f9f9;--button-secondary-bg: #2b3035;--button-secondary-text: #f9f9f9;--button-secondary-bg-hover: #1c1e20;--button-secondary-text-hover: #f9f9f9;--button-link-text: #f3f4f6;--button-link-text-hover: #79b6ff;--header-clear-bg: #0f0f10;--header-mobile-bg: #0f0f10;--header-logo-text: #f9f9f9;--modal-bg: #17181a;--close-btn: #f3f4f6;--item-text: #f3f4f6;--progress-color: #f9f9f9;--progress-bg: #79b6ff;--footer-bg: #0f0f10;--footer-text: #f3f4f6;--footer-text-hover: #79b6ff;--footer-links: #f3f4f6;--footer-links-hover: #79b6ff;--footer-arrows: #fff;--footer-arrows-hover: #0f0f10;--footer-arrows-bg: #dddddd;--footer-arrows-bg-hover: #f3f3f3}:root,:root[data-theme=light]{color-scheme:light;--color-primary: #007bff;--color-secondary: #6c757d;--color-text: #111111;--color-bg: #f9f9f9;--button-primary-bg: #007bff;--button-primary-text: #f9f9f9;--button-primary-bg-hover: #033468;--button-primary-text-hover: #f9f9f9;--button-primary-outline-border: #020202;--button-primary-outline-text: #020202;--button-primary-outline-bg-hover: #007bff;--button-primary-outline-text-hover: #f9f9f9;--button-secondary-bg: #6c757d;--button-secondary-text: #f9f9f9;--button-secondary-bg-hover: #1c1e20;--button-secondary-text-hover: #f9f9f9;--button-link-text: #111111;--button-link-text-hover: #007bff;--header-clear-bg: #007bff;--header-mobile-bg: #007bff;--header-logo-text: #f9f9f9;--modal-bg: #f9f9f9;--close-btn: #111111;--item-text: #111111;--progress-color: #79b6ff;--progress-bg: #dde8f5;--footer-bg: #dadada;--footer-text: #000;--footer-text-hover: #79b6ff;--footer-links: #000;--footer-links-hover: #79b6ff;--footer-arrows: #fff;--footer-arrows-hover: #fff;--footer-arrows-bg: #b6b6b6;--footer-arrows-bg-hover: #8b8a8a}.visual-footer{display:grid;grid-template-columns:1fr 2fr;gap:2rem;align-items:stretch;padding:4rem;background:var(--footer-bg)}.visual-footer__texts{display:flex;flex-direction:column;gap:2rem}.visual-footer__texts .btn{padding:var(--spacing-sm) 0}.visual-footer__texts .btn-link{display:inline;width:fit-content}.visual-footer__texts .title{font-size:1.5rem}.visual-footer__texts .text{font-weight:300;margin:0;display:flex;flex-direction:column;gap:.25rem}.visual-footer__image img{width:100%;height:auto;border-radius:.5rem;object-fit:cover}.visual-footer__contact,.visual-footer__address,.visual-footer__socials{display:flex;flex-direction:column;gap:.25rem}@media (max-width: 768px){.visual-footer{grid-template-columns:1fr}.visual-footer__image{order:-1}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: LinkTypeDirective, selector: "[linkType]", inputs: ["linkType", "href"], outputs: ["anchorClicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
390
- }
391
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: VisualFooterComponent, decorators: [{
392
- type: Component,
393
- args: [{ selector: 'lib-visual-footer', standalone: true, imports: [CommonModule, LinkTypeDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"visual-footer\">\n <div class=\"visual-footer__texts\">\n <div class=\"visual-footer__contact\">\n @if (contactTitle) {\n <h2 class=\"title\">{{ contactTitle }}</h2>\n }\n @if (contactPhone) {\n <a [href]=\"contactPhone.url\" [linkType]=\"contactPhone.linkType\" class=\"btn btn-link\">\n <span>{{ contactPhone.label }}</span>\n </a>\n }\n @if (contactEmail) {\n <a [href]=\"contactEmail.url\" [linkType]=\"contactEmail.linkType\" class=\"btn btn-link\">\n <span>{{ contactEmail.label }}</span>\n </a>\n }\n </div>\n <div class=\"visual-footer__address\">\n @if (addressTitle) {\n <h2 class=\"title\">{{ addressTitle }}</h2>\n }\n <p class=\"text\">\n <span>{{ address?.address }}</span>\n <span>{{ address?.cp }} {{ address?.city }}</span>\n <span>{{ address?.province }} {{ address?.country }}</span>\n </p>\n </div>\n <div class=\"visual-footer__socials\">\n @if (socialsTitle) {\n <h2 class=\"title\">{{ socialsTitle }}</h2>\n }\n @if (socials) {\n @for (social of socials; track $index) {\n <a [href]=\"social.url\" [linkType]=\"social.linkType\" class=\"btn btn-link\">\n <span>{{ social.label }}</span>\n </a>\n }\n }\n </div>\n </div>\n <div class=\"visual-footer__image\">\n @if (image) {\n <img [src]=\"image.url\" [alt]=\"image.alt\" loading=\"lazy\" />\n }\n </div>\n</div>\n", styles: [":root{--font-titles: \"Bebas Neue\", system-ui, sans-serif;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem;--border-radius: 8px}:root[data-theme=dark]{color-scheme:dark;--color-primary: #007bff;--color-secondary: #8a94a1;--color-text: #f3f4f6;--color-bg: #0f0f10;--button-primary-bg: #007bff;--button-primary-text: #f9f9f9;--button-primary-bg-hover: #033468;--button-primary-text-hover: #f9f9f9;--button-primary-outline-border: #020202;--button-primary-outline-text: #020202;--button-primary-outline-bg-hover: #007bff;--button-primary-outline-text-hover: #f9f9f9;--button-secondary-bg: #2b3035;--button-secondary-text: #f9f9f9;--button-secondary-bg-hover: #1c1e20;--button-secondary-text-hover: #f9f9f9;--button-link-text: #f3f4f6;--button-link-text-hover: #79b6ff;--header-clear-bg: #0f0f10;--header-mobile-bg: #0f0f10;--header-logo-text: #f9f9f9;--modal-bg: #17181a;--close-btn: #f3f4f6;--item-text: #f3f4f6;--progress-color: #f9f9f9;--progress-bg: #79b6ff;--footer-bg: #0f0f10;--footer-text: #f3f4f6;--footer-text-hover: #79b6ff;--footer-links: #f3f4f6;--footer-links-hover: #79b6ff;--footer-arrows: #fff;--footer-arrows-hover: #0f0f10;--footer-arrows-bg: #dddddd;--footer-arrows-bg-hover: #f3f3f3}:root,:root[data-theme=light]{color-scheme:light;--color-primary: #007bff;--color-secondary: #6c757d;--color-text: #111111;--color-bg: #f9f9f9;--button-primary-bg: #007bff;--button-primary-text: #f9f9f9;--button-primary-bg-hover: #033468;--button-primary-text-hover: #f9f9f9;--button-primary-outline-border: #020202;--button-primary-outline-text: #020202;--button-primary-outline-bg-hover: #007bff;--button-primary-outline-text-hover: #f9f9f9;--button-secondary-bg: #6c757d;--button-secondary-text: #f9f9f9;--button-secondary-bg-hover: #1c1e20;--button-secondary-text-hover: #f9f9f9;--button-link-text: #111111;--button-link-text-hover: #007bff;--header-clear-bg: #007bff;--header-mobile-bg: #007bff;--header-logo-text: #f9f9f9;--modal-bg: #f9f9f9;--close-btn: #111111;--item-text: #111111;--progress-color: #79b6ff;--progress-bg: #dde8f5;--footer-bg: #dadada;--footer-text: #000;--footer-text-hover: #79b6ff;--footer-links: #000;--footer-links-hover: #79b6ff;--footer-arrows: #fff;--footer-arrows-hover: #fff;--footer-arrows-bg: #b6b6b6;--footer-arrows-bg-hover: #8b8a8a}.visual-footer{display:grid;grid-template-columns:1fr 2fr;gap:2rem;align-items:stretch;padding:4rem;background:var(--footer-bg)}.visual-footer__texts{display:flex;flex-direction:column;gap:2rem}.visual-footer__texts .btn{padding:var(--spacing-sm) 0}.visual-footer__texts .btn-link{display:inline;width:fit-content}.visual-footer__texts .title{font-size:1.5rem}.visual-footer__texts .text{font-weight:300;margin:0;display:flex;flex-direction:column;gap:.25rem}.visual-footer__image img{width:100%;height:auto;border-radius:.5rem;object-fit:cover}.visual-footer__contact,.visual-footer__address,.visual-footer__socials{display:flex;flex-direction:column;gap:.25rem}@media (max-width: 768px){.visual-footer{grid-template-columns:1fr}.visual-footer__image{order:-1}}\n"] }]
394
- }], propDecorators: { contactTitle: [{
395
- type: Input
396
- }], contactPhone: [{
397
- type: Input
398
- }], contactEmail: [{
399
- type: Input
400
- }], addressTitle: [{
401
- type: Input
402
- }], address: [{
403
- type: Input
404
- }], socialsTitle: [{
405
- type: Input
406
- }], socials: [{
407
- type: Input
408
- }], image: [{
409
- type: Input
410
- }] } });
411
-
412
- const mapLangModal = (langs, currentLang = 'es') => {
413
- if (!Array.isArray(langs))
414
- return [];
415
- return langs.map((lang, index) => {
416
- const label = lang.labels?.[currentLang] || lang.labels?.[lang.code] || lang.code;
417
- return {
418
- id: lang.id ?? index,
419
- code: lang.code,
420
- label,
421
- };
422
- });
423
- };
424
-
425
- class LangModalComponent {
426
- data;
427
- dialogRef;
428
- langs;
429
- constructor(data, dialogRef) {
430
- this.data = data;
431
- this.dialogRef = dialogRef;
432
- this.langs = mapLangModal(data.langs, data.currentLang);
433
- }
434
- selectLang(lang) {
435
- this.dialogRef?.close(lang);
436
- }
437
- closeModal() {
438
- this.dialogRef?.close();
439
- }
440
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: LangModalComponent, deps: [{ token: MAT_DIALOG_DATA, optional: true }, { token: i1$2.MatDialogRef, optional: true }], target: i0.ɵɵFactoryTarget.Component });
441
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.19", 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 lang.id) {\n <li (click)=\"selectLang(lang)\">\n <span class=\"modal-item\">{{ lang.label }}</span>\n </li>\n }\n </ol>\n }\n</div>\n", styles: [":root{--font-titles: \"Bebas Neue\", system-ui, sans-serif;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem;--border-radius: 8px}: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) \". \"}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
442
- }
443
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: LangModalComponent, decorators: [{
444
- type: Component,
445
- 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 lang.id) {\n <li (click)=\"selectLang(lang)\">\n <span class=\"modal-item\">{{ lang.label }}</span>\n </li>\n }\n </ol>\n }\n</div>\n", styles: [":root{--font-titles: \"Bebas Neue\", system-ui, sans-serif;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem;--border-radius: 8px}: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) \". \"}\n"] }]
446
- }], ctorParameters: () => [{ type: undefined, decorators: [{
447
- type: Optional
448
- }, {
449
- type: Inject,
450
- args: [MAT_DIALOG_DATA]
451
- }] }, { type: i1$2.MatDialogRef, decorators: [{
452
- type: Optional
453
- }] }] });
454
-
455
- class NavModalComponent {
456
- navItems;
457
- socialItems;
458
- close = new EventEmitter();
459
- closeModal() {
460
- this.close.emit();
461
- }
462
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: NavModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
463
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.19", 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\n @if (navItems?.length) {\n <ol>\n @for (item of navItems; track item.name) {\n <a [href]=\"item.url\" [linkType]=\"item.linkType\" (click)=\"closeModal()\">\n <li>\n <span class=\"modal-item\">{{ item.label }}</span>\n </li>\n </a>\n }\n </ol>\n }\n\n @if (socialItems?.length) {\n <div class=\"buttons\">\n @for (social of socialItems; track social.label) {\n <a class=\"btn btn-link\" [href]=\"social.url\" [linkType]=\"social.linkType\">\n <span>{{ social.icon }}</span>\n {{ social.label }}\n </a>\n }\n </div>\n }\n</div>\n", styles: [":root{--font-titles: \"Bebas Neue\", system-ui, sans-serif;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem;--border-radius: 8px}: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) \". \"}.buttons{display:flex;flex-wrap:wrap;justify-content:center}.buttons a{text-transform:lowercase}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: LinkTypeDirective, selector: "[linkType]", inputs: ["linkType", "href"], outputs: ["anchorClicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
464
- }
465
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: NavModalComponent, decorators: [{
466
- type: Component,
467
- 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\n @if (navItems?.length) {\n <ol>\n @for (item of navItems; track item.name) {\n <a [href]=\"item.url\" [linkType]=\"item.linkType\" (click)=\"closeModal()\">\n <li>\n <span class=\"modal-item\">{{ item.label }}</span>\n </li>\n </a>\n }\n </ol>\n }\n\n @if (socialItems?.length) {\n <div class=\"buttons\">\n @for (social of socialItems; track social.label) {\n <a class=\"btn btn-link\" [href]=\"social.url\" [linkType]=\"social.linkType\">\n <span>{{ social.icon }}</span>\n {{ social.label }}\n </a>\n }\n </div>\n }\n</div>\n", styles: [":root{--font-titles: \"Bebas Neue\", system-ui, sans-serif;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem;--border-radius: 8px}: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) \". \"}.buttons{display:flex;flex-wrap:wrap;justify-content:center}.buttons a{text-transform:lowercase}\n"] }]
468
- }], propDecorators: { navItems: [{
469
- type: Input
470
- }], socialItems: [{
471
- type: Input
472
- }], close: [{
473
- type: Output
474
- }] } });
475
-
476
- const mapNavModal = (navigation, lang) => {
477
- if (!navigation?.items || !Array.isArray(navigation.items))
478
- return [];
479
- return navigation.items.map((item) => {
480
- const slug = item.slug;
481
- const url = slug === 'home' || slug === '' ? `/${lang}` : `/${lang}/${slug}`;
482
- return {
483
- label: item.label?.[lang] ?? item.label?.['es'] ?? slug,
484
- url,
485
- linkType: 'internal',
486
- name: slug,
487
- active: true,
488
- children: [],
489
- };
490
- });
491
- };
492
- const mapSocialLinks = (navigation) => {
493
- if (!navigation?.social || !Array.isArray(navigation.social))
494
- return [];
495
- return navigation.social.map((item, index) => ({
496
- label: item.label ?? '',
497
- url: item.url ?? '',
498
- linkType: item.linkType ?? 'external',
499
- icon: item.icon ?? '',
500
- order: item.order ?? index,
501
- }));
502
- };
503
-
504
- class ThemeService {
505
- platformId;
506
- currentThemeSubject = new BehaviorSubject('light');
507
- currentTheme$ = this.currentThemeSubject.asObservable();
508
- constructor(platformId) {
509
- this.platformId = platformId;
510
- // Aplicar tema por defecto al inicio
511
- if (isPlatformBrowser(this.platformId)) {
512
- this.applyTheme('light');
513
- }
514
- }
515
- getCurrentTheme() {
516
- return this.currentThemeSubject.value;
517
- }
518
- setTheme(theme) {
519
- this.currentThemeSubject.next(theme);
520
- this.applyTheme(theme);
521
- // NO guardar automáticamente en localStorage - solo cuando el usuario hace toggle
522
- }
523
- toggleTheme() {
524
- const currentTheme = this.getCurrentTheme();
525
- const newTheme = currentTheme === 'light' ? 'dark' : 'light';
526
- // Guardar en localStorage solo cuando el usuario hace toggle
527
- if (isPlatformBrowser(this.platformId)) {
528
- localStorage.setItem('theme', newTheme);
529
- }
530
- this.setTheme(newTheme);
531
- }
532
- resetTheme() {
533
- if (isPlatformBrowser(this.platformId)) {
534
- localStorage.removeItem('theme');
535
- this.currentThemeSubject.next('light');
536
- this.applyTheme('light');
537
- }
538
- }
539
- // Método para cargar el tema guardado (opcional)
540
- loadSavedTheme() {
541
- if (isPlatformBrowser(this.platformId)) {
542
- const savedTheme = localStorage.getItem('theme');
543
- if (savedTheme) {
544
- this.setTheme(savedTheme);
545
- }
546
- }
547
- }
548
- applyTheme(theme) {
549
- // Solo aplicar en el navegador
550
- if (!isPlatformBrowser(this.platformId)) {
551
- return;
552
- }
553
- const root = document.documentElement;
554
- if (theme === 'dark') {
555
- root.setAttribute('data-theme', 'dark');
556
- }
557
- else {
558
- root.setAttribute('data-theme', 'light');
559
- }
560
- }
561
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: ThemeService, deps: [{ token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Injectable });
562
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: ThemeService, providedIn: 'root' });
563
- }
564
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: ThemeService, decorators: [{
565
- type: Injectable,
566
- args: [{
567
- providedIn: 'root',
568
- }]
569
- }], ctorParameters: () => [{ type: Object, decorators: [{
570
- type: Inject,
571
- args: [PLATFORM_ID]
572
- }] }] });
573
-
574
- class HeaderClearComponent {
575
- themeService;
576
- isMenuOpen = false;
577
- currentTheme = 'light';
578
- themeSubscription;
579
- logo;
580
- logoDark;
581
- navItems;
582
- socialItems;
583
- homeLink;
584
- navigation;
585
- lang = 'es';
586
- langModal = new EventEmitter();
587
- theme = new EventEmitter();
588
- constructor(themeService) {
589
- this.themeService = themeService;
590
- }
591
- ngOnInit() {
592
- this.themeSubscription = this.themeService.currentTheme$.subscribe((theme) => {
593
- this.currentTheme = theme;
594
- });
595
- }
596
- ngOnChanges() {
597
- this.navItems = mapNavModal(this.navigation, this.lang);
598
- }
599
- ngOnDestroy() {
600
- this.themeSubscription?.unsubscribe();
601
- }
602
- openLanguagesModal() {
603
- this.langModal.emit();
604
- }
605
- toggleTheme() {
606
- this.themeService.toggleTheme();
607
- this.theme.emit();
608
- }
609
- toggleMenu() {
610
- this.isMenuOpen = !this.isMenuOpen;
611
- }
612
- getThemeIcon() {
613
- return this.currentTheme === 'light' ? '🌙' : '☀️';
614
- }
615
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: HeaderClearComponent, deps: [{ token: ThemeService }], target: i0.ɵɵFactoryTarget.Component });
616
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.19", type: HeaderClearComponent, isStandalone: true, selector: "lib-header-clear", inputs: { logo: "logo", logoDark: "logoDark", navItems: "navItems", socialItems: "socialItems", homeLink: "homeLink", navigation: "navigation", lang: "lang" }, outputs: { langModal: "langModal", theme: "theme" }, usesOnChanges: true, ngImport: i0, template: "<header class=\"header-clear\">\n <a [href]=\"homeLink?.url\" [linkType]=\"homeLink?.linkType\">\n <div class=\"header-logo\">\n <!-- Logo -->\n <img\n [src]=\"currentTheme === 'dark' ? logoDark?.url : logo?.url\"\n [alt]=\"currentTheme === 'dark' ? logoDark?.alt : logo?.alt\"\n />\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 [socialItems]=\"socialItems\"\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 });
617
- }
618
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: HeaderClearComponent, decorators: [{
619
- type: Component,
620
- 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\n [src]=\"currentTheme === 'dark' ? logoDark?.url : logo?.url\"\n [alt]=\"currentTheme === 'dark' ? logoDark?.alt : logo?.alt\"\n />\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 [socialItems]=\"socialItems\"\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"] }]
621
- }], ctorParameters: () => [{ type: ThemeService }], propDecorators: { logo: [{
622
- type: Input
623
- }], logoDark: [{
624
- type: Input
625
- }], navItems: [{
626
- type: Input
627
- }], socialItems: [{
628
- type: Input
629
- }], homeLink: [{
630
- type: Input
631
- }], navigation: [{
632
- type: Input
633
- }], lang: [{
634
- type: Input
635
- }], langModal: [{
636
- type: Output
637
- }], theme: [{
638
- type: Output
639
- }] } });
640
-
641
- class HeaderMobileComponent {
642
- themeService;
643
- isMenuOpen = false;
644
- currentTheme = 'light';
645
- themeSubscription;
646
- logo;
647
- logoDark;
648
- navItems;
649
- socialItems;
650
- homeLink;
651
- navigation;
652
- lang = 'es';
653
- langModal = new EventEmitter();
654
- theme = new EventEmitter();
655
- constructor(themeService) {
656
- this.themeService = themeService;
657
- }
658
- ngOnInit() {
659
- this.themeSubscription = this.themeService.currentTheme$.subscribe((theme) => {
660
- this.currentTheme = theme;
661
- });
662
- }
663
- ngOnChanges() {
664
- this.navItems = mapNavModal(this.navigation, this.lang);
665
- }
666
- ngOnDestroy() {
667
- this.themeSubscription?.unsubscribe();
668
- }
669
- openLanguagesModal() {
670
- this.langModal.emit();
671
- }
672
- toggleTheme() {
673
- this.themeService.toggleTheme();
674
- this.theme.emit();
675
- }
676
- toggleMenu() {
677
- this.isMenuOpen = !this.isMenuOpen;
678
- }
679
- getThemeIcon() {
680
- return this.currentTheme === 'light' ? '🌙' : '☀️';
681
- }
682
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: HeaderMobileComponent, deps: [{ token: ThemeService }], target: i0.ɵɵFactoryTarget.Component });
683
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.19", type: HeaderMobileComponent, isStandalone: true, selector: "lib-header-mobile", inputs: { logo: "logo", logoDark: "logoDark", navItems: "navItems", socialItems: "socialItems", homeLink: "homeLink", navigation: "navigation", lang: "lang" }, outputs: { langModal: "langModal", theme: "theme" }, usesOnChanges: true, ngImport: i0, template: "<header class=\"header-mobile\">\n <a [href]=\"homeLink?.url\" [linkType]=\"homeLink?.linkType\">\n <div class=\"header-logo\">\n <!-- Logo -->\n <img\n [src]=\"currentTheme === 'dark' ? logoDark?.url : logo?.url\"\n [alt]=\"currentTheme === 'dark' ? logoDark?.alt : logo?.alt\"\n />\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@if (isMenuOpen && navItems && navItems.length > 0) {\n <lib-nav-modal\n [navItems]=\"navItems\"\n [socialItems]=\"socialItems\"\n (close)=\"isMenuOpen = false\"\n ></lib-nav-modal>\n}\n", styles: [":root{--font-titles: \"Bebas Neue\", system-ui, sans-serif;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem;--border-radius: 8px}.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 });
684
- }
685
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: HeaderMobileComponent, decorators: [{
686
- type: Component,
687
- 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\n [src]=\"currentTheme === 'dark' ? logoDark?.url : logo?.url\"\n [alt]=\"currentTheme === 'dark' ? logoDark?.alt : logo?.alt\"\n />\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@if (isMenuOpen && navItems && navItems.length > 0) {\n <lib-nav-modal\n [navItems]=\"navItems\"\n [socialItems]=\"socialItems\"\n (close)=\"isMenuOpen = false\"\n ></lib-nav-modal>\n}\n", styles: [":root{--font-titles: \"Bebas Neue\", system-ui, sans-serif;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem;--border-radius: 8px}.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"] }]
688
- }], ctorParameters: () => [{ type: ThemeService }], propDecorators: { logo: [{
689
- type: Input
690
- }], logoDark: [{
691
- type: Input
692
- }], navItems: [{
693
- type: Input
694
- }], socialItems: [{
695
- type: Input
696
- }], homeLink: [{
697
- type: Input
698
- }], navigation: [{
699
- type: Input
700
- }], lang: [{
701
- type: Input
702
- }], langModal: [{
703
- type: Output
704
- }], theme: [{
705
- type: Output
706
- }] } });
707
-
708
- class NotFoundComponent {
709
- title;
710
- subtitle;
711
- highlight;
712
- button;
713
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: NotFoundComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
714
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.19", type: NotFoundComponent, isStandalone: true, selector: "lib-404", inputs: { title: "title", subtitle: "subtitle", highlight: "highlight", button: "button" }, ngImport: i0, template: "<div class=\"notfound\">\n <div class=\"notfound__content\">\n @if (title) {\n <h1 class=\"notfound__title\">{{ title }}</h1>\n }\n\n @if (subtitle) {\n <h2 class=\"notfound__subtitle\">{{ subtitle }}</h2>\n }\n\n @if (button) {\n <a\n [href]=\"button.url\"\n [linkType]=\"button.linkType\"\n class=\"btn btn-primary btn-primary--outline\"\n >\n <span>\u2197</span> {{ button.label }}\n </a>\n }\n </div>\n\n @if (highlight) {\n <div class=\"notfound__highlight\">\n {{ highlight }}\n </div>\n }\n</div>", styles: [":root{--font-titles: \"Bebas Neue\", system-ui, sans-serif;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem;--border-radius: 8px}.notfound{min-height:100%;overflow:hidden;padding:6rem 4rem 0}.notfound__content{max-width:55rem;position:relative;z-index:2}.notfound__title{font-size:3rem;font-weight:600;font-family:var(--font-base);margin:0}.notfound__subtitle{font-size:3rem;font-weight:600;line-height:1.2;font-family:var(--font-base);padding-block:0 1rem;margin:0}.notfound__highlight{position:fixed;bottom:0;left:50%;transform:translate(-50%,33%);font-size:38rem;color:var(--color-primary);font-family:var(--font-titles);z-index:1;pointer-events:none}@media (max-width: 768px){.notfound__highlight{display:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: LinkTypeDirective, selector: "[linkType]", inputs: ["linkType", "href"], outputs: ["anchorClicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
715
- }
716
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: NotFoundComponent, decorators: [{
717
- type: Component,
718
- args: [{ selector: 'lib-404', standalone: true, imports: [CommonModule, LinkTypeDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"notfound\">\n <div class=\"notfound__content\">\n @if (title) {\n <h1 class=\"notfound__title\">{{ title }}</h1>\n }\n\n @if (subtitle) {\n <h2 class=\"notfound__subtitle\">{{ subtitle }}</h2>\n }\n\n @if (button) {\n <a\n [href]=\"button.url\"\n [linkType]=\"button.linkType\"\n class=\"btn btn-primary btn-primary--outline\"\n >\n <span>\u2197</span> {{ button.label }}\n </a>\n }\n </div>\n\n @if (highlight) {\n <div class=\"notfound__highlight\">\n {{ highlight }}\n </div>\n }\n</div>", styles: [":root{--font-titles: \"Bebas Neue\", system-ui, sans-serif;--font-base: \"Inter\", system-ui, sans-serif;--font-size-base: 16px;--spacing-xs: .25rem;--spacing-sm: .5rem;--spacing-md: 1rem;--spacing-lg: 2rem;--border-radius: 8px}.notfound{min-height:100%;overflow:hidden;padding:6rem 4rem 0}.notfound__content{max-width:55rem;position:relative;z-index:2}.notfound__title{font-size:3rem;font-weight:600;font-family:var(--font-base);margin:0}.notfound__subtitle{font-size:3rem;font-weight:600;line-height:1.2;font-family:var(--font-base);padding-block:0 1rem;margin:0}.notfound__highlight{position:fixed;bottom:0;left:50%;transform:translate(-50%,33%);font-size:38rem;color:var(--color-primary);font-family:var(--font-titles);z-index:1;pointer-events:none}@media (max-width: 768px){.notfound__highlight{display:none}}\n"] }]
719
- }], propDecorators: { title: [{
720
- type: Input
721
- }], subtitle: [{
722
- type: Input
723
- }], highlight: [{
724
- type: Input
725
- }], button: [{
726
- type: Input
727
- }] } });
728
-
729
- class SphereDeformEffect {
730
- size;
731
- rotationSpeed;
732
- color;
733
- mesh;
734
- time = 0;
735
- constructor(size, rotationSpeed, color) {
736
- this.size = size;
737
- this.rotationSpeed = rotationSpeed;
738
- this.color = color;
739
- }
740
- init(scene, _options) {
741
- const geometry = new THREE.SphereGeometry(this.size, 128, 128);
742
- const material = this.color
743
- ? new THREE.MeshStandardMaterial({ color: this.color, flatShading: true })
744
- : new THREE.MeshNormalMaterial({ flatShading: true });
745
- this.mesh = new THREE.Mesh(geometry, material);
746
- scene.add(this.mesh);
747
- }
748
- animate() {
749
- this.time += 0.02;
750
- const positionAttr = this.mesh.geometry.attributes['position'];
751
- const vertex = new THREE.Vector3();
752
- for (let i = 0; i < positionAttr.count; i++) {
753
- vertex.fromBufferAttribute(positionAttr, i);
754
- const offset = Math.sin(vertex.x * 3 + this.time) * 0.2 +
755
- Math.cos(vertex.y * 5 + this.time * 0.7) * 0.2;
756
- vertex.normalize().multiplyScalar(this.size + offset);
757
- positionAttr.setXYZ(i, vertex.x, vertex.y, vertex.z);
758
- }
759
- positionAttr.needsUpdate = true;
760
- this.mesh.geometry.computeVertexNormals();
761
- this.mesh.rotation.y += this.rotationSpeed;
762
- }
763
- dispose() {
764
- this.mesh?.geometry.dispose();
765
- this.mesh?.material?.dispose();
766
- }
767
- }
768
-
769
- const EFFECT_REGISTRY = {
770
- 'sphere-deform': SphereDeformEffect,
771
- // 'ring-transform': RingTransformEffect,
772
- // 'particles': ParticlesEffect,
773
- };
774
-
775
- class DynamicBackgroundComponent {
776
- canvasRef;
777
- effect = 'sphere-deform';
778
- rotationSpeed = 0.01;
779
- size = 2;
780
- backgroundColor = '#000000';
781
- elementColor;
782
- platformId = inject(PLATFORM_ID);
783
- isBrowser = isPlatformBrowser(this.platformId);
784
- scene;
785
- camera;
786
- renderer;
787
- animationId;
788
- currentEffect;
789
- ngOnInit() {
790
- if (this.isBrowser) {
791
- this.initScene();
792
- this.loadEffect();
793
- this.animate();
794
- window.addEventListener('resize', this.onResize);
795
- }
796
- }
797
- ngOnDestroy() {
798
- if (this.isBrowser) {
799
- cancelAnimationFrame(this.animationId);
800
- this.renderer?.dispose();
801
- this.currentEffect?.dispose();
802
- window.removeEventListener('resize', this.onResize);
803
- }
804
- }
805
- initScene() {
806
- const width = window.innerWidth;
807
- const height = window.innerHeight;
808
- this.scene = new THREE.Scene();
809
- this.scene.background = new THREE.Color(this.backgroundColor);
810
- this.camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
811
- this.camera.position.z = 5;
812
- this.renderer = new THREE.WebGLRenderer({
813
- canvas: this.canvasRef.nativeElement,
814
- antialias: true,
815
- });
816
- this.renderer.setSize(width, height);
817
- const light = new THREE.DirectionalLight(0xffffff, 1);
818
- light.position.set(5, 5, 5).normalize();
819
- this.scene.add(light);
820
- }
821
- loadEffect() {
822
- const EffectClass = EFFECT_REGISTRY[this.effect];
823
- if (!EffectClass) {
824
- throw new Error(`Efecto "${this.effect}" no está registrado en EFFECT_REGISTRY`);
825
- }
826
- this.currentEffect = new EffectClass(this.size, this.rotationSpeed, this.elementColor);
827
- this.currentEffect.init(this.scene, {});
828
- }
829
- animate = () => {
830
- this.animationId = requestAnimationFrame(this.animate);
831
- this.currentEffect.animate();
832
- this.renderer.render(this.scene, this.camera);
833
- };
834
- onResize = () => {
835
- const width = window.innerWidth;
836
- const height = window.innerHeight;
837
- this.camera.aspect = width / height;
838
- this.camera.updateProjectionMatrix();
839
- this.renderer.setSize(width, height);
840
- };
841
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: DynamicBackgroundComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
842
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.19", type: DynamicBackgroundComponent, isStandalone: true, selector: "lib-dynamic-background", inputs: { effect: "effect", rotationSpeed: "rotationSpeed", size: "size", backgroundColor: "backgroundColor", elementColor: "elementColor" }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["bgCanvas"], descendants: true, static: true }], ngImport: i0, template: "<canvas #bgCanvas class=\"dynamic-bg-canvas\"></canvas>\n", styles: [".dynamic-bg-canvas{position:absolute;top:0;left:0;width:100%;height:100%;display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
843
- }
844
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: DynamicBackgroundComponent, decorators: [{
845
- type: Component,
846
- args: [{ selector: 'lib-dynamic-background', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<canvas #bgCanvas class=\"dynamic-bg-canvas\"></canvas>\n", styles: [".dynamic-bg-canvas{position:absolute;top:0;left:0;width:100%;height:100%;display:block}\n"] }]
847
- }], propDecorators: { canvasRef: [{
848
- type: ViewChild,
849
- args: ['bgCanvas', { static: true }]
850
- }], effect: [{
851
- type: Input
852
- }], rotationSpeed: [{
853
- type: Input
854
- }], size: [{
855
- type: Input
856
- }], backgroundColor: [{
857
- type: Input
858
- }], elementColor: [{
859
- type: Input
860
- }] } });
861
-
862
- const mapCategoryProgress = (props) => ({
863
- pretitle: props?.texts?.pretitle,
864
- title: props?.texts?.title,
865
- categories: props?.items?.map((item) => ({
866
- title: item.title,
867
- items: item.items?.map((subItem) => ({
868
- label: subItem.name,
869
- value: subItem.progress,
870
- })),
871
- })),
872
- });
873
-
874
- function mapButtons(data) {
875
- if (!Array.isArray(data))
876
- return [];
877
- return data
878
- .filter((item) => item && typeof item === 'object')
879
- .map((item) => ({
880
- label: item.label ?? '',
881
- url: item.link_type === 'internal' ? (item.page ?? '') : (item.url ?? ''),
882
- linkType: item.link_type ?? 'none',
883
- icon: item.icon,
884
- }));
885
- }
886
- function mapImage(data, cdn) {
887
- if (!data || typeof data !== 'object')
888
- return null;
889
- const src = data.url ?? data.src ?? '';
890
- return {
891
- url: src.startsWith('http') ? src : (cdn ?? '') + src,
892
- alt: data.alt ?? '',
893
- width: data.width,
894
- height: data.height,
895
- format: data.format,
896
- };
897
- }
898
- function mapImageOrGallery(data, cdn) {
899
- if (!data)
900
- return [];
901
- if (Array.isArray(data)) {
902
- return data
903
- .filter((img) => img && typeof img === 'object')
904
- .map((img) => mapImage(img, cdn))
905
- .filter(Boolean);
906
- }
907
- const single = mapImage(data, cdn);
908
- return single ? [single] : [];
909
- }
910
-
911
- const mapHeaderClear = (props, cdn) => {
912
- return {
913
- logo: mapImage(props?.logo, cdn),
914
- logoDark: mapImage(props?.logoDark, cdn),
915
- lang: props?.lang || 'es',
916
- navigation: props?.navigation,
917
- socialItems: mapSocialLinks(props?.navigation),
918
- };
919
- };
920
-
921
- const mapHeroSection = (props) => ({
922
- pretitle: props?.texts?.pretitle,
923
- title: props?.texts?.title,
924
- subtitle: props?.texts?.subtitle,
925
- text: props?.texts?.text,
926
- buttons: mapButtons(props?.buttons),
927
- highlight: props?.texts?.highlight,
928
- });
929
-
930
- const mapLegalFooter = (props) => ({
931
- year: props?.texts?.year,
932
- brand: props?.texts?.brand,
933
- credits: props?.texts?.credits,
934
- links: mapButtons(props?.footer_links),
935
- //variant
936
- });
937
-
938
- const mapLinksFooter = (props) => ({
939
- links: mapButtons(props?.footer_links),
940
- });
941
-
942
- const map404 = (props) => ({
943
- title: props?.texts?.title,
944
- subtitle: props?.texts?.subtitle,
945
- highlight: props?.texts?.highlight,
946
- button: mapButtons(props?.buttons)[0],
947
- });
948
-
949
- const mapSectionIntro = (props) => ({
950
- pretitle: props?.texts?.pretitle,
951
- title: props?.texts?.title,
952
- subtitle: props?.texts?.subtitle,
953
- text: props?.texts?.text,
954
- button: mapButtons(props?.button)[0],
955
- });
956
-
957
- const mapSocialFooter = (props) => ({
958
- images: mapImage(props?.multimedia),
959
- socials: mapButtons(props?.social_links),
960
- hashtag: props?.texts?.hashtag,
961
- });
962
-
963
- const mapVisualFooter = (props) => ({
964
- contactTitle: props?.texts?.contactTitle,
965
- contactPhone: mapButtons(props?.contactPhone),
966
- contactEmail: mapButtons(props?.contactEmail),
967
- addressTitle: props?.texts?.addressTitle,
968
- address: {
969
- address: props?.address?.address,
970
- city: props?.address?.city,
971
- country: props?.address?.country,
972
- cp: props?.address?.cp,
973
- province: props?.address?.province,
974
- },
975
- socialsTitle: props?.texts?.socialsTitle,
976
- socials: mapButtons(props?.social_links),
977
- image: mapImage(props?.multimedia),
978
- });
979
-
980
- const componentMappers = {
981
- 'hero-section': mapHeroSection,
982
- 'header-clear': mapHeaderClear,
983
- 'lang-modal': mapLangModal,
984
- 'section-intro': mapSectionIntro,
985
- 'category-progress': mapCategoryProgress,
986
- 'links-footer': mapLinksFooter,
987
- 'legal-footer': mapLegalFooter,
988
- 'social-footer': mapSocialFooter,
989
- 'visual-footer': mapVisualFooter,
990
- 'not-found': map404,
991
- };
992
-
993
- const CDN_BASE_URL = new InjectionToken('CDN_BASE_URL');
994
-
995
- class MapperService {
996
- platformId = inject(PLATFORM_ID);
997
- cdn = inject(CDN_BASE_URL);
998
- mapComponents(body) {
999
- if (!body || body.length === 0) {
1000
- return [];
1001
- }
1002
- return body
1003
- .filter((component) => component && component.name && component.props)
1004
- .map((component) => {
1005
- const name = component.name.toLowerCase();
1006
- const mapper = componentMappers[name];
1007
- const mapped = {
1008
- name,
1009
- order: component.order,
1010
- props: {},
1011
- };
1012
- if (mapper) {
1013
- try {
1014
- mapped.props = mapper(component.props, this.cdn);
1015
- }
1016
- catch (e) {
1017
- console.error(`Error mapping props for component "${name}"`, e);
1018
- }
1019
- }
1020
- else {
1021
- console.warn(`No mapper found for component "${name}"`);
1022
- }
1023
- return mapped;
1024
- });
1025
- }
1026
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: MapperService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1027
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: MapperService, providedIn: 'root' });
1028
- }
1029
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: MapperService, decorators: [{
1030
- type: Injectable,
1031
- args: [{
1032
- providedIn: 'root',
1033
- }]
12
+ args: [{ selector: 'lib-ui-lib', standalone: true, imports: [], template: `
13
+ <p>ui-lib works!</p>
14
+ ` }]
1034
15
  }] });
1035
16
 
1036
- class ScreenSizerService {
1037
- breakpoints = {
1038
- xs: 480,
1039
- sm: 768,
1040
- md: 1024,
1041
- lg: 1280,
1042
- xl: 1536,
1043
- };
1044
- isXs = signal(false);
1045
- isSm = signal(false);
1046
- isMd = signal(false);
1047
- isLg = signal(false);
1048
- isXl = signal(false);
1049
- minSm = signal(false);
1050
- minMd = signal(false);
1051
- minLg = signal(false);
1052
- minXl = signal(false);
1053
- platformId = inject(PLATFORM_ID);
1054
- get width() {
1055
- if (isPlatformBrowser(this.platformId)) {
1056
- return Math.min(window.innerWidth, window.outerWidth);
1057
- }
1058
- return 0;
1059
- }
1060
- constructor() {
1061
- if (isPlatformBrowser(this.platformId)) {
1062
- fromEvent(window, 'resize')
1063
- .pipe(debounceTime(200), map(() => this.width), distinctUntilChanged(), startWith(this.width))
1064
- .subscribe((width) => this.updateFlags(width));
1065
- }
1066
- }
1067
- updateFlags(width) {
1068
- const { xs, sm, md, lg, xl } = this.breakpoints;
1069
- this.isXs.set(width < sm);
1070
- this.isSm.set(width >= sm && width < md);
1071
- this.isMd.set(width >= md && width < lg);
1072
- this.isLg.set(width >= lg && width < xl);
1073
- this.isXl.set(width >= xl);
1074
- this.minSm.set(width >= sm);
1075
- this.minMd.set(width >= md);
1076
- this.minLg.set(width >= lg);
1077
- this.minXl.set(width >= xl);
1078
- }
1079
- // Métodos rápidos si no usas signals directamente
1080
- isXsInstant() {
1081
- return this.isXs();
1082
- }
1083
- isSmInstant() {
1084
- return this.isSm();
1085
- }
1086
- isMdInstant() {
1087
- return this.isMd();
1088
- }
1089
- isLgInstant() {
1090
- return this.isLg();
1091
- }
1092
- isXlInstant() {
1093
- return this.isXl();
1094
- }
1095
- minSmInstant() {
1096
- return this.minSm();
1097
- }
1098
- minMdInstant() {
1099
- return this.minMd();
1100
- }
1101
- minLgInstant() {
1102
- return this.minLg();
1103
- }
1104
- minXlInstant() {
1105
- return this.minXl();
1106
- }
1107
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: ScreenSizerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1108
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: ScreenSizerService, providedIn: 'root' });
1109
- }
1110
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: ScreenSizerService, decorators: [{
1111
- type: Injectable,
1112
- args: [{ providedIn: 'root' }]
1113
- }], ctorParameters: () => [] });
1114
-
1115
17
  /*
1116
18
  * Public API Surface of ui-lib
1117
19
  */
1118
20
  /* COMPONENTS */
1119
- // export * from './lib/ui-lib.component';
21
+ // export * from './lib/components/core/index';
22
+ // export * from './lib/components/shared/index';
23
+ // export * from './lib/pipes/index';
1120
24
 
1121
25
  /**
1122
26
  * Generated bundle index. Do not edit.
1123
27
  */
1124
28
 
1125
- export { CDN_BASE_URL, CategoryProgressComponent, Default, DynamicBackgroundComponent, HeaderClearComponent, HeaderMobileComponent, HeroSectionComponent, LangModalComponent, LegalFooterComponent, LinkType, LinkTypeDirective, LinksFooterComponent, MapperService, MockUiIconComponent, NavModalComponent, NotFoundComponent, ScreenSizerService, SectionIntroComponent, SocialFooterComponent, ThemeService, UiIconComponent, VisualFooterComponent, componentMappers, mapButtons, mapImage, mapImageOrGallery };
29
+ export { UiLibComponent };
1126
30
  //# sourceMappingURL=lluc_llull-ui-lib.mjs.map