athlefi-ui 0.1.6 → 0.1.8

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 (46) hide show
  1. package/README.md +21 -10
  2. package/package.json +3 -1
  3. package/src/assets/Logo 1.png +0 -0
  4. package/src/assets/Logo 3.png +0 -0
  5. package/src/assets/android-chrome-192x192.png +0 -0
  6. package/src/assets/android-chrome-512x512.png +0 -0
  7. package/src/assets/apple-touch-icon.png +0 -0
  8. package/src/assets/favicon-16x16.png +0 -0
  9. package/src/assets/favicon-32x32.png +0 -0
  10. package/src/assets/favicon.ico +0 -0
  11. package/src/assets/icono.svg +1 -0
  12. package/src/assets/icono_name.svg +1 -0
  13. package/src/assets/profilepic.webp +0 -0
  14. package/src/assets/site.webmanifest +21 -0
  15. package/src/components/atoms/Button.astro +95 -30
  16. package/src/components/atoms/ContactIcon.astro +91 -0
  17. package/src/components/atoms/FooterLink.astro +50 -0
  18. package/src/components/atoms/FormInput.astro +102 -0
  19. package/src/components/atoms/IconCard.astro +99 -0
  20. package/src/components/atoms/Logo.astro +59 -0
  21. package/src/components/atoms/NavLink.astro +70 -0
  22. package/src/components/atoms/SocialIcon.astro +80 -0
  23. package/src/components/atoms/TabButton.astro +71 -0
  24. package/src/components/atoms/TextMono.astro +152 -0
  25. package/src/components/atoms/TimelineStep.astro +215 -0
  26. package/src/components/atoms/auxfile.astro +120 -0
  27. package/src/icons/american-football-outline.svg +16 -0
  28. package/src/icons/astro.svg +1 -0
  29. package/src/icons/background.svg +1 -0
  30. package/src/icons/bar-chart-outline.svg +13 -0
  31. package/src/icons/card-outline.svg +5 -0
  32. package/src/icons/cash-outline.svg +10 -0
  33. package/src/icons/diamond-outline.svg +8 -0
  34. package/src/icons/document-text-outline.svg +6 -0
  35. package/src/icons/eye-outline.svg +4 -0
  36. package/src/icons/laptop-outline.svg +4 -0
  37. package/src/icons/location-outline.svg +4 -0
  38. package/src/icons/mail-outline.svg +4 -0
  39. package/src/icons/person-outline.svg +4 -0
  40. package/src/icons/phone-portrait-outline.svg +4 -0
  41. package/src/icons/pie-chart-outline.svg +4 -0
  42. package/src/icons/rocket-outline.svg +4 -0
  43. package/src/icons/search-outline.svg +4 -0
  44. package/src/icons/shield-checkmark-outline.svg +4 -0
  45. package/src/icons/trophy-outline.svg +7 -0
  46. package/src/index.ts +10 -0
Binary file
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "Athlefi",
3
+ "short_name": "Athlefi",
4
+ "description": "Athlefi - Tu plataforma de fitness",
5
+ "icons": [
6
+ {
7
+ "src": "/android-chrome-192x192.png",
8
+ "sizes": "192x192",
9
+ "type": "image/png"
10
+ },
11
+ {
12
+ "src": "/android-chrome-512x512.png",
13
+ "sizes": "512x512",
14
+ "type": "image/png"
15
+ }
16
+ ],
17
+ "theme_color": "#1a1a1a",
18
+ "background_color": "#1a1a1a",
19
+ "display": "standalone",
20
+ "start_url": "/"
21
+ }
@@ -1,75 +1,140 @@
1
1
  ---
