<head>
  <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Satisfy&family=Tourney:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&display=swap" rel="stylesheet">
</head>

<header>
  <h1>Welcome to the New York Recreational Cricket League</h1>
  <p>Join us to experience the thrill of cricket right in the heart of New York City!</p>
</header>

<section id="about">
  <h2>About the League</h2>
  <p>The New York Recreational Cricket League (NYRCL) is dedicated to promoting the sport of cricket among New Yorkers of all ages. We offer a friendly but competitive environment where players can improve their skills and enjoy the game.</p>
</section>

<section id="join">
  <h2>How to Join</h2>
  <p>Interested in playing? We welcome players of all skill levels! To join, simply fill out our online registration form on our website, or contact us at join@nyrcl.com for more details.</p>
</section>

<section id="fees">
  <h2>League Fees</h2>
  <p>The registration fee for the league is $150 per player, which covers the entire season. This fee includes uniforms, equipment rental, and insurance.</p>
</section>

<section id="location">
  <h2>Location of Games</h2>
  <p>All games are held at the iconic Central Park Cricket Fields, located near the north end of Central Park, easily accessible via public transportation.</p>
</section>

<section id="schedule">
  <h2>Season Schedule</h2>
  <p>The NYRCL season runs from April through September, with games typically held on weekends. Here is the schedule for the upcoming season:</p>
  <ul>
    <li>Opening Day: April 15th</li>
    <li>Mid-Season Tournament: July 8th-9th</li>
    <li>Season Finals: September 20th</li>
    <li>Closing Ceremony: September 30th</li>
  </ul>
</section>

<footer>
  <p>Contact Us: </p>
  <p>Email: info@nyrcl.com | Phone: (555) 123-4567</p>
  <p>Follow us on our social media pages for updates and more information.</p>
</footer>

<!-- MIT License - Copyright (c) 2024 Rafael Romero -->
/** CSS Reset by github.com/Lazzzer00/Best-CSS-Reset-2024 */

*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
  padding: 0;
}

ul[role="list"],
ol[role="list"] {
  list-style: none;
}

html:focus-within {
  scroll-behavior: smooth;
}

a:not([class]) {
  text-decoration-skip-ink: auto;
}

img,
picture,
svg,
video,
canvas {
  max-width: 100%;
  height: auto;
  vertical-align: middle;
  font-style: italic;
  background-repeat: no-repeat;
  background-size: cover;
}

input,
button,
textarea,
select {
  font: inherit;
}

@media (prefers-reduced-motion: reduce) {
  html:focus-within {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
    transition: none;
  }
}

body,
html {
  height: 100%;
  scroll-behavior: smooth;
}

/** End CSS Reset */

body {
  font-family: "Lato", sans-serif;
  font-style: normal;
  text-align: center;
}

h1,
h2 {
  font-family: "Tourney";
}
h2 {
  font-size: 40px;
}

header {
  background-color: #e0ddcf;
  color: #b64c5d;
  display: flex;
  flex-direction: column;
  width: 100%;
  align-items: center;
  justify-content: center;
}

header div {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

header p {
  font-size: 20px;
  margin: 32px auto 64px;
  font-weight: 600;
}

header h1,
header p {
  width: 75%;
  animation: 2s ease-in 1 normal appearFromBelow;
}

@keyframes appearFromBelow {
  from {
    opacity: 0;
    transform: translateY(400%);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

#NY-cricket-league-logo {
  width: 80%;
  margin: 24px auto 16px;
  animation: 2s ease-in 1 normal moveToTheLeft;
}

@keyframes moveToTheLeft {
  from {
    transform: translateX(60%);
  }
  to {
    transform: translateX(0);
  }
}

@media (min-width: 1030px) {
  header {
    height: 70vh;
    flex-direction: row;
    justify-content: space-around; 
  }
  
  header div {
    width: 45%;
  }
  
  header h1,
  header p {
    width: 100%;
  }
  
  #NY-cricket-league-logo {
    width: 33%;
    margin: 0;
  }
}

#about {
  background-color: #b64c5d;
  color: #fff;
  width: 100%;
  margin: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
}

#about p {
  margin: 32px auto;
  width: 70%;
  font-size: 1.2rem;
}

#about div {
  margin: 32px auto;
  transition: transform 1.5s;
}

.hideTextBelow {
  transform: translateY(300px);
}

.showTextBelow {
  transform: translateY(0);
}

#about img {
  display: block;
  width: auto;
  height: auto;
  align-self: center;
  transition: transform 2s;
}

