/* Doughbry's first impression: the page load curtain, the triangle spinner, and smooth page changes.
   Loaded on every page right after base.css. Works with js/intro.js.
   Safe by design: with JavaScript off, or for people who ask for less motion, none of this hides anything. */

/* ---------- The triangle spinner (the only spinner on the site) ---------- */
.tri-spinner {
  display: inline-block; width: 1.15em; height: 1.15em; flex: none;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 20 L84 78 H16 Z' stroke='black' stroke-width='18' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 20 L84 78 H16 Z' stroke='black' stroke-width='18' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
  transform-origin: 50% 58%;
  animation: tri-spin 1.35s cubic-bezier(0.65, 0, 0.35, 1) infinite;
  will-change: transform;
}
.tri-spinner--lg { width: 46px; height: 46px; }
@keyframes tri-spin {            /* turns corner to corner, with a tiny rest on each corner */
  0% { transform: rotate(0deg); }
  28%, 33% { transform: rotate(120deg); }
  61%, 66% { transform: rotate(240deg); }
  94%, 100% { transform: rotate(360deg); }
}

/* A button that is busy: add class is-loading (and disable it) while it waits */
.btn.is-loading { position: relative; color: transparent !important; pointer-events: none; }
.btn.is-loading::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: 1.25em; height: 1.25em; margin: -0.72em 0 0 -0.625em;
  background: var(--ink, #14261E);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 20 L84 78 H16 Z' stroke='black' stroke-width='18' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 20 L84 78 H16 Z' stroke='black' stroke-width='18' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
  transform-origin: 50% 58%;
  animation: tri-spin 1.1s cubic-bezier(0.65, 0, 0.35, 1) infinite;
}
.btn--forest.is-loading::after { background: var(--cream, #F0F0E7); }

/* ---------- The page load curtain ---------- */
.intro { display: none; }                       /* never shows unless intro.js asks for it */
html.intro-run { overflow: hidden; }            /* no scrolling behind the curtain */
html.intro-run .intro {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: clamp(1.5rem, 4.5vh, 2.6rem);
  background: var(--red, #D04F30); color: var(--yellow, #F6BE25);
  transform: translate3d(0, 0, 0);
  transition: transform 0.72s cubic-bezier(0.76, 0, 0.24, 1);
  will-change: transform;
}
html.intro-run::before {                         /* a yellow sheet right behind the red one: it follows a beat later, so the lift reads as red, then yellow, then the page */
  content: ""; position: fixed; inset: 0; z-index: 999; pointer-events: none;
  background: var(--yellow, #F6BE25);
  transform: translate3d(0, 0, 0);
  transition: transform 0.72s cubic-bezier(0.76, 0, 0.24, 1) 0.12s;
  will-change: transform;
}
html.intro-out::before { transform: translate3d(0, calc(-100% - 4px), 0); }
html.intro-run .intro::after {                   /* a row of little triangles trailing the curtain as it lifts */
  content: ""; position: absolute; left: 0; right: 0; top: calc(100% - 1px); height: 22px;
  background:
    linear-gradient(135deg, var(--red, #D04F30) 25%, transparent 25%) -22px 0 / 44px 44px repeat-x,
    linear-gradient(225deg, var(--red, #D04F30) 25%, transparent 25%) -22px 0 / 44px 44px repeat-x;
}
.intro__logo { width: min(66vw, 430px); }
.intro__logo img {
  display: block; width: 100%; height: auto;
  animation: intro-logo-in 0.75s cubic-bezier(0.2, 1.25, 0.35, 1) 0.12s both;
  will-change: transform, opacity;
}
html.intro-run .intro .tri-spinner { animation: tri-spin 1.35s cubic-bezier(0.65, 0, 0.35, 1) infinite, intro-fade-in 0.4s ease 0.05s both; }
@keyframes intro-logo-in { from { opacity: 0; transform: translate3d(0, 22px, 0) scale(0.88); } to { opacity: 1; transform: none; } }
@keyframes intro-fade-in { from { opacity: 0; } to { opacity: 1; } }

/* The lift: intro.js adds intro-out when the page is ready */
html.intro-out .intro { transform: translate3d(0, calc(-100% - 26px), 0); }
html.intro-out .intro__logo { transition: transform 0.5s cubic-bezier(0.5, 0, 0.75, 0), opacity 0.3s ease; transform: translate3d(0, -18px, 0) scale(1.04); opacity: 0; }
html.intro-out .intro .tri-spinner { transition: opacity 0.2s ease; opacity: 0; }

/* ---------- Entrances that wait for the curtain ----------
   Put data-enter on anything in the first screen. Give each a step with style="--i:1", "--i:2" ...
   While the curtain is up they wait. The moment it lifts (html.is-ready) they ease in one after another.
   With no JavaScript neither class exists, so everything is simply visible. */
html.intro-run:not(.is-ready) [data-enter] { opacity: 0; }
html.is-ready [data-enter] { animation: enter-up 0.72s cubic-bezier(0.2, 0.8, 0.2, 1) both; animation-delay: calc(var(--i, 0) * 85ms + var(--enter-base, 120ms)); }
html.is-ready [data-enter="pop"] { animation-name: enter-pop; animation-duration: 0.8s; }
html.is-ready [data-enter="fade"] { animation-name: intro-fade-in; }
@keyframes enter-up { from { opacity: 0; transform: translate3d(0, 20px, 0); } to { opacity: 1; transform: none; } }
@keyframes enter-pop { 0% { opacity: 0; transform: scale(0.82) rotate(-6deg); } 60% { opacity: 1; transform: scale(1.04) rotate(1deg); } 100% { opacity: 1; transform: none; } }

/* ---------- Smooth page changes ---------- */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  ::view-transition-old(root) { animation: vt-out 0.2s ease both; }
  ::view-transition-new(root) { animation: vt-in 0.34s cubic-bezier(0.2, 0.8, 0.2, 1) both; }
  .site-header { view-transition-name: site-header; }
}
@keyframes vt-out { to { opacity: 0; transform: translate3d(0, -8px, 0); } }
@keyframes vt-in { from { opacity: 0; transform: translate3d(0, 12px, 0); } }

/* The small "one moment" spinner that appears only if the next page is slow (intro.js adds it) */
.page-wait {
  position: fixed; left: 50%; bottom: calc(18px + env(safe-area-inset-bottom, 0px)); z-index: 900;
  width: 54px; height: 54px; margin-left: -27px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--forest, #1C5642); color: var(--yellow, #F6BE25); border: 3px solid var(--ink, #14261E);
  box-shadow: 0 5px 0 0 rgba(20, 38, 30, 0.9);
  opacity: 0; transform: translate3d(0, 24px, 0) scale(0.9); pointer-events: none;
  transition: opacity 0.25s ease, transform 0.35s cubic-bezier(0.2, 1.2, 0.35, 1);
}
.page-wait .tri-spinner { width: 24px; height: 24px; }
html.is-leaving .page-wait { opacity: 1; transform: none; }

/* ---------- Less motion: no curtain, no movement, everything simply there ---------- */
@media (prefers-reduced-motion: reduce) {
  html.intro-run { overflow: auto; }
  html.intro-run .intro { display: none; }
  html.intro-run::before { display: none; }
  html.intro-run:not(.is-ready) [data-enter] { opacity: 1; }
  html.is-ready [data-enter] { animation: none; }
  .tri-spinner, .btn.is-loading::after { animation: tri-pulse 1.2s ease-in-out infinite !important; animation-duration: 1.2s !important; animation-iteration-count: infinite !important; }
}
@keyframes tri-pulse { 50% { opacity: 0.35; } }
