/* ==========================================================================
   Motion
   ALIGN独自のモーションシステム（ブラッシュアップ分）

   方針：
   - 「整って現れる」「順序を持って現れる」「身体の動きを感じる」を基本コンセプトとし、
     Harmony Piano Schoolのような柔らかなfade-up中心の演出とは異なる、
     シャープで認識できる動きを採用する。
   - 既存の reveal.js / intro.js の仕組み（IntersectionObserver・
     prefers-reduced-motion判定・Progressive Enhancement）はそのまま利用し、
     二重にopacity/transformを制御しないよう、対象要素ごとに責務を分離する。
   - hoverによる動きは、fine pointer + hover可能端末でのみ有効にする。
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. Hero Text Reveal
   ローディング（ブランドイントロ）終了後に、Heroの見出しが行単位で
   下から上へシャープに現れる。JavaScript側（hero-reveal.js）が
   .js-hero-armed / .is-hero-visible を付与するまで、CSSは通常表示のまま
   （＝JavaScript無効時・reduced-motion時は最初から全文表示される）。
   -------------------------------------------------------------------------- */

.p-hero__title .c-hero-line {
  display: block;
  overflow: hidden;
}

.p-hero__title .c-hero-line__inner {
  display: block;
}

@media (prefers-reduced-motion: no-preference) {
  .js-hero-armed .c-hero-line__inner {
    transform: translateY(105%);
    opacity: 0;
    transition: transform 620ms var(--ease-intro), opacity 320ms var(--ease-standard);
  }

  .js-hero-armed .c-hero-line:nth-child(2) .c-hero-line__inner {
    transition-delay: 90ms;
  }

  .js-hero-armed.is-hero-visible .c-hero-line__inner {
    transform: translateY(0);
    opacity: 1;
  }

  .js-hero-armed .p-hero__subtitle,
  .js-hero-armed .p-hero__actions,
  .js-hero-armed .p-hero__badges {
    opacity: 0;
    transform: translateY(10px);
    transition: opacity 420ms var(--ease-standard), transform 420ms var(--ease-standard);
  }

  .js-hero-armed .p-hero__subtitle {
    transition-delay: 260ms;
  }

  .js-hero-armed .p-hero__actions {
    transition-delay: 340ms;
  }

  .js-hero-armed .p-hero__badges {
    transition-delay: 420ms;
  }

  .js-hero-armed.is-hero-visible .p-hero__subtitle,
  .js-hero-armed.is-hero-visible .p-hero__actions,
  .js-hero-armed.is-hero-visible .p-hero__badges {
    opacity: 1;
    transform: translateY(0);
  }
}

/* --------------------------------------------------------------------------
   1. Section Heading Motion
   「— 02 / FEATURES」等のセクションラベルについて、
   1) 左のlineが左→右へ伸びる → 2) ラベルが現れる → 3) 見出しが続いて現れる
   というシーケンスを、既存の .js-reveal-target / IntersectionObserver
   （reveal.js）が付与する .js-reveal / .is-visible を起点に、CSSの
   transition-delayだけで表現する（新しい監視処理は追加しない）。

   対象要素には、既存構造に .js-heading-target を追加している。
   親要素（.js-reveal-target本体）の汎用フェードは、この対象では
   opacity:1 / transform:none にリセットし、子要素側でのみ制御することで
   同一要素への二重のtransform/opacity適用を避けている。
   -------------------------------------------------------------------------- */

.c-section-label__text {
  display: inline-block;
}

@media (prefers-reduced-motion: no-preference) {
  .js-reveal.js-heading-target {
    opacity: 1;
    transform: none;
  }

  .js-heading-target.js-reveal .c-section-label::before {
    transform-origin: left;
    transform: scaleX(0);
    transition: transform 460ms var(--ease-intro);
  }

  .js-heading-target.js-reveal .c-section-label__text {
    opacity: 0;
    transform: translateX(-6px);
    transition: opacity 320ms var(--ease-standard) 220ms,
      transform 320ms var(--ease-standard) 220ms;
  }

  .js-heading-target.js-reveal > h2 {
    opacity: 0;
    transform: translateY(10px);
    transition: opacity 420ms var(--ease-standard) 380ms,
      transform 420ms var(--ease-standard) 380ms;
  }

  .js-heading-target.js-reveal > :not(.c-section-label):not(h2) {
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 420ms var(--ease-standard) 520ms,
      transform 420ms var(--ease-standard) 520ms;
  }

  .js-heading-target.js-reveal.is-visible .c-section-label::before {
    transform: scaleX(1);
  }

  .js-heading-target.js-reveal.is-visible .c-section-label__text,
  .js-heading-target.js-reveal.is-visible > h2,
  .js-heading-target.js-reveal.is-visible > :not(.c-section-label):not(h2) {
    opacity: 1;
    transform: none;
  }
}

