textos com bordas

Insira o código no campo CSS personalizado do widget TITULO acima:

				
					selector .elementor-heading-title::after,
selector .elementor-heading-title::before {
content: "TEXTOS COM BORDAS";
padding-left: 22px;
text-align: center;
position: absolute;
top: 0;
left: 0;
background: #ffffff;
background-clip: text;
-webkit-background-clip: text;
color: transparent !important;
-webkit-text-fill-color: transparent;
z-index: 1;
}
selector .elementor-heading-title::before{
background: none;
z-index: 0;
text-stroke: 2px #000000;
-webkit-text-stroke: 5px #000000;
}
selector {
opacity: 0.3;
mask-image: linear-gradient(to bottom, #000, transparent);
-webki-mask-image: linear-gradient(to bottom, #000, transparent);
}

				
			

Textos com degradê

Insira o código no campo CSS personalizado do widget TITULO acima:

				
					selector .elementor-heading-title{
background: linear-gradient(45deg, #000000, #ffffff);
background-clip: text;
-webkit-background-clip: text;
color: transparent !important;
-webkit-text-fill-color: transparent;
}
				
			

Textos com degradê em uma palavra específica

Insira o código no campo CSS personalizado do widget TITULO acima:

				
					.degrade{
background: linear-gradient(45deg, #000000, #ffffff);
background-clip: text;
-webkit-background-clip: text;
color: transparent !important;
-webkit-text-fill-color: transparent;
}
				
			

Em seguida coloque a palavra entre o código span abaixo:

				
					<span class="degrade"></span>
				
			

Textos que aparecem e mudam no scroll

Insira o código no campo CSS personalizado de cada texto em específico.

				
					.container-titulos {
    position: relative;
    width: 100%;
    height: 1000vh; /*controle a duração do scroll por aqui*/
    opacity: 0;
}

.container-sticky {
    position: sticky;
    top: 0;
    left: 0;
    height: 100vh;
}

.frases {
    text-wrap: balance; /*equilibra a quantidade de palavras por linha*/
}

.frases.oculto {
    visibility: hidden;
    position: absolute;
}
				
			

Javascript (Widget HTML no rodapé da página):

				
					<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/ScrollTrigger.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/SplitText.min.js"></script>

<script>
gsap.registerPlugin(ScrollTrigger, SplitText);

(function () {
  let splits = [];
  let masters = [];

  function destroyAll() {
    splits.forEach(s => { try { s.revert(); } catch(e){} });
    splits = [];
    masters.forEach(tl => { try { tl.kill(); } catch(e){} });
    masters = [];
    ScrollTrigger.getAll().forEach(st => st.kill());
    gsap.killTweensOf("*");
  }

  function build() {
    const containers = document.querySelectorAll('.container-titulos');

    containers.forEach(container => {
      container.style.opacity = "1";

      const frases = Array.from(
        container.querySelectorAll('.frases .elementor-heading-title')
      );

      const timelineMestre = gsap.timeline({
        scrollTrigger: {
          trigger: container,
          start: "top 10%",
          end: "bottom bottom",
          scrub: true,
        }
      });

      const duracaoAparecer = 1;  
      const duracaoSumir    = 1;
      const sobreposicao    = 0.05;

      frases.forEach((frase, index) => {
        frase.setAttribute("aria-label", frase.textContent);

        if (frase._split) { try { frase._split.revert(); } catch(e){} }

        const split = new SplitText(frase, {
          type: "words,chars",
          wordsClass: "word",
          charsClass: "char"
        });
        frase._split = split;
        splits.push(split);

        gsap.set(frase, { visibility: "visible" });
        void frase.offsetHeight;

        const timelineFrase = gsap.timeline();

        timelineFrase.from(split.chars, {
          autoAlpha: 0,
        //   filter: "blur(10px)",
          stagger: { amount: duracaoAparecer, from: "start" },
          duration: duracaoAparecer
        });

        if (index < frases.length - 1) {
          timelineFrase.to(split.chars, {
            autoAlpha: 0,
            // filter: "blur(10px)",
            stagger: { amount: duracaoSumir, from: "start" }, //mude para end, caso queira que suma de trás para frente
            duration: duracaoSumir
          });
        }

        timelineMestre.add(timelineFrase, index === 0 ? undefined : `-=${sobreposicao}`);
      });

      masters.push(timelineMestre);
    });

    requestAnimationFrame(() => ScrollTrigger.refresh());
  }

  function start() {
    requestAnimationFrame(() => requestAnimationFrame(build));
  }

  function initAfterFonts() {
    if (document.fonts && document.fonts.ready) {
      document.fonts.ready.then(start).catch(start);
    } else {
      start();
    }
  }

  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", initAfterFonts, { once: true });
  } else {
    initAfterFonts();
  }

  let lastW = window.innerWidth, lastH = window.innerHeight, to;
  window.addEventListener("resize", () => {
    const w = window.innerWidth, h = window.innerHeight;
    if (w !== lastW || Math.abs(h - lastH) > 80) {
      lastW = w; lastH = h;
      clearTimeout(to);
      to = setTimeout(() => { destroyAll(); initAfterFonts(); }, 120);
    }
  }, { passive: true });

})();
</script>
				
			

Essa é a primeira frase

depois vem essa

e a terceira é esta aqui que tem mais texto e poderia ter mais

esta é a última frase.