Curbside Dark Logo

Curbside

Curbside Dark Logo

Curbside

/* ========== PAGE TRANSITION ========== */
.w-page-transition {
  position: fixed;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: -9999;
}

/* --- Dark layer --- */
.w-page-transition-dark {
  position: absolute;
  height: 100vh;
  inset: 0;
  background: var(--bg-dark, #000);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 20px;
  opacity: 0;
  transition: opacity 0.8s cubic-bezier(0.77, 0, 0.175, 1);
   z-index: 1;
}

.w-page-transition-dark.active {
  opacity: 1;
}

/* --- Dark - Logo wrapper --- */
.w-page-transition-dark__logo-wrapper {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) translateY(50%);
  display: flex;
  flex-direction: row;
  justify-content: center;
  gap: 20px;
  opacity: 0;
  transition: transform 0.8s ease, opacity 0.8s ease;
  z-index: 2;
}

.w-page-transition-dark__logo-wrapper.active {
  transform: translate(-50%, -50%) translateY(0);
  opacity: 1;
}

.w-page-transition-dark__text {
  color: var(--text-title-contrast, #fff);
  font-size: clamp(32px, 4vw, 100px);
}

.w-page-transition-dark__favicon {
  opacity: 0;
  width: 80px;
  height: 80px;
}

/* --- Light layer --- */
.w-page-transition-light {
  position: absolute;
  height: 100vh;
  inset: 0;
  background: var(--bg-body, #fff);
  display: flex;
  align-items: center;
  justify-content: center;
  transform: translateY(100%);
  transition: transform 1s cubic-bezier(0.77, 0, 0.175, 1);
  z-index: 3;
}

.w-page-transition-light.active {
  transform: translateY(0);
}

/* --- Light - Logo wrapper --- */
.w-page-transition-light__logo-wrapper {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) translateY(0);
  display: flex;
  flex-direction: row;
  justify-content: center;
  gap: 20px;
  opacity: 0;
  transition: opacity 0.6s ease 0.3s, transform 0.6s ease 0.3s;
  z-index: 4;
}

.w-page-transition-light__logo-wrapper.active {
  opacity: 1;
  transform: translate(-50%, -50%) translateY(0);
}

.w-page-transition-light__text {
  color: var(--text-title, #000);
  font-size: clamp(32px, 4vw, 100px);
}

.w-page-transition-light__favicon {
  width: 80px;
  height: 80px;
  opacity: 0;
  transform: scale(0) rotate(-90deg);
  transition: all 0.6s ease 0.3s;
}

.w-page-transition-light__favicon.appear {
  opacity: 1;
  transform: scale(1) rotate(0);
}


document.addEventListener("DOMContentLoaded", () => {
  const dark = document.querySelector(".w-page-transition-dark");
  const darkWrapper = document.querySelector(".w-page-transition-dark__logo-wrapper");
  const light = document.querySelector(".w-page-transition-light");
  const lightWrapper = document.querySelector(".w-page-transition-light__logo-wrapper");
  const favicon = document.querySelector(".w-page-transition-light__favicon");
  const pageTransition = document.querySelector(".w-page-transition");

  if (!dark || !light || !pageTransition) return;

  /** Helper delay */
  function wait(ms) {
    return new Promise((res) => setTimeout(res, ms));
  }

  /** PAGE LEAVE (trước khi chuyển trang) **/
  function startLeave() {
    pageTransition.style.zIndex = "9999";
    dark.classList.add("active");
  }

  /** PAGE ENTER (hiệu ứng khi vào trang) **/
  async function startEnter() {
    // Luôn đảm bảo z-index cao khi bắt đầu
    pageTransition.style.zIndex = "9999";

    // Step 1: Dark layer fade in
    dark.classList.add("active");
    await wait(600);

    // Step 2: Logo/text dark xuất hiện
    darkWrapper.classList.add("active");
    await wait(800);

    // Step 3: Light layer trượt lên
    light.classList.add("active");
    lightWrapper.classList.add("active");
    await wait(1000);

    // Step 4: Logo favicon hiện ra
    favicon.classList.add("appear");
    await wait(1200);

    // Step 5: Toàn bộ transition fade out nhanh
    pageTransition.style.transition = "opacity 0.6s ease";
    pageTransition.style.opacity = "0";
    await wait(1200);

    // Step 6: Reset trạng thái cho lần sau
    dark.classList.remove("active");
    darkWrapper.classList.remove("active");
    light.classList.remove("active");
    lightWrapper.classList.remove("active");
    favicon.classList.remove("appear");

    // Reset style sau khi đã ẩn hẳn
    pageTransition.style.opacity = "";
    pageTransition.style.transition = "";

    // Đưa z-index xuống thấp để không che nội dung
    pageTransition.style.zIndex = "-9999";
  }

  /** Run on initial load **/
  startEnter();

  /** Trigger transition khi click link **/
  document.querySelectorAll("a[href]").forEach((link) => {
    link.addEventListener("click", (e) => {
      const url = link.href;
      if (
        url.includes("#") ||
        url.startsWith("mailto:") ||
        url.startsWith("tel:") ||
        link.target === "_blank"
      )
        return;

      e.preventDefault();
      startLeave();
      setTimeout(() => {
        window.location.href = url;
      }, 600);
    });
  });
});

The Baker’s Son

Category: Bakery

A heritage bakery reimagined for a new generation, blending Filipino tradition with modern taste and storytelling.

From Flour to Legacy
The Scent of Home

Brief.

A heartfelt narrative that celebrates craftsmanship passed through generations, showcasing the beauty of family, hard work, and cultural pride.

Challenge.

Translating decades of tradition and emotional depth into visuals that feel both nostalgic and fresh for younger audiences.

Warm Light, Honest Craft.

Through lifestyle photography, cinematic food videography, and community-driven social content, the project captures the soul of early-morning baking and the enduring warmth that turns a loaf of bread into a family story.

Watch the film.