/* Motion layer. js/motion.js adds html.motion and the classes used here.
   Only the individual translate / scale / rotate properties are used, so nothing here overrides
   a transform set in styles.css. The full motion plays for everyone, even when the OS asks for
   reduced motion (owner decision), so nothing here is gated on that media query. */
:root {
  --ease-in-out: cubic-bezier(.77, 0, .175, 1);
}

/* ---------- gate: the shrine fades up out of the night on load ---------- */
/* from-only keyframes with backwards fill, so the walk-through rules in styles.css still win afterwards.
   The SVG scene only animates while it is the gate; once .has-3d is set, the 3D layer CSS owns its opacity. */
@keyframes gate-fade { from { opacity: 0; } }
@keyframes gate-rise { from { opacity: 0; translate: 0 14px; } }
@keyframes gate-moon-rise { from { opacity: 0; translate: 0 24px; } }
@keyframes gate-torii-rise { from { opacity: 0; translate: 0 28px; scale: .96; } }
html.js .gate:not(.has-3d) .gate-moon { animation: gate-moon-rise 1.2s var(--ease-out) backwards; }
html.js .gate:not(.has-3d) .torii { animation: gate-torii-rise 1s var(--ease-out) .12s backwards; }
html.js .gate:not(.has-3d) .toro { animation: gate-fade .9s ease .4s backwards; }
html.js .gate .gate-name { animation: gate-rise .7s var(--ease-out) .45s backwards; }
html.js .gate .gate-title { animation: gate-rise .7s var(--ease-out) .52s backwards; }
html.js .gate .btn-enter { animation: gate-rise .7s var(--ease-out) .59s backwards; }

/* ---------- scroll reveals ---------- */
/* transitions sit on the .is-in state only, so hiding on load is instant and only the reveal animates */
html.motion .rv { opacity: 0; translate: 0 28px; }
html.motion .rv.is-in {
  opacity: 1; translate: none;
  transition: opacity .9s var(--ease-out) var(--d, 0s), translate 1.1s var(--ease-out) var(--d, 0s);
}

/* section kanji: the brush writes it top to bottom, or left to right when it sits in a row */
html.motion .ink { clip-path: inset(-20% -20% 120% -20%); }
html.motion .ink[data-ink="row"] { clip-path: inset(-20% 120% -20% -20%); }
html.motion .ink.is-in {
  clip-path: inset(-20%);
  transition: clip-path 1.1s var(--ease-in-out) var(--d, 0s);
}

/* hanko: pressed down onto the paper, then it stays */
html.motion .stamp { opacity: 0; scale: 1.5; rotate: -12deg; }
html.motion .stamp.is-in {
  opacity: 1; scale: none; rotate: none;
  transition: opacity .18s ease-out var(--d, 0s), scale .42s var(--ease-out) var(--d, 0s), rotate .42s var(--ease-out) var(--d, 0s);
}

/* the big vertical kanji drift a little slower than the page, which gives the sections depth */
@supports (animation-timeline: view()) {
  @media (min-width: 641px) {
    .section-kanji:not(.section-kanji-row) {
      animation: kanji-drift linear both;
      animation-timeline: view();
      animation-range: cover;
    }
    @keyframes kanji-drift {
      from { translate: 0 40px; }
      to { translate: 0 -40px; }
    }
  }
}

/* ---------- nav: a red ink line follows the section you are reading ---------- */
.topnav { position: relative; }
.nav-ink {
  position: absolute; left: 0; bottom: 0;
  width: 100px; height: 2px;
  background: var(--shu);
  transform-origin: 0 50%;
  opacity: 0;
  pointer-events: none;
  transition: translate .35s var(--ease-in-out), scale .35s var(--ease-in-out), opacity .25s ease;
}
.nav-ink.is-on { opacity: 1; }
.nav-ink.no-slide { transition: opacity .25s ease; }
.topnav a.is-current { color: var(--gofun); }
.topnav a.is-current:hover { text-decoration: none; }

/* ---------- ambient sakura that follow you in from the gate ---------- */
.ambient-petals {
  position: fixed; inset: 0;
  width: 100%; height: 100%;
  z-index: -1;
  pointer-events: none;
  opacity: 0;
  transition: opacity 2s ease .6s;
}
.ambient-petals.is-on { opacity: 1; }

/* ---------- press feedback on the contract copy button ---------- */
.slip-copy:not(:disabled) { transition: scale .12s var(--ease-out); }
.slip-copy:not(:disabled):active { scale: .97; }