/* --------------------------------------------------------------------------
   2. Existing scroll reveal - 順序を持って現れる補強
   l-grid--3（Features / Training / Voice / Plan）は、カードごとに個別の
   .js-reveal-target として既存監視されている。ここでは新たなopacity/transform
   制御を追加せず、transition-delayのみを付与し、01→02→03の短いstaggerを
   一貫して持たせる。
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  .l-grid--3 > .js-reveal:nth-child(1) {
    transition-delay: 0ms;
  }

  .l-grid--3 > .js-reveal:nth-child(2) {
    transition-delay: 90ms;
  }

  .l-grid--3 > .js-reveal:nth-child(3) {
    transition-delay: 180ms;
  }
}

/* --------------------------------------------------------------------------
   3. Flow - 手順そのものをmotionで表現する
   .c-flow-list全体を1つのIntersectionObserver対象としたまま、
   子要素（各手順）にのみ短いstaggerを持たせる。hoverは追加しない。
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  .js-reveal.js-flow-target {
    opacity: 1;
    transform: none;
  }

  .js-flow-target.js-reveal .c-flow-list__item {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 420ms var(--ease-standard), transform 420ms var(--ease-standard);
  }

  .js-flow-target.js-reveal .c-flow-list__item:nth-child(1) {
    transition-delay: 0ms;
  }

  .js-flow-target.js-reveal .c-flow-list__item:nth-child(2) {
    transition-delay: 90ms;
  }

  .js-flow-target.js-reveal .c-flow-list__item:nth-child(3) {
    transition-delay: 180ms;
  }

  .js-flow-target.js-reveal .c-flow-list__item:nth-child(4) {
    transition-delay: 270ms;
  }

  .js-flow-target.js-reveal .c-flow-list__item:nth-child(5) {
    transition-delay: 360ms;
  }

  .js-flow-target.js-reveal.is-visible .c-flow-list__item {
    opacity: 1;
    transform: none;
  }
}

/* --------------------------------------------------------------------------
   4. Features - hover interaction（fine pointerのみ）
   -------------------------------------------------------------------------- */

@media (hover: hover) and (pointer: fine) {
  .c-card {
    transition: box-shadow var(--duration-base) var(--ease-standard),
      border-color var(--duration-base) var(--ease-standard);
  }

  .c-card:hover {
    box-shadow: 0 20px 44px -28px rgba(31, 41, 43, 0.32);
    border-color: var(--color-border);
  }
}

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .c-card {
    transition: transform var(--duration-base) var(--ease-standard),
      box-shadow var(--duration-base) var(--ease-standard),
      border-color var(--duration-base) var(--ease-standard);
  }

  .c-card:hover {
    transform: translateY(-6px);
  }
}

/* --------------------------------------------------------------------------
   5. Training - 写真を主役にしたhover interaction（fine pointerのみ）
   カード自体は動かさず、.c-media内の画像のみをわずかに拡大する。
   .c-mediaは既存でoverflow:hiddenのため、拡大した画像は枠内に収まる。
   -------------------------------------------------------------------------- */

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .c-training-card .c-media img {
    transition: transform 560ms var(--ease-standard);
  }

  .c-training-card:hover .c-media img {
    transform: scale(1.03);
  }
}

/* --------------------------------------------------------------------------
   6. Voice - Featuresより弱いhover interaction（fine pointerのみ）
   -------------------------------------------------------------------------- */

@media (hover: hover) and (pointer: fine) {
  .c-voice-card {
    transition: box-shadow var(--duration-base) var(--ease-standard);
  }

  .c-voice-card:hover {
    box-shadow: 0 14px 32px -26px rgba(31, 41, 43, 0.24);
  }
}

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .c-voice-card {
    transition: transform var(--duration-base) var(--ease-standard),
      box-shadow var(--duration-base) var(--ease-standard);
  }

  .c-voice-card:hover {
    transform: translateY(-4px);
  }
}

/* --------------------------------------------------------------------------
   7. Plan - 中央カードの強調をmotionでも引き継ぐ（fine pointerのみ）
   -------------------------------------------------------------------------- */