.hideImageFromLeft {
  transform: translateX(-999px);
}

.hideImageFromRight {
  transform: translateX(999px);
}

.showImage {
  transform: translateX(0);
}

@media (min-width: 1030px) {
  #about {
    height: 70vh;
    flex-direction: row;
  }
  
  #about img {
    max-width: 25%;
    align-self: end;
  }
  
  #about img:first-child {
    align-self: start;
  }
  
  #about div {
    margin: 0;
  }
}

#join {
  background-color: #e0ddcf;
  height: 70vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  position: relative;
}

#join h2 {
  margin: 32px auto 0;
  z-index: 2;
  transition: transform 1.5s;
}

#join p {
  width: 80%;
  margin: 16px auto;
  font-size: 1.2rem;
  z-index: 2;
  transition: transform 1.5s;
}

#join p:nth-child(5) {
  margin-top: 32px;
}

#join button {
  font-size: 1.5rem;
  z-index: 2;
  box-shadow: inset 0px 0px 0px 0px #ffffff;
  background-color: #ededed;
  border-radius: 6px;
  border: 1px solid #dcdcdc;
  display: inline-block;
  cursor: pointer;
  color: #000;
  font-size: 15px;
  font-weight: bold;
  padding: 8px 24px;
  text-decoration: none;
  text-shadow: 0px 1px 0px #ffffff;
  transition: transform 1.5s;
  height: 42px;
}

#join button:hover {
  background-color: #dfdfdf;
}
#join button:active {
  position: relative;
  top: 1px;
}

#join div {
  position: absolute;
  width: 100%;
  height: 60vh;
  top: 10vh;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  z-index: 1;
  transition: transform 2s;
}

.shrinkElement {
  transform: scale(0.1);
}

.expandElement {
  transform: scale(1);
}

#fees {
  background-color: #36323c;
  color: #f1f0ea;
  display: flex;
  flex-direction: column;
  align-items: center;
}

#fees h2 {
  margin: 32px auto;
  transition: transform 1.5s;
}

#fees p {
  width: 85%;
  margin: 0 auto;
  font-weight: 600;
  transition: transform 1.5s;
}

#fees div {
  display: flex;
  width: 90%;
  justify-content: start;
  align-items: center;
  margin: 32px auto;
  padding: 20px;
  font-weight: 600;
  border-radius: 6px;
  background: #b64c5d;
  transition: transform 1.5s;
}

#fees div h4 {
  text-align: center;
  margin: 0 auto;
  border-bottom: 2px solid white;
  white-space: nowrap;
  transition: width 1.5s;
  transition-delay: 650ms;
}

.smallPrice {
  width: 14%;
}

.biggerPrice {
  width: 60%;
}

#cricket-action-illustration {
  width: 90%;
  transition: transform 1.5s;
}

@media (min-width: 1030px) {
  #fees div, #fees p {
    width: 60%;
  }
  #cricket-action-illustration {
    width: 33%;  
  }
}

#location {
  background-color: #e0ddcf;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  position: relative;
}

#location h2 {
  margin: 32px auto 0;
  transition: transform 1.5s;
}

#location p {
  margin: 32px auto;
  width: 85%;
  transition: transform 1.5s;
}

#location div {
  width: 98%;
  margin-bottom: 32px;
  transition: transform 1.5s;
}

@media (min-width: 1030px) {
  #location p {
    width: 50%;
  }
  
  #location div {
    width: 65%;
  }
}

#schedule {
  background-color: #b64c5d;
  color: #fefefe;
  display: flex;
  flex-direction: column;
  position: relative;
}

#schedule h2 {
  margin: 32px auto 0;
  background: rgba(72, 63, 63, 0.6);
  padding: 6px 12px;
  border-radius: 4px;
  transition: transform 1.5s;
}

#schedule p {
  margin: 32px auto;
  width: 100%;
  background: rgba(72, 63, 63, 0.8);
  padding: 6px 12px;
  border-radius: 4px;
  transition: transform 1.5s;
}

#schedule ul {
  width: 100%;
  display: grid;
}

#schedule li {
  width: 85%;
  list-style-type: none;
  border: 8px solid #fefefe;
  border-radius: 16px;
  margin: 12px auto;
  justify-self: center;
  transition: transform 1.5s;
}

#schedule div {
  width: 100%;
  padding: 16px;
  display: flex;
  align-items: center;
  background: #fefefe;
}

#schedule img {
  width: 15%;
}