/* ---------- sound toggle: lands with the hero actions, gives under a press, and its icon swaps in ---------- */
@keyframes sound-in { from { opacity: 0; scale: .9; translate: 0 8px; } }
@keyframes icon-in { from { opacity: 0; scale: .9; } }
.sound:not([hidden]) {
  animation: sound-in .28s var(--ease-out) 1.6s backwards;
  transition: scale .12s var(--ease-out), translate .3s var(--ease-out), opacity .2s ease;
}
.sound:active { scale: .95; }
.sound svg { animation: icon-in .18s var(--ease-out); }
/* phones: it steps out of the way while you scroll down to read, and comes back when you scroll up (js/motion.js) */
.sound.is-tucked { translate: 0 calc(100% + 28px); opacity: 0; pointer-events: none; }

/* ---------- petal burst on download and copy ---------- */
.burst-petal {
  position: fixed; left: 0; top: 0; z-index: 60;
  border-radius: 50% 0 50% 50%;
  pointer-events: none;
  will-change: transform, opacity;
}

/* ---------- dojo: the old picture fades off a ghost canvas when an option changes (js/motion.js) ---------- */
.pfp-frame { position: relative; }
.pfp-ghost { position: absolute; pointer-events: none; border-radius: 4px; opacity: 0; }

/* ---------- how to buy: the rule above each step is drawn in wet red ink, then dries to a hairline ---------- */
html.motion .steps li::before { scale: 0 1; background-color: var(--shu); }
html.motion .steps li.is-in::before {
  scale: none; background-color: var(--rule);
  transition: scale .9s var(--ease-in-out) var(--d, 0s), background-color 1.4s ease calc(var(--d, 0s) + .7s);
}

/* ---------- hero night: the print settles in layer by layer as the gate fades, then the layers part on scroll ---------- */
/* The arrival animates the individual `translate` property and the parallax animates `transform`, so the two compose
   instead of overriding each other. */
@keyframes night-rise { from { opacity: 0; translate: 0 60px; } }
@keyframes night-fade { from { opacity: 0; } }
html.arrived .night-far { animation: night-rise 1.6s var(--ease-out) 1s backwards; }
html.arrived .night-mid { animation: night-rise 1.6s var(--ease-out) 1.12s backwards; }
html.arrived .night-near { animation: night-rise 1.5s var(--ease-out) 1.24s backwards; }
html.arrived .night-mist { animation: night-fade 2.4s ease 1.4s backwards; }
html.arrived .moon { animation: night-fade 1.8s ease .9s backwards; }

@supports (animation-timeline: scroll()) {
  /* once arrived, each layer drifts at its own depth as the hero scrolls away */
  html.arrived .night-far { animation: night-rise 1.6s var(--ease-out) 1s backwards, par-far linear both; animation-timeline: auto, scroll(root); animation-range: normal, 0 100vh; }
  html.arrived .night-mid { animation: night-rise 1.6s var(--ease-out) 1.12s backwards, par-mid linear both; animation-timeline: auto, scroll(root); animation-range: normal, 0 100vh; }
  html.arrived .night-stars { animation: twinkle 6s ease-in-out infinite alternate, par-stars linear both; animation-timeline: auto, scroll(root); animation-range: normal, 0 100vh; }
  @keyframes par-far { to { transform: translateY(90px); } }
  @keyframes par-mid { to { transform: translateY(45px); } }
  @keyframes par-stars { to { transform: translateY(160px); } }
}

/* ---------- legend: the ofuda drop onto their cords ---------- */
html.motion .ofuda.rv { translate: -50% -36px; }
html.motion .ofuda.rv.is-in { translate: -50% 0; }

/* ---------- footer: the seigaiha tide drifts one tile every 32s, a seamless loop on the compositor ---------- */
@keyframes seigaiha-drift { to { translate: -96px 0; } }
.footer::before { animation: seigaiha-drift 32s linear infinite; }

/* ---------- top bar seal: pressed like a hanko ---------- */
.brand .seal-sm { transition: scale .16s var(--ease-out), rotate .16s var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .brand:hover .seal-sm { scale: .92; rotate: -4deg; }
}
.brand:active .seal-sm { scale: .86; transition-duration: .1s; }

/* ---------- finale: the greeting is brushed on left to right, then the line under it lands ---------- */
html.motion .finale-kana.ink { clip-path: inset(-20% 120% -20% -20%); }
html.motion .finale-kana.ink.is-in { clip-path: inset(-20%); transition: clip-path 1.6s var(--ease-in-out) var(--d, 0s); }

@media print {
  html.motion .rv, html.motion .ink, html.motion .stamp {
    opacity: 1 !important; translate: none !important; scale: none !important;
    rotate: none !important; clip-path: none !important;
  }
  html.motion .steps li::before { scale: none !important; background-color: rgba(243, 241, 236, .14) !important; }
  .ambient-petals, .burst-petal, .nav-ink { display: none !important; }
}