@media (hover: hover) and (pointer: fine) {
  .c-plan-card {
    transition: box-shadow var(--duration-base) var(--ease-standard);
  }

  .c-plan-card:hover {
    box-shadow: 0 14px 30px -26px rgba(31, 41, 43, 0.22);
  }

  .c-plan-card--featured:hover {
    box-shadow: 0 22px 46px -24px rgba(0, 0, 0, 0.45);
  }
}

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .c-plan-card {
    transition: transform var(--duration-base) var(--ease-standard),
      box-shadow var(--duration-base) var(--ease-standard);
  }

  .c-plan-card:hover {
    transform: translateY(-4px);
  }

  .c-plan-card--featured:hover {
    transform: translateY(-6px);
  }
}

/* --------------------------------------------------------------------------
   8. Navigation - hover underline（中央から左右へ伸びる）
   既存の .c-nav-link::after（scaleXでの下線アニメーション）はそのまま利用し、
   起点のみ左端から中央へ変更する。hover / focus-visible のトリガーは
   既存実装（components.css）のまま変更しない。
   -------------------------------------------------------------------------- */

.c-nav-link::after {
  transform-origin: center;
}

/* --------------------------------------------------------------------------
   9. CTA Shine - 主要CTA「初回体験を予約する」専用hover（fine pointerのみ）
   .c-button--primary はサイト内で常にこのCTAを指すため、対象を限定できる。
   常時ループさせず、hover開始時に一度だけ通過させる
   （hover解除時はtransitionなしで即座に開始位置へ戻すため、
   再度hoverした際に毎回同じ一度きりの動きを再現できる）。
   -------------------------------------------------------------------------- */

.c-button--primary {
  position: relative;
  overflow: hidden;
}

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .c-button--primary::after {
    content: "";
    position: absolute;
    inset-block: -25%;
    /* 水平方向の基準位置をleft:0に固定する（未指定だとブラウザ推定のstatic
       positionに委ねられ、退避量の計算基準が不定になるため）。 */
    inset-inline-start: 0;
    /* 帯幅を細くし、広告的な面ではなく細い光の筋に近づける。 */
    inline-size: 16%;
    background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.22), transparent);
    /* 斜め移動（Y軸方向の変位）をなくし、左→右の水平方向のみのスイープにする。
       rotate(4deg)のごく軽い傾きだけを残し、光の筋としての質感を保つ。
       自身の幅の100%分（-100%）で自分自身の footprint を完全に押し出したうえで、
       ボタン幅に依存せず確実に外側へ退避できるよう固定バッファ(px)を加算する。 */
    transform: translate3d(calc(-100% - 50px), 0, 0) rotate(4deg);
    pointer-events: none;
    transition: transform 0s linear;
  }

  .c-button--primary:hover::after,
  .c-button--primary:focus-visible::after {
    transition: transform 720ms var(--ease-standard);
    transform: translate3d(calc(650% + 50px), 0, 0) rotate(4deg);
  }

  /* .c-buttonの.transition（components.css）と詳細度が同じ（クラス1つ）だと
     読み込み順次第で意図せず負けうるため、.c-button.c-button--primaryの
     2クラス指定にして詳細度を確実に上げる（この要素は常に両方のclassを持つ）。 */
  .c-button.c-button--primary {
    transition: transform var(--duration-base) var(--ease-standard),
      box-shadow var(--duration-base) var(--ease-standard),
      background-color var(--duration-fast) var(--ease-standard);
  }

  .c-button--primary:hover,
  .c-button--primary:focus-visible {
    transform: translateY(-2px);
    box-shadow: 0 16px 32px -18px rgba(61, 88, 82, 0.5);
  }
}

/* --------------------------------------------------------------------------
   10. Parallax - TRAINING / TRAINER画像のごく控えめな視差（parallax.js）
   .c-media（既存でoverflow:hidden＋position:relative）の内側に、
   専用の内側wrapper（.c-parallax__inner）を新設し、そこにのみ
   scroll駆動のtranslate3dを適用する。
   - .c-media自体（TRAINERではReveal対象）やカード本体（TRAININGではReveal対象）、
     img自体（TRAININGではhover scale対象）とは別要素のため、
     既存のtransform制御と衝突しない。
   - JS（parallax.js）が要素ごとに --parallax-overscan をpxで設定した場合のみ
     オーバースキャン（コンテナよりわずかに大きい寸法）が有効になる。
     reduced-motion / coarse pointer / JS無効等でJSが動かない場合は
     var(--parallax-overscan, 0px)が0pxとなり、通常のcoverと同じ見た目になる
     （余白露出やレイアウト崩れが起きない）。
   -------------------------------------------------------------------------- */

.c-parallax__inner {
  position: absolute;
  inset-inline: 0;
  inset-block: calc(var(--parallax-overscan, 0px) * -1);
  block-size: calc(100% + var(--parallax-overscan, 0px) * 2);
}

.c-parallax__inner img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