#schedule div p {
  width: 80%;
  margin: 0 auto;
  font-size: 1.3rem;
  font-weight: 600;
  color: #000;
  background: none;
}

@media (min-width: 1030px) {
  #schedule p {
    width: 50%;
  }
  
  #schedule li {
    width: 40%;
    margin: 40px 24px;
  }
  
  #schedule li:nth-child(2) {
    justify-self: start;
  }

  #schedule li:nth-child(3) {
    justify-self: end;
  }
}

footer {
  background-color: #36323c;
  color: #f1f0ea;
  display: flex;
  flex-direction: column;
}

footer p {
  margin: 16px auto;
}

footer p:nth-child(2) {
  margin: 0 auto;
}
/* Almost all images used in this website comes from the google search 'cricket' and uses the Creative Commons License for fair use */

/* Cricket SVG llustration
  https://storyset.com/sport
*/
/* A helpful page for color reference, used for this demo 
  http://colormind.io/bootstrap/
*/
/* SVG icons 
  https://www.svgrepo.com/
*/
/* Good resource for cool svg Blobs
  https://www.blobmaker.app/
*/

/* I tried adding this line on Scroll by vaibhav-lone
  https://codepen.io/vaibhav-lone/pen/WKapRN
  But couldn't make it without adding the SVG directly to the HTML :(
*/

// Email trigger (you will see it later)
function sendEmail() {
  window.open("mailto:join@nyrcl.com");
}

// Getting all sections
const headerElement = document.getElementsByTagName("header")[0];
const aboutSection = document.getElementById("about");
const joinSection = document.getElementById("join");
const feesSection = document.getElementById("fees");
const locationSection = document.getElementById("location");
const scheduleSection = document.getElementById("schedule");

// Here we adding the logo of the Page
(function () {
  let img = document.createElement("img");
  img.setAttribute("id", "NY-cricket-league-logo");
  img.src =
    "https://gist.github.com/user-attachments/assets/c073dc0c-7bf1-47a3-9261-1e3d1c97b554";
  headerElement.prepend(img);
  
  let textContainer = document.createElement("div");
  const headers = headerElement.getElementsByTagName("h1");
  const paragraphs = headerElement.getElementsByTagName("p");
  textContainer.appendChild(headers[0]);
  textContainer.appendChild(paragraphs[0]);
  headerElement.append(textContainer);
})();

// Adding and reorganizing the elements in the about section
(function () {
  let teamImg = document.createElement("img");
  teamImg.setAttribute("id", "cricket-team");
  teamImg.src =
    "https://gist.github.com/user-attachments/assets/532e38fc-7777-40c7-8f3f-7a4eb414788b";

  let kidImg = document.createElement("img");
  kidImg.setAttribute("id", "cricket-boy");
  kidImg.src =
    "https://gist.github.com/user-attachments/assets/bb1963ac-5d68-49cc-9a6b-59931f4e3e17";

  let textContainer = document.createElement("div");
  const headers = aboutSection.getElementsByTagName("h2");
  const paragraphs = aboutSection.getElementsByTagName("p");
  // We created a div and selected the elements in the about section, remember that the tag "selector" return an HTMLCollection
  // Having that in mind we insert the only elements in the section in the new div we created
  if (headers.length > 0 && paragraphs.length > 0) {
    textContainer.prepend(headers[0]);
    textContainer.appendChild(paragraphs[0]);
  }
  // Then we append the new div in the about section, and AFTER that (the order matter here) we insert the images, before and after the div
  aboutSection.appendChild(textContainer);
  aboutSection.insertAdjacentElement("afterbegin", teamImg);
  aboutSection.insertAdjacentElement("beforeend", kidImg);

  // This class will be the initial state of elments animation
  textContainer.classList.add("hideTextBelow");
  teamImg.classList.add("hideImageFromLeft");
  kidImg.classList.add("hideImageFromRight");

  const aboutPos = aboutSection.getBoundingClientRect();
  let lastKnownScrollPosition = 0;
  let ratio = 300;

  // We will see the position of the window and the elements
  document.addEventListener("scroll", (event) => {
    lastKnownScrollPosition = window.scrollY;
    // And when the window is in the position we expect the user to be
    if (lastKnownScrollPosition >= aboutPos.top - ratio) {
      window.requestAnimationFrame(() => {
        // We will add a new class, that will override the initial state of the element animation and make them reach the desired position/shape
        textContainer.classList.add("showTextBelow");
        teamImg.classList.add("showImage");
        kidImg.classList.add("showImage");
      });
    } else {
      // And when the elements are not "in sight" we will revert those changes (when the window position is above them not below)
      textContainer.classList.remove("showTextBelow");
      teamImg.classList.remove("showImage");
      kidImg.classList.remove("showImage");
    }
  });
})();

