---
import { Image } from "astro:assets";
import refraction from "../assets/bg/bg-refraction.webp";
import paper from "../assets/bg/bg-paper.webp";
import split from "../assets/bg/bg-split.webp";
import align from "../assets/bg/bg-align.webp";

/**
 * 배경은 섹션마다 다른 말을 해야 한다. 같은 그림을 전부에 깔면 그건 벽지다.
 * 넷 다 gpt-image-2 로 만들었고, 프롬프트에 이 페이지의 토큰 값을 그대로 넣었다.
 */
const SOURCES = { refraction, paper, split, align } as const;

interface Props {
  variant?: keyof typeof SOURCES;
  /**
   * `fixed`  — 뷰포트에 고정. 콘텐츠만 그 위를 지나간다. 무한히 먼 원경.
   * `drift`  — 스크롤보다 느리게 따라온다. 중경. 종이처럼 가까운 재질에 쓴다.
   */
  mode?: "fixed" | "drift";
  /** drift 전용. 이미지를 컨테이너보다 이 비율만큼 키우고 그 초과분 전체를 움직인다 */
  depth?: number;
  opacity?: number;
  flip?: boolean;
}
const {
  variant = "refraction",
  mode = "fixed",
  depth = 0.35,
  opacity = 0.9,
  flip = false,
} = Astro.props;
const src = SOURCES[variant];

// 밝은 종이만 그대로 얹고, 어두운 광원 사진은 더하기 합성한다.
const additive = variant !== "paper";

const scale = 1 + depth;
const shift = -(depth / scale) * 100;
---

{/*
  패럴랙스의 원형은 "배경이 고정되어 원경처럼 보이는 것"이다.
  느리게 같이 움직이는 것으로는 그 인상이 안 나온다 — 속도만 다를 뿐 같은 방향이다.

  `background-attachment: fixed` 는 쓰지 않는다. iOS Safari 가 GPU 메모리 때문에
  그것을 throttle 해서 스크롤 중 배경이 튀거나 리셋된다.
  대신 부모에 `clip-path: inset(0)` 을 걸어 **fixed 의 컨테이닝 블록**으로 만든다.
  그러면 배경은 뷰포트에 고정되면서 그 섹션 영역에서만 보인다.

  주의: 조상에 `transform`·`filter`·`mask` 가 있으면 그게 컨테이닝 블록이 되어
  이 기법이 통째로 깨진다. 그래서 위아래 페이드 마스크를 포기했다 —
  마스크를 걸면 고정이 사라진다. 경계는 clip 으로 딱 자른다.
*/}
<div
  class="bg-photo"
  class:list={[mode, { flip, additive }]}
  aria-hidden="true"
  style={`--bg-opacity:${opacity}; --bg-h:${scale * 100}%; --bg-shift:${shift.toFixed(2)}%`}
>
  <Image src={src} alt="" widths={[860, 1400, 1920]} sizes="100vw" loading="lazy" decoding="async" />
</div>

<style>
  .bg-photo {
    z-index: -1;
    pointer-events: none;
    grid-column: full;
  }

  /* ---- 원경: 뷰포트에 고정 ---------------------------------- */
  .fixed {
    position: fixed;
    inset: 0;
  }
  .fixed :global(img) {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    opacity: var(--bg-opacity);
  }

  /* ---- 중경: 스크롤보다 느리게 ------------------------------ */
  .drift {
    position: absolute;
    inset: 0;
  }
  .drift :global(img) {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    /* 컨테이너보다 크다. 이 초과분이 곧 움직일 수 있는 거리다 */
    height: var(--bg-h);
    object-fit: cover;
    display: block;
    opacity: var(--bg-opacity);
  }

  /*
    어두운 배경 위의 광원 사진은 opacity 로 누르면 안 된다 — 빛까지 같이 죽는다.
    screen 은 검정을 투명하게 만들고 밝은 곳만 더한다.
  */
  .additive :global(img) { mix-blend-mode: screen; }
  .flip :global(img) { transform: scaleX(-1); }

  @media (prefers-reduced-motion: no-preference) {
    @supports (animation-timeline: view()) {
      /* drift 만 움직인다. fixed 는 애초에 안 움직이는 것이 효과다 */
      .drift :global(img) {
        animation: bg-parallax linear both;
        animation-timeline: view();
        animation-range: cover 0% cover 100%;
      }
      .drift.flip :global(img) { animation-name: bg-parallax-flip; }
    }
  }

  @keyframes bg-parallax {
    from { transform: translateY(0); }
    to   { transform: translateY(var(--bg-shift)); }
  }
  @keyframes bg-parallax-flip {
    from { transform: translateY(0) scaleX(-1); }
    to   { transform: translateY(var(--bg-shift)) scaleX(-1); }
  }

  /* 모션을 줄이는 설정에서는 고정 배경도 부담이 될 수 있다. 흐름에 되돌린다 */
  @media (prefers-reduced-motion: reduce) {
    .fixed { position: absolute; }
  }

  @media (prefers-reduced-transparency: reduce) {
    .additive :global(img) { opacity: calc(var(--bg-opacity) * 0.9); }
    .bg-photo:not(.additive) :global(img) { opacity: calc(var(--bg-opacity) * 0.7); }
  }
</style>
