1/** 2 * Humano â interacción transversal (sin dependencias): 3 * · Reveal suave de secciones al entrar en viewport (solo las que empiezan 4 * bajo el pliegue, para no ocultar nunca el hero ni provocar parpadeo). 5 * · Contador que sube cuando el dato "+20.000" se hace visible. 6 * Respeta prefers-reduced-motion: si el usuario lo pide, no anima nada. 7 */ 8( function () { 9 'use strict'; 10 11 var reduce = window.matchMedia && window.matchMedia( '(prefers-reduced-motion: reduce)' ).matches; 12 13 function ready( fn ) { 14 if ( document.readyState !== 'loading' ) { fn(); } 15 else { document.addEventListener( 'DOMContentLoaded', fn ); } 16 } 17 18 // ââ Reveal de secciones ââââââââââââââââââââââââââââââââââââââââââââââââ 19 function initReveal() { 20 if ( reduce || ! ( 'IntersectionObserver' in window ) ) { return; } 21 var fold = window.innerHeight * 0.85; 22 var sections = Array.prototype.slice.call( document.querySelectorAll( 'body section' ) ); 23 var targets = sections.filter( function ( s ) { 24 return s.getBoundingClientRect().top > fold; 25 } ); 26 if ( ! targets.length ) { return; } 27 28 targets.forEach( function ( s ) { s.classList.add( 'humano-reveal' ); } ); 29 30 var io = new IntersectionObserver( function ( entries ) { 31 entries.forEach( function ( e ) { 32 if ( e.isIntersecting ) { 33 e.target.classList.add( 'is-inview' ); 34 io.unobserve( e.target ); 35 } 36 } ); 37 }, { rootMargin: '0px 0px -12% 0px', threshold: 0.08 } ); 38 39 targets.forEach( function ( s ) { io.observe( s ); } ); 40 } 41 42 // ââ Contador que sube ââââââââââââââââââââââââââââââââââââââââââââââââââ 43 function animateCount( elNode ) { 44 var raw = elNode.textContent.trim(); 45 var m = raw.match( /[\d.,]+/ ); 46 if ( ! m ) { return; } 47 var digits = m[ 0 ].replace( /[.,\s]/g, '' ); 48 var target = parseInt( digits, 10 ); 49 if ( ! target || target < 0 ) { return; } 50 var prefix = raw.slice( 0, m.index ); 51 var suffix = raw.slice( m.index + m[ 0 ].length ); 52 var nf = new Intl.NumberFormat( 'es-ES' ); 53 var dur = 1500; 54 var start = null; 55 56 function frame( ts ) { 57 if ( start === null ) { start = ts; } 58 var p = Math.min( 1, ( ts - start ) / dur ); 59 var eased = 1 - Math.pow( 1 - p, 3 ); // easeOutCubic 60 var val = Math.round( eased * target ); 61 elNode.textContent = prefix + nf.format( val ) + suffix; 62 if ( p < 1 ) { window.requestAnimationFrame( frame ); } 63 } 64 window.requestAnimationFrame( frame ); 65 } 66 67 function initCounters() { 68 var nums = Array.prototype.slice.call( document.querySelectorAll( '.humano-social__num' ) ); 69 if ( ! nums.length ) { return; } 70 if ( reduce || ! ( 'IntersectionObserver' in window ) ) { return; } 71 var io = new IntersectionObserver( function ( entries ) { 72 entries.forEach( function ( e ) { 73 if ( e.isIntersecting ) { 74 animateCount( e.target ); 75 io.unobserve( e.target ); 76 } 77 } ); 78 }, { threshold: 0.6 } ); 79 nums.forEach( function ( n ) { io.observe( n ); } ); 80 } 81 82 // ââ Entrada de iconos al viewport ââââââââââââââââââââââââââââââââââââââ 83 function initIcons() { 84 if ( reduce || ! ( 'IntersectionObserver' in window ) ) { return; } 85 var icons = Array.prototype.slice.call( document.querySelectorAll( '.humano-icon' ) ); 86 if ( ! icons.length ) { return; } 87 // Marca <html> para que el estado inicial oculto del CSS solo aplique con JS 88 // (sin JS o con reduced-motion, los iconos quedan visibles por defecto). 89 document.documentElement.classList.add( 'humano-icons-anim' ); 90 var io = new IntersectionObserver( function ( entries ) { 91 entries.forEach( function ( e ) { 92 if ( e.isIntersecting ) { 93 e.target.classList.add( 'is-inview' ); 94 io.unobserve( e.target ); 95 } 96 } ); 97 }, { rootMargin: '0px 0px -8% 0px', threshold: 0.2 } ); 98 icons.forEach( function ( n ) { io.observe( n ); } ); 99 } 100 101 ready( function () { 102 initReveal(); 103 initCounters(); 104 initIcons(); 105 } ); 106}() );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.