// We will do similir stuff to the other sections so you can refer the section above for explanation, it's a little crowded with all the comments so take a while and look carefully to all parts

// Join Section
(function () {
  const websiteLabel = document.createElement("p");
  const websiteButton = document.createElement("button");
  const mailLabel = document.createElement("p");
  const mailButton = document.createElement("button");
  const dot = document.createElement("div");
  const headers = joinSection.getElementsByTagName("h2");
  const paragraphs = joinSection.getElementsByTagName("p");

  if (paragraphs.length > 0) {
    paragraphs[0].innerText =
      "Interested in playing? We welcome players of all skill levels! To join...";
    // We need to add the margin styling here because we are transforming the element with innerText
    paragraphs[0].style.marginBottom = "40px";
    paragraphs[0].classList.add("hideTextBelow");
  }

  // We don't need to it with these elements because they are not yet showing in the dom
  websiteLabel.innerText =
    "Simply fill out our online registration form on our website";
  websiteButton.textContent = "Take me there!";
  websiteButton.addEventListener("click", (event) =>
    window.open("https://dev.to/rafajrg21", "_blank")
  );
  joinSection.appendChild(websiteLabel);
  joinSection.appendChild(websiteButton);

  mailLabel.innerText = "Or contact us at join@nyrcl.com for more details";
  mailButton.textContent = "Send a Mail";
  mailButton.addEventListener("click", (event) => sendEmail());
  joinSection.appendChild(mailLabel);
  joinSection.appendChild(mailButton);

  dot.style.backgroundImage =
    "url('https://gist.github.com/user-attachments/assets/8fff7e2a-b66c-4be5-b81f-468a4ab7cf86')";
  joinSection.appendChild(dot);

  websiteLabel.classList.add("hideTextBelow");
  websiteButton.classList.add("hideTextBelow");
  mailLabel.classList.add("hideTextBelow");
  mailButton.classList.add("hideTextBelow");
  headers[0].classList.add("hideTextBelow");
  dot.classList.add("shrinkElement");

  let joinPos = joinSection.getBoundingClientRect();
  let lastKnownScrollPosition = 0;
  let ratio = window.innerWidth <= 500 ? 0 : 450;

  document.addEventListener("scroll", (event) => {
    lastKnownScrollPosition = window.scrollY;
    if (lastKnownScrollPosition >= joinPos.top - ratio) {
      window.requestAnimationFrame(() => {
        websiteLabel.classList.add("showTextBelow");
        websiteButton.classList.add("showTextBelow");
        mailLabel.classList.add("showTextBelow");
        mailButton.classList.add("showTextBelow");
        headers[0].classList.add("showTextBelow");
        paragraphs[0].classList.add("showTextBelow");
        dot.classList.add("expandElement");
      });
    } else {
      websiteLabel.classList.remove("showTextBelow");
      websiteButton.classList.remove("showTextBelow");
      mailLabel.classList.remove("showTextBelow");
      mailButton.classList.remove("showTextBelow");
      headers[0].classList.remove("showTextBelow");
      paragraphs[0].classList.remove("showTextBelow");
      dot.classList.remove("expandElement");
    }
  });
})();

// Fees section
(function () {
  const container = document.createElement("div");
  const price = document.createElement("h4");
  const start = document.createElement("span");
  const end = document.createElement("span");
  const headers = feesSection.getElementsByTagName("h2");
  const paragraphs = feesSection.getElementsByTagName("p");
  let img = document.createElement("img");
  img.setAttribute("id", "cricket-action-illustration");
  img.src =
    "https://gist.github.com/user-attachments/assets/3dd6271f-acae-4e2a-ba4a-d53f909d2921";

  start.innerText = "Season start";
  price.innerText = "150 US$";
  end.innerText = "Season end";

  container.appendChild(start);
  container.appendChild(price);
  container.appendChild(end);
  feesSection.appendChild(container);
  feesSection.appendChild(img);

  headers[0].classList.add("hideTextBelow");
  paragraphs[0].classList.add("hideTextBelow");
  container.classList.add("hideTextBelow");
  price.classList.add("smallPrice");
  img.classList.add("shrinkElement");

  let feesPos = feesSection.getBoundingClientRect();
  let lastKnownScrollPosition = 0;
  let ratio = window.innerWidth <= 500 ? 50 : 450;

  document.addEventListener("scroll", (event) => {
    lastKnownScrollPosition = window.scrollY;
    if (lastKnownScrollPosition >= feesPos.top - ratio) {
      window.requestAnimationFrame(() => {
        headers[0].classList.add("showTextBelow");
        paragraphs[0].classList.add("showTextBelow");
        container.classList.add("showTextBelow");
        price.classList.add("biggerPrice");
        img.classList.add("expandElement");
      });
    } else {
      headers[0].classList.remove("showTextBelow");
      paragraphs[0].classList.remove("showTextBelow");
      container.classList.remove("showTextBelow");
      price.classList.remove("biggerPrice");
      img.classList.remove("expandElement");
    }
  });
})();

