/*
   fade-in-out.css

   - img.fade-io: Image fade in/out
   - .fade-text-io: Text block gentle fade in/out
   - .fade-chars-io: Text per-character animation
   - .zoom-in-wrap: Image zoom-in with initial-size clipping window

   Copyleft 🄯 2026 Taiji Yamada <taiji_yamada@mac.com>
 */

/*
   img.fade-io: Image fade in / out
 */

img.fade-io {
  opacity: 0;
  transform: translate3d(0, 12px, 0);

  transition:
    opacity 2500ms ease,
    transform 2500ms ease;

  will-change: opacity, transform;
}

img.fade-io.is-visible {
  opacity: 1;
  transform: translate3d(0, 0, 0);

  transition:
    opacity 5000ms ease,
    transform 5000ms ease;

  will-change: opacity, transform;
}

/*
   .fade-text-io: Text block fade in / out
 */

.fade-text-io {
  opacity: 0;
  transform: translate3d(0, 6px, 0);

  transition:
    opacity 3600ms ease,
    transform 3600ms ease;

  will-change: opacity, transform;
}

.fade-text-io.is-visible {
  opacity: 1;
  transform: translate3d(0, 0, 0);

  transition:
    opacity 4800ms ease,
    transform 4800ms ease;

  will-change: opacity, transform;
}

/*
   .fade-chars-io: Text per-character animation
   - JS will wrap characters in <span class="ch">
   - Show/hide via .is-visible on the container
 */

.fade-chars-io {
  /* layout is preserved; JS will insert spans */
}

/* each character */
.fade-chars-io .ch {
  display: inline-block;
  opacity: 0;
  transform: translate3d(0, 6px, 0);

  transition:
    opacity 900ms ease,
    transform 900ms ease;

  will-change: opacity, transform;
}

/* visible: characters animate in with per-char delay set by JS */
.fade-chars-io.is-visible .ch {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

/* spaces: keep width but no visible glyph */
.fade-chars-io .ch.space {
  width: 0.33em; /* 好みで調整 */
}

/*
   .zoom-in-wrap: Zoom-in images
 */

/* clipping window */
.zoom-in-wrap {
  overflow: hidden;
  display: inline-block; /* 窓サイズ＝中身(img)の初期サイズ */
  line-height: 0;        /* img下の余白防止 */
}

/* image defines window size at scale=1 */
.zoom-in-wrap > img.zoom-in-io {
  display: block;
  width: 100%;
  height: auto;
  transform-origin: center center;

  transform: scale(1);
  transition: transform 8000ms ease;
  will-change: transform;
}

/* zoom-in progresses inside fixed window */
.zoom-in-wrap > img.zoom-in-io.is-visible {
  transform: scale(1.14);
}

/*
   Safari / iOS stabilization
 */

img.fade-io,
img.fade-io.is-visible,
.fade-text-io,
.fade-text-io.is-visible,
.fade-chars-io,
.fade-chars-io.is-visible,
.fade-chars-io .ch,
.zoom-in-wrap > img.zoom-in-io,
.zoom-in-wrap > img.zoom-in-io.is-visible {
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

/*
   prefers-reduced-motion
 */

@media (prefers-reduced-motion: reduce) {
  img.fade-io,
  .fade-text-io,
  .zoom-in-wrap > img.zoom-in-io {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .fade-chars-io .ch {
    opacity: 1;
    transform: none;
    transition: none;
  }
}
