@charset "UTF-8";
/* ==========================================================================
   photo-anm.css
   Grid Tile Flip Transition  —  写真を正方形タイルに分割し、
   左上 → 右下の斜め方向の波でパラパラとめくれながら次の写真へ切り替わる演出。

   ※ 数値の調整は JS 側の PHOTO_ANM_DEFAULTS でおこないます。
     （JS が下記のカスタムプロパティへ流し込みます）
       --photo-anm-grid           分割数
       --photo-anm-flip-duration  1タイルのめくれ時間
       --photo-anm-delay-step     斜め1段ごとの遅延
       --photo-anm-perspective    3Dの奥行き
       --photo-anm-ease           イージング
       --photo-anm-shade          陰影の濃さ
       --photo-anm-overlap        タイルの重なり（継ぎ目防止）
       --photo-anm-rx / --photo-anm-ry / --photo-anm-flip-deg  回転軸と方向
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. セクション本体
   -------------------------------------------------------------------------- */
.photo_anm {
  position: relative;
  width: 100%;
  margin: 0;
  padding: 0;
}

/* --------------------------------------------------------------------------
   2. ステージ（写真が表示される枠）
   -------------------------------------------------------------------------- */
.photo_anm__stage {
  /* --- JS から上書きされる既定値 --- */
  --photo-anm-grid: 8;
  --photo-anm-flip-duration: 0.65s;
  --photo-anm-delay-step: 0.06s;
  --photo-anm-perspective: 900px;
  --photo-anm-ease: cubic-bezier(0.45, 0.05, 0.25, 1);
  --photo-anm-shade: 0.38;
  --photo-anm-overlap: 1px;
  --photo-anm-rx: 0;
  --photo-anm-ry: 1;
  --photo-anm-flip-deg: 180deg;
  --photo-anm-ratio: 16 / 9;

  /* --- ここから下は JS（ResizeObserver）が実寸(px)を入れます --- */
  --photo-anm-stage-w: 0px;   /* ステージの実寸・横 */
  --photo-anm-stage-h: 0px;   /* ステージの実寸・縦 */
  --photo-anm-tile-w: 0px;    /* タイル1枚の横（= ステージ横 ÷ 列数） */
  --photo-anm-tile-h: 0px;    /* タイル1枚の縦（正方形モードでは横と同値） */
  --photo-anm-offset-y: 0px;  /* 正方形を保つための縦方向のはみ出し調整 */

  position: relative;
  width: 100%;
  aspect-ratio: var(--photo-anm-ratio);
  overflow: hidden;
  background-color: #000;          /* 白背景が覗かないよう黒で下敷き */
  isolation: isolate;
  -webkit-user-select: none;
          user-select: none;
}

/* 親要素の高さいっぱいに敷きたい場合は section に .photo_anm--fill を付与 */
.photo_anm--fill .photo_anm__stage {
  aspect-ratio: auto;
  height: 100%;
}

/* --------------------------------------------------------------------------
   3. ベースレイヤー（常に「次の写真」を敷いておく）
      → タイルが真横（90°）を向いて消える瞬間や、わずかな隙間から
        白背景ではなく必ず次の写真が覗くようにするための保険。
   -------------------------------------------------------------------------- */
.photo_anm__base {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  z-index: 0;
}

.photo_anm__base img {
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  object-position: center;
}

/* --------------------------------------------------------------------------
   4. タイルを並べるグリッド
   -------------------------------------------------------------------------- */
.photo_anm__grid {
  position: absolute;
  inset: 0;
  z-index: 1;
  opacity: 1;
  transition: opacity 0.6s linear;
}

/* --------------------------------------------------------------------------
   5. タイル 1 枚
      --col / --row / --photo-anm-delay は JS がインラインで付与します。
      幅・高さを --photo-anm-overlap 分だけ大きくして継ぎ目（隙間）を消します。
   -------------------------------------------------------------------------- */