// Location Section
(function () {
  // Check if there's an existing iframe to avoid multiple iframes
  const mapContainer = document.createElement("div");
  if (mapContainer.childElementCount > 0) {
    alert(
      "An iframe already exists. Please remove the existing one before adding a new one."
    );
    return;
  }

  // Creating iframe element
  let el = document.createElement("iframe");

  // Setting the values for the attributes
  el.src =
    "https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d6041.261117030968!2d-73.96729677915575!3d40.79213547907594!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x89c2f61feed865df%3A0x4db398720c78be5d!2sNorth%20Meadow!5e0!3m2!1ses-419!2sve!4v1722788933891!5m2!1ses-419!2sve";
  el.width = "100%";
  el.height = "300px";
  el.style.border = "2px solid #36323c";
  el.style.borderRadius = "6px";
  el.allowfullscreen = "";
  el.loading = "lazy";
  el.referrerpolicy = "no-referrer-when-downgrade";

  // Adding the created iframe to div as a child element and then showing them in the location section
  mapContainer.appendChild(el);
  locationSection.appendChild(mapContainer);

  const headers = locationSection.getElementsByTagName("h2");
  const paragraphs = locationSection.getElementsByTagName("p");

  headers[0].classList.add("hideTextBelow");
  paragraphs[0].classList.add("hideTextBelow");
  mapContainer.classList.add("shrinkElement");

  let locationPos = locationSection.getBoundingClientRect();
  let lastKnownScrollPosition = 0;
  let ratio = window.innerWidth <= 500 ? 0 : 450;

  document.addEventListener("scroll", (event) => {
    lastKnownScrollPosition = window.scrollY;
    if (lastKnownScrollPosition >= locationPos.top - ratio) {
      window.requestAnimationFrame(() => {
        headers[0].classList.add("showTextBelow");
        paragraphs[0].classList.add("showTextBelow");
        mapContainer.classList.add("expandElement");
      });
    } else {
      headers[0].classList.remove("showTextBelow");
      paragraphs[0].classList.remove("showTextBelow");
      mapContainer.classList.remove("expandElement");
    }
  });
})();

