// ========================================================================== // FOOTER // ========================================================================== @use '../abstracts/variables' as v; @use '../abstracts/mixins' as mix; @use 'sass:map'; .footer { background: transparent; color: v.$white; position: relative; overflow: hidden; .footer-main { position: relative; z-index: 1; padding: map.get(v.$spacers, 8) 0 map.get(v.$spacers, 4); @include mix.respond-to-max('md') { padding: map.get(v.$spacers, 6) 0 map.get(v.$spacers, 3); } } .footer-content { display: grid; grid-template-columns: repeat(5, 1fr); gap: map.get(v.$spacers, 4); align-items: start; @include mix.respond-to-max('md') { grid-template-columns: repeat(3, 1fr); gap: map.get(v.$spacers, 4); } @include mix.respond-to-max('sm') { @include mix.flex(column, center, center); gap: map.get(v.$spacers, 4); } } .footer-section { width: 100%; max-width: 300px; } .footer-title { font-family: v.$font-family-heading; font-size: map.get(v.$font-sizes, 'lg'); font-weight: map.get(v.$font-weights, 'semibold'); margin-bottom: map.get(v.$spacers, 3); color: v.$white; position: relative; &::after { content: ''; position: absolute; bottom: -8px; left: 0; width: 40px; height: 2px; background: v.$primary-light; } } .footer-about { .footer-logo { margin-bottom: map.get(v.$spacers, 3); .image { max-width: 150px; height: auto; } @include mix.respond-to-max('sm') { text-align: center; } } .footer-description { font-size: map.get(v.$font-sizes, 'sm'); line-height: 1.6; margin-bottom: map.get(v.$spacers, 4); opacity: 0.9; color: rgba(v.$white, 0.9); } .footer-social { display: flex; flex-direction: column; margin-top: map.get(v.$spacers, 2); .social-label { display: block; font-size: map.get(v.$font-sizes, 'sm'); font-weight: map.get(v.$font-weights, 'medium'); margin-bottom: map.get(v.$spacers, 3); opacity: 0.9; color: rgba(v.$white, 0.9); } .social-links { @include mix.flex(row, flex-start, center); gap: map.get(v.$spacers, 2); flex-wrap: wrap; @include mix.respond-to-max('md') { @include mix.justify-content(center); } } .social-link { width: 40px; height: 40px; background: rgba(v.$white, 0.1); @include mix.border-radius(50%); @include mix.flex(row, center, center); color: v.$white; text-decoration: none; @include mix.transition(v.$transition-base); backdrop-filter: blur(10px); svg { width: 18px; height: 18px; fill: currentColor; } &:hover { background: rgba(v.$primary-light, 0.3); @include mix.transform(translateY(-3px)); @include mix.box-shadow(0 5px 15px rgba(v.$primary-light, 0.3)); } } } } .footer-menu { list-style: none; padding: 0; margin: 0; li { margin-bottom: map.get(v.$spacers, 2); &:last-child { margin-bottom: 0; } } @include mix.respond-to-max('sm') { padding-top: 10px; padding-left: 10px; } } .footer-link { color: rgba(v.$white, 0.8); font-size: map.get(v.$font-sizes, 'sm'); text-decoration: none; @include mix.transition(v.$transition-base); display: inline-block; &:hover { color: v.$primary-light; @include mix.transform(translateX(5px)); } } .footer-contact { @include mix.flex(column, center, center); .footer-contact-info { @include mix.flex(column, flex-start, stretch); gap: map.get(v.$spacers, 3); } .contact-item { @include mix.flex(row, flex-start, flex-start); gap: map.get(v.$spacers, 2); &:last-child { margin-bottom: 0; } .contact-icon { flex-shrink: 0; width: 20px; height: 20px; margin-top: 2px; color: v.$primary-light; svg { width: 100%; height: 100%; fill: currentColor; } } .contact-text { @include mix.flex(column, flex-start, flex-start); gap: map.get(v.$spacers, 1); .contact-label { font-size: map.get(v.$font-sizes, 'xs'); font-weight: map.get(v.$font-weights, 'medium'); color: v.$primary-light; text-transform: uppercase; letter-spacing: 0.5px; } .contact-value { font-size: map.get(v.$font-sizes, 'sm'); font-weight: map.get(v.$font-weights, 'regular'); color: rgba(v.$white, 0.9); line-height: 1.5; } } } } .footer-newsletter { .newsletter-description { font-size: map.get(v.$font-sizes, 'sm'); line-height: 1.6; margin-bottom: map.get(v.$spacers, 3); opacity: 0.9; color: rgba(v.$white, 0.9); } .newsletter-form { margin-bottom: map.get(v.$spacers, 4); } .newsletter-input-group { @include mix.flex(row, flex-start, stretch); margin-bottom: map.get(v.$spacers, 2); background: rgba(v.$white, 0.1); @include mix.border-radius(50px); padding: 4px; backdrop-filter: blur(10px); } .newsletter-input { flex: 1; background: transparent; border: none; padding: map.get(v.$spacers, 2) map.get(v.$spacers, 3); color: v.$white; font-size: map.get(v.$font-sizes, 'sm'); font-family: v.$font-family-sans; outline: none; @include mix.transition(v.$transition-base); &::placeholder { color: rgba(v.$white, 0.6); } &:focus { background: rgba(v.$white, 0.05); } } .newsletter-btn { width: 40px; height: 40px; background: v.$primary-light; border: none; @include mix.border-radius(50%); color: v.$white; cursor: pointer; @include mix.flex(row, center, center); @include mix.transition(v.$transition-base); svg { width: 16px; height: 16px; fill: currentColor; } &:hover { background: v.$primary; @include mix.transform(scale(1.05)); } } .newsletter-checkbox { @include mix.flex(row, flex-start, flex-start); gap: map.get(v.$spacers, 2); font-size: map.get(v.$font-sizes, 'xs'); cursor: pointer; line-height: 1.4; input { display: none; &:checked + .checkmark { background-color: v.$primary-light; border-color: v.$primary-light; &::after { display: block; } } } .checkmark { position: relative; width: 16px; height: 16px; border: 2px solid rgba(v.$white, 0.3); @include mix.border-radius(v.$border-radius-sm); @include mix.transition(v.$transition-base); flex-shrink: 0; margin-top: 1px; &::after { content: ''; position: absolute; display: none; left: 4px; top: 0px; width: 4px; height: 8px; border: solid v.$white; border-width: 0 2px 2px 0; @include mix.transform(rotate(45deg)); } } .checkbox-text { color: rgba(v.$white, 0.8); a { color: v.$primary-light; text-decoration: none; @include mix.transition(v.$transition-base); &:hover { text-decoration: underline; color: v.$white; } } } } .footer-copyright { margin-top: map.get(v.$spacers, 4); padding-top: map.get(v.$spacers, 3); border-top: 1px solid rgba(v.$white, 0.1); p { font-size: map.get(v.$font-sizes, 'sm'); color: rgba(v.$white, 0.8); margin: 0; @include mix.respond-to-max('sm') { font-size: map.get(v.$font-sizes, 'xs'); text-align: center; } } } } } .scroll-to-top { position: fixed; bottom: map.get(v.$spacers, 5); right: map.get(v.$spacers, 5); width: 50px; height: 50px; background: v.$primary; color: v.$white; border: none; @include mix.border-radius(50%); cursor: pointer; // Cambiado de display: none a opacity/visibility para mejores transiciones opacity: 0; visibility: hidden; @include mix.flex(row, center, center); @include mix.box-shadow(v.$box-shadow-lg); @include mix.transition(v.$transition-base); @include mix.transform(translateY(20px) scale(0.8)); z-index: map.get(v.$z-indices, 'fixed'); svg { width: 20px; height: 20px; fill: currentColor; @include mix.transition(transform 0.2s ease); } &:hover { background: v.$primary-dark; @include mix.transform(translateY(-3px) scale(1.05)); @include mix.box-shadow(0 6px 20px rgba(v.$primary, 0.4)); svg { @include mix.transform(translateY(-2px)); } } &.show { opacity: 1; visibility: visible; @include mix.transform(translateY(0) scale(1)); } // Estado activo/click &:active { @include mix.transform(translateY(-1px) scale(0.95)); } // Estado de scrolling (previene múltiples clicks) &.scrolling { pointer-events: none; opacity: 0.7; svg { animation: scrolling-spin 0.8s linear infinite; } } // Accesibilidad - estado de focus &:focus { outline: none; @include mix.box-shadow(0 0 0 3px rgba(v.$primary, 0.3)); } @include mix.respond-to-max('md') { bottom: map.get(v.$spacers, 4); right: map.get(v.$spacers, 4); width: 45px; height: 45px; svg { width: 18px; height: 18px; } } @include mix.respond-to-max('sm') { bottom: map.get(v.$spacers, 3); right: map.get(v.$spacers, 3); width: 40px; height: 40px; svg { width: 16px; height: 16px; } } } // Animación de rotación para el estado scrolling @keyframes scrolling-spin { 0% { @include mix.transform(rotate(0deg)); } 100% { @include mix.transform(rotate(360deg)); } } // Animación fadeInUp (mantiene tu animación original como alternativa) @keyframes fadeInUp { from { opacity: 0; @include mix.transform(translateY(20px)); } to { opacity: 1; @include mix.transform(translateY(0)); } } // Soporte para movimiento reducido @media (prefers-reduced-motion: reduce) { .scroll-to-top { @include mix.transition(opacity 0.2s ease); &.show { @include mix.transform(none); } &:hover { @include mix.transform(translateY(-3px)); } svg { @include mix.transition(none); } } @keyframes scrolling-spin { 0%, 100% { @include mix.transform(none); } } } // ========================================================================== // ANIMATIONS // ========================================================================== @keyframes fadeInUp { from { opacity: 0; @include mix.transform(translateY(20px)); } to { opacity: 1; @include mix.transform(translateY(0)); } } .footer-section { animation: fadeInUp 0.6s ease-out; animation-fill-mode: both; &[data-aos] { animation: none; // Let AOS handle animations when available } }