.photo_anm__tile {
  position: absolute;
  left: calc(var(--photo-anm-tile-w) * var(--col));
  top: calc(var(--photo-anm-offset-y) + var(--photo-anm-tile-h) * var(--row));
  width: calc(var(--photo-anm-tile-w) + var(--photo-anm-overlap));
  height: calc(var(--photo-anm-tile-h) + var(--photo-anm-overlap));
  perspective: var(--photo-anm-perspective);   /* タイルごとに遠近法 */
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   6. カード（表＝現在の写真 / 裏＝次の写真）
   -------------------------------------------------------------------------- */
.photo_anm__card {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transform-origin: 50% 50%;
  will-change: transform;
}

.photo_anm__face {
  position: absolute;
  inset: 0;
  overflow: hidden;
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
  transform-origin: 50% 50%;
}

/* 裏面はあらかじめ 180° 回しておく（回転後に正しい向きで見える） */
.photo_anm__face--back {
  transform: rotate3d(var(--photo-anm-rx), var(--photo-anm-ry), 0, 180deg);
}

/* --------------------------------------------------------------------------
   7. 各面に敷く写真
      ステージ全体と同じサイズの枠（span）を、自分のタイル位置ぶんだけ
      マイナス方向にずらして配置＝写真をタイルで切り出している状態。
      中の <img>（HTML の <img> の複製）は object-fit: cover で枠いっぱいに敷くため、
      アスペクト比は常に維持されます。
   -------------------------------------------------------------------------- */
.photo_anm__img {
  position: absolute;
  left: calc(var(--photo-anm-tile-w) * var(--col) * -1);
  top: calc((var(--photo-anm-offset-y) + var(--photo-anm-tile-h) * var(--row)) * -1);
  display: block;
  width: var(--photo-anm-stage-w);
  height: var(--photo-anm-stage-h);
}

.photo_anm__img img {
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  object-position: center;
  -webkit-user-drag: none;
}

/* --------------------------------------------------------------------------
   8. 陰影（3D回転の立体感）
   -------------------------------------------------------------------------- */
.photo_anm__shade {
  position: absolute;
  inset: 0;
  background-color: #000;
  opacity: 0;
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   9. アニメーション本体
   -------------------------------------------------------------------------- */
@keyframes photo_anm_flip {
  from { transform: rotate3d(var(--photo-anm-rx), var(--photo-anm-ry), 0, 0deg); }
  to   { transform: rotate3d(var(--photo-anm-rx), var(--photo-anm-ry), 0, var(--photo-anm-flip-deg)); }
}

/* 表面：手前 → 奥へ回り込むので、徐々に暗くなる */
@keyframes photo_anm_shade_front {
  0%   { opacity: 0; }
  50%  { opacity: var(--photo-anm-shade); }
  100% { opacity: var(--photo-anm-shade); }
}

/* 裏面：奥 → 手前へ出てくるので、徐々に明るくなる */
@keyframes photo_anm_shade_back {
  0%   { opacity: var(--photo-anm-shade); }
  50%  { opacity: var(--photo-anm-shade); }
  100% { opacity: 0; }
}

.photo_anm__grid.is-flipping .photo_anm__card,
.photo_anm__grid.is-flipping .photo_anm__shade {
  animation-duration: var(--photo-anm-flip-duration);
  animation-timing-function: var(--photo-anm-ease);
  animation-delay: var(--photo-anm-delay);   /* = (row + col) × delayStep */
  animation-iteration-count: 1;
  animation-fill-mode: forwards;             /* めくり終わりで固定＝チラつき防止 */
}

.photo_anm__grid.is-flipping .photo_anm__card {
  animation-name: photo_anm_flip;
}
.photo_anm__grid.is-flipping .photo_anm__face--front > .photo_anm__shade {
  animation-name: photo_anm_shade_front;
}
.photo_anm__grid.is-flipping .photo_anm__face--back > .photo_anm__shade {
  animation-name: photo_anm_shade_back;
}

/* --------------------------------------------------------------------------
   10. 動きを減らす設定の端末へのフォールバック（静かなクロスフェード）
   -------------------------------------------------------------------------- */
.photo_anm__grid.is-fading {
  opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
  .photo_anm__grid.is-flipping .photo_anm__card,
  .photo_anm__grid.is-flipping .photo_anm__shade {
    animation: none !important;
  }
}

/* --------------------------------------------------------------------------
   11. レスポンシブについて
      アスペクト比・perspective など「画面幅で変えたい値」は JS 側の
      PHOTO_ANM_DEFAULTS.mobile で指定します（JS がインラインで流し込むため、
      ここでメディアクエリを書いても上書きされます）。
      画面幅に関係なく写真は object-fit: cover で常にアスペクト比を維持し、
      コンテナいっぱいに表示されます。
   -------------------------------------------------------------------------- */