2
- interface Props {
3
- variant?: 'primary' | 'secondary' | 'tertiary';
4
- size?: 's' | 'm' | 'l';
2
+ export interface Props {
3
+ variant?: "primary" | "outline" | "ghost";
4
+ size?: "sm" | "md" | "lg";
5
+ type?: "button" | "submit" | "reset";
5
6
  disabled?: boolean;
7
+ href?: string;
8
+ class?: string;
9
+ ariaLabel?: string;
6
10
  }
7
11
 
8
- const {
9
- variant = 'primary',
10
- size = 'm',
11
- disabled = false
12
+ const {
13
+ variant = "primary",
14
+ size = "md",
15
+ type = "button",
16
+ disabled = false,
17
+ href,
18
+ class: className = "",
19
+ ariaLabel,
12
20
  } = Astro.props;
21
+
22
+ const Element = href ? "a" : "button";
23
+ const elementProps = href ? { href } : { type, disabled };
13
24
  ---
14
25
 
15
- <button
16
- class={`btn btn--${variant} btn--${size}`}
17
- disabled={disabled}
26
+ <Element
27
+ {...elementProps}
28
+ class={`btn btn--${variant} btn--${size} ${className}`}
29
+ aria-label={ariaLabel}
18
30
  >
19
31
  <slot />
20
- </button>
32
+ </Element>
21
33
 
22
34
  <style>
23
35
  .btn {
24
- font-family: var(--font-family-manrope);
25
- border: none;
36
+ display: inline-flex;
37
+ align-items: center;
38
+ justify-content: center;
39
+ text-align: center;
40
+ white-space: nowrap;
41
+ border-radius: 9999px;
42
+ transition: all 0.2s ease;
26
43
  cursor: pointer;
27
- transition: all 0.3s ease;
28
- border-radius: 8px;
44
+ text-decoration: none;
45
+ border: none;
46
+ outline: none;
47
+ }
48
+
49
+ /* Focus states */
50
+ .btn:focus-visible {
51
+ outline: 2px solid var(--color-primary-60);
52
+ outline-offset: 2px;
29
53
  }
30
54
 
31
55
  /* Variantes */
32
56
  .btn--primary {
33
- background-color: var(--color-primary-60);
34
- color: var(--color-white);
57
+ background-color: var(--color-white);
58
+ color: var(--color-primary-90);
35
59
  }
36
60
 
37
61
  .btn--primary:hover:not(:disabled) {
38
- background-color: var(--color-primary-30);
62
+ background-color: var(--color-gray-light);
39
63
  }
40
64
 
41
- .btn--secondary {
42
- background-color: var(--color-gray-light);
43
- color: var(--color-primary-90);
65
+ .btn--primary:focus-visible {
66
+ outline-color: var(--color-white);
44
67
  }
45
68
 
46
- .btn--tertiary {
69
+ .btn--outline {
47
70
  background-color: transparent;
48
71
  color: var(--color-primary-60);
49
72
  border: 2px solid var(--color-primary-60);
50
73
  }
51
74
 
52
- /* Tamaños */
53
- .btn--s {
75
+ .btn--outline:hover:not(:disabled) {
76
+ background-color: var(--color-primary-60);
77
+ color: var(--color-primary-90);
78
+ }
79
+
80
+ .btn--outline:focus-visible {
81
+ outline-color: var(--color-primary-60);
82
+ }
83
+
84
+ .btn--ghost {
85
+ background-color: transparent;
86
+ color: var(--color-white);
87
+ }
88
+
89
+ .btn--ghost:hover:not(:disabled) {
90
+ background-color: rgba(255, 255, 255, 0.1);
91
+ }
92
+
93
+ .btn--ghost:focus-visible {
94
+ outline-color: rgba(255, 255, 255, 0.5);
95
+ }
96
+
97
+ /* Tamaños - usa clases de tipografía globales */
98
+ .btn--sm {
99
+ padding: 6px 12px;
100
+ }
101
+
102
+ .btn--md {
103
+ padding: 8px 16px;
104
+ }
105
+
106
+ .btn--lg {
107
+ padding: 12px 24px;
108
+ }
109
+
110
+ /* Aplicar estilos de tipografía */
111
+ :global(.btn--sm) {
112
+ font-family: var(--font-family-manrope);
54
113
  font-size: var(--font-size-button-s);
55
114
  font-weight: var(--font-weight-button-s);
56
- padding: 8px 16px;
115
+ line-height: var(--line-height-button-s);
116
+ letter-spacing: var(--letter-spacing-button-s);
57
117
  }
58
118
 
59
- .btn--m {
119
+ :global(.btn--md) {
120
+ font-family: var(--font-family-manrope);
60
121
  font-size: var(--font-size-button-m);
61
122
  font-weight: var(--font-weight-button-m);
62
- padding: 12px 24px;
123
+ line-height: var(--line-height-button-m);
124
+ letter-spacing: var(--letter-spacing-button-m);
63
125
  }
64
126
 
65
- .btn--l {
127
+ :global(.btn--lg) {
128
+ font-family: var(--font-family-manrope);
66
129
  font-size: var(--font-size-button-l);
67
130
  font-weight: var(--font-weight-button-l);
68
- padding: 16px 32px;
131
+ line-height: var(--line-height-button-l);
132
+ letter-spacing: var(--letter-spacing-button-l);
69
133
  }
70
134
 
71
135
  /* Disabled */
72
- .btn:disabled {
136
+ .btn:disabled,
137
+ .btn[disabled] {
73
138
  opacity: 0.5;
74
139
  cursor: not-allowed;
75
140
  }
@@ -0,0 +1,91 @@
1
+ ---
2
+ import phoneIcon from "../../icons/phone-portrait-outline.svg?raw";
3
+ import mailIcon from "../../icons/mail-outline.svg?raw";
4
+ import locationIcon from "../../icons/location-outline.svg?raw";
5
+
6
+ export interface Props {
7
+ icon: "phone" | "mail" | "location";
8
+ title: string;
9
+ text: string;
10
+ class?: string;
11
+ }
12
+
13
+ const {
14
+ icon,
15
+ title,
16
+ text,
17
+ class: className = ""
18
+ } = Astro.props;
19
+
20
+ // Mapeo de íconos a contenido SVG
21
+ const iconMap = {
22
+ phone: phoneIcon,
23
+ mail: mailIcon,
24
+ location: locationIcon,
25
+ };
26
+
27
+ const svgContent = iconMap[icon];
28
+ ---
29
+
30
+ <div class={`contact-icon ${className}`}>
31
+ <!-- Ícono SVG -->
32
+ <div class="contact-icon__icon-wrapper" aria-hidden="true">
33
+ <Fragment set:html={svgContent} />
34
+ </div>
35
+
36
+ <!-- Título -->
37
+ <h4 class="contact-icon__title">
38
+ {title}
39
+ </h4>
40
+
41
+ <!-- Texto descriptivo -->
42
+ <p class="contact-icon__text">
43
+ {text}
44
+ </p>
45
+ </div>
46
+
47
+ <style>
48
+ .contact-icon {
49
+ display: flex;
50
+ flex-direction: column;
51
+ align-items: center;
52
+ text-align: center;
53
+ }
54
+
55
+ .contact-icon__icon-wrapper {
56
+ display: flex;
57
+ align-items: center;
58
+ justify-content: center;
59
+ width: 48px;
60
+ height: 48px;
61
+ margin-bottom: 16px;
62
+ }
63
+
64
+ .contact-icon__icon-wrapper :global(svg) {
65
+ width: 48px;
66
+ height: 48px;
67
+ color: var(--color-primary-60);
68
+ fill: var(--color-primary-60);
69
+ }
70
+
71
+ .contact-icon__title {
72
+ font-family: var(--font-family-manrope);
73
+ font-size: var(--font-size-h4);
74
+ font-weight: var(--font-weight-h4);
75
+ line-height: var(--line-height-h4);
76
+ letter-spacing: var(--letter-spacing-h4);
77
+ color: var(--color-primary-60);
78
+ margin-bottom: 8px;
79
+ }
80
+
81
+ .contact-icon__text {
82
+ font-family: var(--font-family-manrope);
83
+ font-size: var(--font-size-body-m);
84
+ font-weight: var(--font-weight-body-m);
85
+ line-height: var(--line-height-body-m);
86
+ letter-spacing: var(--letter-spacing-body-m);
87
+ color: var(--color-white);
88
+ line-height: 1.6;
89
+ }
90
+ </style>
91
+
@@ -0,0 +1,50 @@
1
+ ---
2
+ export interface Props {
3
+ href: string;
4
+ class?: string;
5
+ external?: boolean;
6
+ ariaLabel?: string;
7
+ }
8
+
9
+ const {
10
+ href,
11
+ class: className = "",
12
+ external = false,
13
+ ariaLabel,
14
+ } = Astro.props;
15
+ ---
16
+
17
+ <a
18
+ href={href}
19
+ class={`footer-link ${className}`}
20
+ target={external ? "_blank" : undefined}
21
+ rel={external ? "noopener noreferrer" : undefined}
22
+ aria-label={ariaLabel}
23
+ >
24
+ <slot />
25
+ </a>
26
+
27
+ <style>
28
+ .footer-link {
29
+ display: inline-block;
30
+ color: var(--color-white);
31
+ font-family: var(--font-family-manrope);
32
+ font-size: var(--font-size-menu);
33
+ font-weight: var(--font-weight-menu);
34
+ line-height: var(--line-height-menu);
35
+ letter-spacing: var(--letter-spacing-menu);
36
+ text-decoration: none;
37
+ transition: color 0.2s ease-in-out;
38
+ border-radius: 2px;
39
+ }
40
+
41
+ .footer-link:hover {
42
+ color: var(--color-primary-60);
43
+ }
44
+
45
+ .footer-link:focus-visible {
46
+ outline: 2px solid var(--color-primary-60);
47
+ outline-offset: 2px;
48
+ }
49
+ </style>
50
+
@@ -0,0 +1,102 @@
1
+ ---
2
+ export interface Props {
3
+ type: "text" | "email" | "tel" | "textarea";
4
+ name: string;
5
+ label: string;
6
+ placeholder: string;
7
+ required?: boolean;
8
+ class?: string;
9
+ }
10
+
11
+ const {
12
+ type,
13
+ name,
14
+ label,
15
+ placeholder,
16
+ required = false,
17
+ class: className = ""
18
+ } = Astro.props;
19
+ ---
20
+
21
+ <div class={`form-input ${className}`}>
22
+ <!-- Label -->
23
+ <label for={name} class="form-input__label">
24
+ {label}
25
+ </label>
26
+
27
+ <!-- Input/Textarea -->
28
+ {type === "textarea" ? (
29
+ <textarea
30
+ id={name}
31
+ name={name}
32
+ placeholder={placeholder}
33
+ required={required}
34
+ rows={4}
35
+ class="form-input__field form-input__textarea"
36
+ ></textarea>
37
+ ) : (
38
+ <input
39
+ type={type}
40
+ id={name}
41
+ name={name}
42
+ placeholder={placeholder}
43
+ required={required}
44
+ class="form-input__field"
45
+ />
46
+ )}
47
+ </div>
48
+
49
+ <style>
50
+ .form-input {
51
+ display: flex;
52
+ flex-direction: column;
53
+ }
54
+
55
+ .form-input__label {
56
+ color: var(--color-white);
57
+ font-family: var(--font-family-manrope);
58
+ font-size: var(--font-size-body-m);
59
+ font-weight: var(--font-weight-medium);
60
+ line-height: var(--line-height-body-m);
61
+ margin-bottom: 8px;
62
+ }
63
+
64
+ .form-input__field {
65
+ width: 100%;
66
+ padding: 12px 16px;
67
+ background-color: rgba(255, 255, 255, 0.2);
68
+ border: 1px solid var(--color-white);
69
+ border-radius: 8px;
70
+ color: var(--color-white);
71
+ font-family: var(--font-family-manrope);
72
+ font-size: var(--font-size-body-m);
73
+ font-weight: var(--font-weight-body-m);
74
+ line-height: var(--line-height-body-m);
75
+ transition: border-color 0.2s ease, box-shadow 0.2s ease;
76
+ outline: none;
77
+ }
78
+
79
+ .form-input__field::placeholder {
80
+ color: var(--color-white);
81
+ opacity: 0.7;
82
+ }
83
+
84
+ .form-input__field:focus {
85
+ border-color: var(--color-primary-60);
86
+ box-shadow: 0 0 0 1px var(--color-primary-60);
87
+ }
88
+
89
+ .form-input__textarea {
90
+ resize: none;
91
+ }
92
+
93
+ /* Estados de validación HTML5 */
94
+ .form-input__field:invalid:not(:placeholder-shown) {
95
+ border-color: var(--color-error);
96
+ }
97
+
98
+ .form-input__field:valid:not(:placeholder-shown) {
99
+ border-color: var(--color-success);
100
+ }
101
+ </style>
102
+
@@ -0,0 +1,99 @@
1
+ ---
2
+ import trophyIcon from "../../icons/trophy-outline.svg?raw";
3
+ import personIcon from "../../icons/person-outline.svg?raw";
4
+ import footballIcon from "../../icons/american-football-outline.svg?raw";
5
+ import laptopIcon from "../../icons/laptop-outline.svg?raw";
6
+
7
+ export interface Props {
8
+ icon:
9
+ | "trophy-outline"
10
+ | "person-outline"
11
+ | "football-american-outline"
12
+ | "laptop-outline";
13
+ text: string;
14
+ title: string;
15
+ class?: string;
16
+ }
17
+
18
+ const { icon, title, text, class: className = "" } = Astro.props;
19
+
20
+ // Mapeo de íconos a contenido SVG
21
+ const iconMap = {
22
+ "trophy-outline": trophyIcon,
23
+ "person-outline": personIcon,
24
+ "football-american-outline": footballIcon,
25
+ "laptop-outline": laptopIcon,
26
+ };
27
+
28
+ const svgContent = iconMap[icon];
29
+ ---
30
+
31
+ <div class={`icon-card ${className}`}>
32
+ <!-- Ícono SVG -->
33
+ <div class="icon-card__icon-wrapper" aria-hidden="true">
34
+ <Fragment set:html={svgContent} />
35
+ </div>
36
+
37
+ <!-- Título -->
38
+ <h3 class="icon-card__title">
39
+ {title}
40
+ </h3>
41
+
42
+ <!-- Texto descriptivo -->
43
+ <p class="icon-card__text">
44
+ {text}
45
+ </p>
46
+ </div>
47
+
48
+ <style>
49
+ .icon-card {
50
+ display: flex;
51
+ flex-direction: column;
52
+ align-items: center;
53
+ text-align: center;
54
+ }
55
+
56
+ .icon-card__icon-wrapper {
57
+ display: flex;
58
+ align-items: center;
59
+ justify-content: center;
60
+ width: 64px;
61
+ height: 64px;
62
+ margin-bottom: 16px;
63
+ }
64
+
65
+ .icon-card__icon-wrapper :global(svg) {
66
+ width: 48px;
67
+ height: 48px;
68
+ color: var(--color-primary-60);
69
+ fill: var(--color-primary-60);
70
+ }
71
+
72
+ .icon-card__title {
73
+ font-family: var(--font-family-manrope);
74
+ font-size: var(--font-size-h3);
75
+ font-weight: var(--font-weight-h3);
76
+ line-height: 1;
77
+ letter-spacing: var(--letter-spacing-h3);
78
+ color: var(--color-primary-60);
79
+ margin-bottom: 8px;
80
+ }
81
+
82
+ .icon-card__text {
83
+ font-family: var(--font-family-manrope);
84
+ font-size: var(--font-size-body-s);
85
+ font-weight: var(--font-weight-medium);
86
+ line-height: var(--line-height-body-s);
87
+ letter-spacing: var(--letter-spacing-body-s);
88
+ color: var(--color-white);
89
+ width: 160px;
90
+ }
91
+
92
+ /* Responsive: ancho mayor en pantallas grandes */
93
+ @media (min-width: 1024px) {
94
+ .icon-card__text {
95
+ width: 270px;
96
+ }
97
+ }
98
+ </style>
99
+
@@ -0,0 +1,59 @@
1
+ ---
2
+ import logoImage from "../../assets/Logo 3.png";
3
+
4
+ export interface Props {
5
+ class?: string;
6
+ size?: "sm" | "md" | "lg";
7
+ href?: string;
8
+ }
9
+
10
+ const {
11
+ class: className = "",
12
+ size = "lg",
13
+ href = "/"
14
+ } = Astro.props;
15
+ ---
16
+
17
+ <a
18
+ href={href}
19
+ class={`logo logo--${size} ${className}`}
20
+ aria-label="ATHLEFI - Ir a la página principal"
21
+ >
22
+ <img
23
+ src={logoImage.src}
24
+ alt="ATHLEFI"
25
+ class="logo__image"
26
+ width={logoImage.width}
27
+ height={logoImage.height}
28
+ />
29
+ </a>
30
+
31
+ <style>
32
+ .logo {
33
+ display: inline-flex;
34
+ align-items: center;
35
+ }
36
+
37
+ .logo__image {
38
+ width: 100%;
39
+ height: 100%;
40
+ object-fit: contain;
41
+ }
42
+
43
+ /* Tamaños */
44
+ .logo--sm {
45
+ width: 96px;
46
+ height: 24px;
47
+ }
48
+
49
+ .logo--md {
50
+ width: 128px;
51
+ height: 32px;
52
+ }
53
+
54
+ .logo--lg {
55
+ width: 208px;
56
+ height: 64px;
57
+ }
58
+ </style>
59
+
@@ -0,0 +1,70 @@
1
+ ---
2
+ export interface Props {
3
+ href: string;
4
+ class?: string;
5
+ isActive?: boolean;
6
+ ariaCurrent?:
7
+ | "page"
8
+ | "step"
9
+ | "location"
10
+ | "date"
11
+ | "time"
12
+ | "true"
13
+ | "false";
14
+ }
15
+
16
+ const {
17
+ href,
18
+ class: className = "",
19
+ isActive = false,
20
+ ariaCurrent = "page",
21
+ } = Astro.props;
22
+
23
+ // Detectar si el enlace está activo basado en la URL actual
24
+ const currentPath = Astro.url.pathname;
25
+ const isCurrentPage =
26
+ currentPath === href || (href !== "/" && currentPath.startsWith(href));
27
+
28
+ const activeState = isActive || isCurrentPage;
29
+ ---
30
+
31
+ <a
32
+ href={href}
33
+ class={`nav-link ${activeState ? "nav-link--active" : ""} ${className}`}
34
+ aria-current={activeState ? ariaCurrent : undefined}
35
+ >
36
+ <slot />
37
+ </a>
38
+
39
+ <style>
40
+ .nav-link {
41
+ display: inline-flex;
42
+ align-items: center;
43
+ padding: 8px 12px;
44
+ font-family: var(--font-family-manrope);
45
+ font-size: var(--font-size-body-m);
46
+ font-weight: var(--font-weight-body-m);
47
+ line-height: var(--line-height-body-m);
48
+ letter-spacing: var(--letter-spacing-body-m);
49
+ color: var(--color-white);
50
+ text-decoration: none;
51
+ border-radius: 6px;
52
+ border-bottom: 2px solid transparent;
53
+ transition: color 0.2s ease-in-out, border-color 0.2s ease-in-out;
54
+ }
55
+
56
+ .nav-link:hover {
57
+ color: var(--color-primary-60);
58
+ }
59
+
60
+ .nav-link:focus-visible {
61
+ outline: 2px solid var(--color-primary-60);
62
+ outline-offset: 2px;
63
+ }
64
+
65
+ .nav-link--active {
66
+ color: var(--color-primary-60);
67
+ border-bottom-color: var(--color-primary-60);
68
+ }
69
+ </style>
70
+