/* fx — giobi.com motion layer.
   Everything here is opt-in through html.fx (set by an inline script in the
   layout) and switched off for prefers-reduced-motion. Without JS the site
   renders exactly as before. */

/* ── Page transitions (cross-document View Transitions, Chromium) ── */
@view-transition { navigation: auto; }
.site-header { view-transition-name: fx-header; }
::view-transition-old(root) { animation: fx-page-out .22s ease both; }
::view-transition-new(root) { animation: fx-page-in .38s cubic-bezier(.2,.7,.2,1) both; }
@keyframes fx-page-out { to { opacity: 0; transform: translateY(-10px); } }
@keyframes fx-page-in { from { opacity: 0; transform: translateY(14px); } }

/* Theme switch: a circle opening from the theme dot */
html.fx-theme-switch::view-transition-old(root) { animation: none; }
html.fx-theme-switch::view-transition-new(root) {
  animation: fx-theme-in .6s cubic-bezier(.6,0,.2,1) both;
}
@keyframes fx-theme-in {
  from { clip-path: circle(0 at var(--fx-tx, 0) var(--fx-ty, 0)); }
  to { clip-path: circle(var(--fx-tr, 150vmax) at var(--fx-tx, 0) var(--fx-ty, 0)); }
}

/* ── Scroll progress (pure CSS, scroll-driven animations) ── */
@supports (animation-timeline: scroll()) {
  .site-header::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
    background: var(--color-orange); transform-origin: 0 50%; transform: scaleX(0);
    animation: fx-progress linear both; animation-timeline: scroll(root);
  }
  @keyframes fx-progress { to { transform: scaleX(1); } }
}

/* ── Reveal on scroll ── */
html.fx .fx-r {
  opacity: 0; transform: translateY(26px);
  transition: opacity .7s ease, transform .8s cubic-bezier(.2,.7,.2,1);
  transition-delay: calc(var(--fx-i, 0) * 70ms);
}
html.fx .fx-r.is-in { opacity: 1; transform: none; }

/* Section titles: a line that draws itself in */
html.fx .h2-section-title.fx-r, html.fx .pf-group-title.fx-r { position: relative; }
html.fx .h2-section-title.fx-r::before {
  content: ""; position: absolute; left: 0; top: -.55rem; height: 2px; width: 2.4rem;
  background: var(--color-orange); transform: scaleX(0); transform-origin: 0 50%;
  transition: transform .9s .2s cubic-bezier(.2,.7,.2,1);
}
html.fx .h2-section-title.fx-r.is-in::before { transform: scaleX(1); }

/* Hero title, word by word */
html.fx .fx-word { display: inline-block; overflow: hidden; vertical-align: bottom; padding-bottom: .08em; margin-bottom: -.08em; }
html.fx .fx-word > span {
  display: inline-block; transform: translateY(105%);
  animation: fx-word .9s cubic-bezier(.2,.8,.2,1) forwards;
  animation-delay: calc(var(--fx-i, 0) * 80ms + 120ms);
}
@keyframes fx-word { to { transform: none; } }

/* ── Tilt cards ── */
.fx-tilt {
  transform: perspective(900px) rotateX(var(--fx-rx, 0deg)) rotateY(var(--fx-ry, 0deg));
  transition: transform .5s cubic-bezier(.2,.7,.2,1);
  will-change: transform;
}
/* Revealed cards keep the tilt: same transform, higher specificity than .fx-r.is-in */
html.fx .fx-tilt.fx-r.is-in { transform: perspective(900px) rotateX(var(--fx-rx, 0deg)) rotateY(var(--fx-ry, 0deg)); }
.fx-tilt.is-tilting, html.fx .fx-tilt.fx-r.is-tilting { transition: transform .08s linear; transition-delay: 0s; }
.fx-tilt::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
  background: radial-gradient(420px circle at var(--fx-gx, 50%) var(--fx-gy, 50%), rgba(255,255,255,.22), transparent 45%);
  opacity: 0; transition: opacity .3s;
}
.fx-tilt.is-tilting::after { opacity: 1; }

/* ── Hero: three.js lake behind the text, pixel art that breaks apart ── */
.h2-hero-full[data-fx-waves] { position: relative; isolation: isolate; }
.fx-waves {
  position: absolute; inset: 0; z-index: -1; width: 100%; height: 100%;
  opacity: 0; transition: opacity 1.6s ease;
}
.fx-waves.is-on { opacity: 1; }
.h2-hero-art { cursor: crosshair; }
.fx-pixels { position: absolute; pointer-events: none; opacity: 0; transition: opacity .25s; }
.fx-pixels.is-on { opacity: 1; }
.h2-hero-art img.fx-hidden { opacity: 0; }
.h2-hero-art img { transition: opacity .25s; }
.fx-hint {
  position: absolute; bottom: 1.2rem; left: 50%; transform: translateX(-50%);
  font-family: var(--font-mono); font-size: .72rem; letter-spacing: .06em;
  color: rgba(255,255,255,.55); white-space: nowrap; pointer-events: none;
  transition: opacity .4s;
}
.fx-hint.is-gone { opacity: 0; }

/* ── Scramble keeps the link width stable ── */
.fx-scramble { display: inline-block; }

/* ── The owl easter egg ── */
.fx-owl {
  position: fixed; z-index: 200; left: 0; top: 0; width: 92px; height: 92px;
  color: var(--color-orange); pointer-events: none;
  filter: drop-shadow(0 6px 18px rgba(0,0,0,.25));
}
.fx-owl svg { width: 100%; height: 100%; }
.fx-owl .fx-wing-l, .fx-owl .fx-wing-r { transform-box: fill-box; animation: fx-flap .28s ease-in-out infinite alternate; }
.fx-owl .fx-wing-l { transform-origin: 100% 20%; }
.fx-owl .fx-wing-r { transform-origin: 0 20%; animation-direction: alternate-reverse; }
@keyframes fx-flap { from { transform: rotate(-28deg); } to { transform: rotate(18deg); } }
.fx-owl-say {
  position: fixed; z-index: 201; font-family: var(--font-mono); font-size: .82rem;
  background: var(--color-headers); color: var(--color-background);
  padding: .5rem .8rem; border-radius: 10px 10px 10px 2px; pointer-events: none;
  opacity: 0; transform: translateY(6px); transition: opacity .3s, transform .3s;
}
.fx-owl-say.is-on { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
  html.fx .fx-r { opacity: 1; transform: none; transition: none; }
  html.fx .fx-word > span { animation: none; transform: none; }
  .fx-tilt { transform: none !important; }
  .site-header::after { display: none; }
}