// Schedule Section
(function () {
  const uls = scheduleSection.getElementsByTagName("ul");
  while (uls[0].firstChild) {
    uls[0].removeChild(uls[0].firstChild);
  }
  
  const parallax = document.createElement("span");
  parallax.style.backgroundImage = "url('https://gist.github.com/user-attachments/assets/0f0baa7b-e12d-4602-8311-ab53233551fa')";
  parallax.style.position = "absolute";
  parallax.style.top = "0";
  parallax.style.left = "0";
  parallax.style.height = "100%";
  parallax.style.width = "100%";
  parallax.style.backgroundAttachment = "fixed";
  parallax.style.backgroundPosition = "center";
  parallax.style.backgroundRepeat = "no-repeat";
  parallax.style.backgroundSize = "cover";
  scheduleSection.prepend(parallax);
  
  const opening = document.createElement("li");
  const openingContainer = document.createElement("div");
  const openingIcon = document.createElement("img");
  const openingText = document.createElement("p");
  const mid = document.createElement("li");
  const midContainer = document.createElement("div");
  const midIcon = document.createElement("img");
  const midText = document.createElement("p");
  const finals = document.createElement("li");
  const finalsContainer = document.createElement("div");
  const finalsIcon = document.createElement("img");
  const finalsText = document.createElement("p");
  const closing = document.createElement("li");
  const closingContainer = document.createElement("div");
  const closingIcon = document.createElement("img");
  const closingText = document.createElement("p");

  openingIcon.setAttribute("id", "olympic-torch-runner-icon");
  openingIcon.src =
    "https://gist.github.com/user-attachments/assets/8f25d475-c580-4c49-8188-921bd08115b5";
  openingContainer.appendChild(openingIcon);
  openingText.innerText = "Opening Day: April 15th";
  openingContainer.appendChild(openingText);
  opening.appendChild(openingContainer);
  uls[0].appendChild(opening);

  midIcon.setAttribute("id", "cricket-icon");
  midIcon.src =
    "https://gist.github.com/user-attachments/assets/e976e5da-87ec-436a-aee0-2fd024804bc4";
  midContainer.appendChild(midIcon);
  midText.innerText = "Mid-Season Tournament: July 8th-9th";
  midContainer.appendChild(midText);
  mid.appendChild(midContainer);
  uls[0].appendChild(mid);

  finalsIcon.setAttribute("id", "champions-cup-icon");
  finalsIcon.src =
    "https://gist.github.com/user-attachments/assets/a49eadfe-dc42-4e93-87d1-e6df6e8bc7b9";
  finalsContainer.appendChild(finalsIcon);
  finalsText.innerText = "Season Finals: September 20th";
  finalsContainer.appendChild(finalsText);
  finals.appendChild(finalsContainer);
  uls[0].appendChild(finals);

  closingIcon.setAttribute("id", "podium-icon");
  closingIcon.src =
    "https://gist.github.com/user-attachments/assets/7bc66228-8cb1-4237-b5a2-cedb316653bb";
  closingContainer.appendChild(closingIcon);
  closingText.innerText = "Season Finals: September 20th";
  closingContainer.appendChild(closingText);
  closing.appendChild(closingContainer);
  uls[0].appendChild(closing);

  const headers = scheduleSection.getElementsByTagName("h2");
  const paragraphs = scheduleSection.getElementsByTagName("p");

  headers[0].classList.add("hideTextBelow");
  paragraphs[0].classList.add("hideTextBelow");
  opening.classList.add("hideTextBelow");
  mid.classList.add("hideTextBelow");
  finals.classList.add("hideTextBelow");
  closing.classList.add("hideTextBelow");

  let schedulePos = scheduleSection.getBoundingClientRect();
  let openingPos = opening.getBoundingClientRect();
  let midPos = mid.getBoundingClientRect();
  let finalsPos = finals.getBoundingClientRect();
  let closingPos = closing.getBoundingClientRect();
  let lastKnownScrollPosition = 0;
  let ratio = window.innerWidth <= 500 ? 250 : 600;

  document.addEventListener("scroll", (event) => {
    lastKnownScrollPosition = window.scrollY;
    if (lastKnownScrollPosition >= schedulePos.top - ratio) {
      window.requestAnimationFrame(() => {
        headers[0].classList.add("showTextBelow");
        paragraphs[0].classList.add("showTextBelow");
      });
    } else {
      headers[0].classList.remove("showTextBelow");
      paragraphs[0].classList.remove("showTextBelow");
    }

    if (lastKnownScrollPosition >= openingPos.top - ratio) {
      window.requestAnimationFrame(() => {
        opening.classList.add("showTextBelow");
      });
    } else {
      opening.classList.remove("showTextBelow");
    }

    if (lastKnownScrollPosition >= midPos.top - ratio) {
      window.requestAnimationFrame(() => {
        mid.classList.add("showTextBelow");
      });
    } else {
      mid.classList.remove("showTextBelow");
    }

    if (lastKnownScrollPosition >= finalsPos.top - ratio) {
      window.requestAnimationFrame(() => {
        finals.classList.add("showTextBelow");
      });
    } else {
      finals.classList.remove("showTextBelow");
    }

    if (lastKnownScrollPosition >= closingPos.top - ratio) {
      window.requestAnimationFrame(() => {
        closing.classList.add("showTextBelow");
      });
    } else {
      closing.classList.remove("showTextBelow");
    }
  });
})();

/* Links for various references
https://stackoverflow.com/questions/20307555/how-to-make-text-appear-on-scroll-in-html

https://developer.mozilla.org/en-US/docs/Web/API/Document/scroll_event

https://stackoverflow.com/questions/442404/retrieve-the-position-x-y-of-an-html-element

https://stackoverflow.com/questions/16303954/setting-button-text-via-javascript

https://www.geeksforgeeks.org/dynamically-create-and-remove-iframe-in-javascript/

https://www.tutorialspoint.com/how-to-add-google-map-inside-html-page-without-using-api-key

https://developer.mozilla.org/es/docs/Web/API/Document/createElementNS

https://www.w3schools.com/howto/howto_css_parallax.asp
*/

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.