/*
 * animations.css — S.Factory アニメーション定義
 *
 * 設計方針:
 *   - 純CSS @keyframes + IntersectionObserver (main.js) の組み合わせ
 *   - transform / opacity のみ使用 (GPU合成 60fps)
 *   - clip-path / width / height などレイアウト・ラスタ再計算を伴うプロパティは使わない
 *   - prefers-reduced-motion: reduce で全アニメ即時無効
 *   - JS無効でも全コンテンツ閲覧可 (プログレッシブエンハンスメント)
 *     .js クラスが <html> にある場合のみ初期非表示を適用
 *   - will-change: Ken Burns (14s) と parallax 対象のみ静的付与。
 *     ドロワーは .is-rendered 付与時のみ付与 (非表示時のGPUレイヤ常時確保を解消)。
 *
 * トークン参照 (tokens.css で定義):
 *   --ease-out / --ease-soft
 *   --dur-1/2/3            .4s / .6s / .9s
 *   --stagger              .08s (カード/行の段差)
 *   --dur-kenburns         14s  (Ken Burns ズーム)
 *   --hero-delay-base/step/lead/sub/actions/side/detail  ヒーローステージング遅延
 *   --rise-sm/md/lg/rev    移動距離トークン (12/20/28/24px)
 *   --zoom-kenburns/icon-in/company/hover-sm/hover-md ズーム率
 *   --accent-red           装飾アクセント下線色
 *   --accent-red-ink       白地 AA 4.5:1 準拠の赤
 *
 * チェーン機構 (v7):
 *   1. .js ゲート配下のヒーロー各要素はデュアルアニメ (本番 + sf-open-failsafe 系)
 *   2. .js.sf-pre:not(.sf-reveal) で animation-play-state: paused, running
 *      → sf-reveal 付与 (T0) で自動再開。オープニング無し環境は最初から running。
 *   3. フェイルセーフは4系統 (6s後強制表示):
 *      - sf-open-failsafe        : opacity/visibility のみ (side-note/detail/slide — transform/filter 保護)
 *      - sf-open-failsafe-move   : +transform:none (header/lead/sub/actions/proof/floating — translateY 解除)
 *      - sf-open-failsafe-hero-line: +transform:none+filter:none (heading-line — blur 解除)
 *      - sf-open-failsafe-x      : scaleX(1)/visibility (lead::after/detail-rule — scaleX 解除)
 *   4. reduced-motion は §12 の * ルールで全停止。
 *
 * ホバー/トランジションの責務分離:
 *   アニメ・トランジション・ホバー演出は本ファイルに一元化。
 *   style.css にはレイアウト・外観（色・余白・サイズ）のみ記述。
 */

/* ==========================================================================
   ▌ 1. @keyframes 定義
   ========================================================================== */

/* --- ヒーロー: blur-in + スライドアップ ---
 * GPU負荷考慮: blur は見出し4行・ワンショットのみ。
 * will-change はワンショット(.9s)のため付与しない。 */
@keyframes sf-hero-line-in {
  from {
    opacity: 0;
    transform: translateY(var(--rise-lg));
    filter: blur(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
    filter: blur(0px);
  }
}

/* --- 汎用フェードアップ --- */
@keyframes sf-fade-up {
  from {
    opacity: 0;
    transform: translateY(var(--rise-md));
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* --- ヘッダー: フェードダウン (ロード時) --- */
@keyframes sf-fade-down {
  from {
    opacity: 0;
    transform: translateY(calc(var(--rise-md) * -0.5));
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* --- Ken Burns: ヒーロー背景超ゆっくりズーム --- */
@keyframes sf-ken-burns {
  from { transform: scale(1.0); }
  to   { transform: scale(var(--zoom-kenburns)); }
}

/* --- アイコンスケールイン --- */
@keyframes sf-icon-in {
  from {
    opacity: 0;
    transform: scale(var(--zoom-icon-in));
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

/* --- フェードのみ (side-note / detail) --- */
@keyframes sf-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* --- scaleX 0→1 (hero__lead 赤下線 / hero__detail-rule) --- */
@keyframes sf-scale-x-in {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* --- フェイルセーフ: 6s 後に強制全表示 ---
 * JS が何らかの理由でステージングを解除できなかった場合の焼き付き防止。
 * transform:none は Ken Burns(scale) / side-note(translateY+rotate) など
 * load-bearing な transform を持つ要素を破壊するため含めない。
 * filter:none は hero__slide.is-active の恒久的な grayscale(style.css) を
 * 6s 後に剥がしてしまうため含めない。opacity/visibility のみ復帰させる。
 * to に visibility:visible を含めることで opening.css クロークも解除する。 */
@keyframes sf-open-failsafe {
  to {
    opacity: 1;
    visibility: visible;
  }
}

/* scaleX 隠し要素(lead::after / detail-rule)専用フェイルセーフ */
@keyframes sf-open-failsafe-x {
  to {
    transform: scaleX(1);
    visibility: visible;
  }
}

/* translateY を持つ要素(header/lead/sub/actions/proof/floating)専用フェイルセーフ */
@keyframes sf-open-failsafe-move {
  to {
    opacity: 1;
    transform: none;
  }
}

/* translateY+blur を持つ要素(heading-line)専用フェイルセーフ */
@keyframes sf-open-failsafe-hero-line {
  to {
    opacity: 1;
    transform: none;
    filter: none;
  }
}

/* ==========================================================================
   ▌ 2. ヘッダー — ロード時フェードダウン
   ========================================================================== */

.site-header {
  animation: sf-fade-down var(--dur-2) var(--ease-out) both,
             sf-open-failsafe-move 0.01s linear var(--failsafe-delay) forwards;
  transition:
    background-color var(--dur-2) var(--ease-soft),
    border-color     var(--dur-2) var(--ease-soft),
    box-shadow       var(--dur-2) var(--ease-soft);
}

/* オープニング中は sf-fade-down の遅延時計も一時停止 */
.js.sf-pre:not(.sf-reveal) .site-header {
  animation-play-state: paused, running;
}

/* スクロールでヒーローを超えたら JS が付与する */
.site-header.is-scrolled {
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.10);
}

/* ロゴ・ナビ・CTA・ハンバーガー: 透過↔実体で色が滑らかに切替わる */
.site-header__logo,
.site-header__nav-link,
.site-header__cta,
.hamburger__line {
  transition:
    color            var(--dur-2) var(--ease-soft),
    background-color var(--dur-2) var(--ease-soft),
    border-color     var(--dur-2) var(--ease-soft),
    opacity          var(--dur-0) var(--ease-out);
}

/* ==========================================================================
   ▌ 3. ヒーロー — ロード時ステージング (v7 タイムライン)
   ========================================================================== */

/*
 * CLS 対策: .js クラス付与で .hero__heading-line が inline → inline-block に
 * 変わる可能性と、web font swap で高さが変化する可能性に対し、
 * .hero__heading に min-height を設けて周辺コンテンツへのリフローを抑止する。
 */
/* ⚠ 見出しの行数と一致させること。多すぎるとリード文との間に空白が空く */
.hero__heading {
  min-height: 4.15lh;
}

/* ===== hero__logo: 見出しより先 (T0) に出す ===== */
.js .hero__logo {
  opacity: 0;
  animation:
    sf-fade-up var(--dur-2) var(--ease-out) both,
    sf-open-failsafe-move 0.01s linear var(--failsafe-delay) forwards;
  animation-delay: 0s, var(--failsafe-delay);
}
.js.sf-pre:not(.sf-reveal) .hero__logo {
  animation-play-state: paused, running;
}

/* ===== 見出し行: デュアルアニメ + play-state ゲート ===== */
.js .hero__heading-line {
  overflow: hidden;
  opacity: 0;
  animation:
    sf-hero-line-in var(--dur-3) var(--ease-out) both,
    sf-open-failsafe-hero-line 0.01s linear var(--failsafe-delay) forwards;
}

/* オープニング進行中はステージング遅延時計を停止。sf-open-failsafe は running 維持 */
.js.sf-pre:not(.sf-reveal) .hero__heading-line {
  animation-play-state: paused, running;
}

/* T0 + base + (n-1)*step の遅延 (calc を使い nth-child で導出) */
.js .hero__heading-line:nth-child(1) {
  animation-delay: var(--hero-delay-base), var(--failsafe-delay);
}
.js .hero__heading-line:nth-child(2) {
  animation-delay: calc(var(--hero-delay-base) + var(--hero-delay-step) * 1), var(--failsafe-delay);
}
.js .hero__heading-line:nth-child(3) {
  animation-delay: calc(var(--hero-delay-base) + var(--hero-delay-step) * 2), var(--failsafe-delay);
}
.js .hero__heading-line:nth-child(4) {
  animation-delay: calc(var(--hero-delay-base) + var(--hero-delay-step) * 3), var(--failsafe-delay);
}
.js .hero__heading-line:nth-child(5) {
  animation-delay: calc(var(--hero-delay-base) + var(--hero-delay-step) * 4), var(--failsafe-delay);
}

/* ===== hero__lead: T0+0.62s、dur 0.6s ===== */
.js .hero__lead {
  opacity: 0;
  animation:
    sf-fade-up var(--dur-2) var(--ease-out) both,
    sf-open-failsafe-move 0.01s linear var(--failsafe-delay) forwards;
  animation-delay: var(--hero-delay-lead), var(--failsafe-delay);
}
.js.sf-pre:not(.sf-reveal) .hero__lead {
  animation-play-state: paused, running;
}

/* hero__lead の赤下線 (::after): T0+0.82s、dur 0.5s、scaleX 0→1 */
.js .hero__lead::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: var(--accent-red);
  transform-origin: left center;
  transform: scaleX(0);
  animation:
    sf-scale-x-in 0.5s var(--ease-out) both,
    sf-open-failsafe-x 0.01s linear var(--failsafe-delay) forwards;
  animation-delay: calc(var(--hero-delay-lead) + 0.20s), var(--failsafe-delay);
}
.js.sf-pre:not(.sf-reveal) .hero__lead::after {
  animation-play-state: paused, running;
}

/* hero__lead は ::after を持つので position:relative が必要 */
/* 下線は ::after(scaleX 入場アニメ)で実装。position:relative は ::after の基準。 */
.hero__lead {
  position: relative;
}

/* ===== hero__sub: T0+0.78s、dur 0.6s ===== */
.js .hero__sub {
  opacity: 0;
  animation:
    sf-fade-up var(--dur-2) var(--ease-out) both,
    sf-open-failsafe-move 0.01s linear var(--failsafe-delay) forwards;
  animation-delay: var(--hero-delay-sub), var(--failsafe-delay);
}
.js.sf-pre:not(.sf-reveal) .hero__sub {
  animation-play-state: paused, running;
}

/* ===== hero__side-note: T0+1.10s、dur 0.8s、フェードのみ ===== */
.js .hero__side-note {
  opacity: 0;
  animation:
    sf-fade-in 0.8s var(--ease-out) both,
    sf-open-failsafe 0.01s linear var(--failsafe-delay) forwards;
  animation-delay: var(--hero-delay-side), var(--failsafe-delay);
}
.js.sf-pre:not(.sf-reveal) .hero__side-note {
  animation-play-state: paused, running;
}

/* ===== hero__detail: T0+1.20s、dur 0.7s、フェード ===== */
.js .hero__detail {
  opacity: 0;
  animation:
    sf-fade-in 0.7s var(--ease-out) both,
    sf-open-failsafe 0.01s linear var(--failsafe-delay) forwards;
  animation-delay: var(--hero-delay-detail), var(--failsafe-delay);
}
.js.sf-pre:not(.sf-reveal) .hero__detail {
  animation-play-state: paused, running;
}

/* hero__detail-rule: T0+1.35s、scaleX 0→1 (0.5s) */
.js .hero__detail-rule {
  transform-origin: left center;
  transform: scaleX(0);
  animation:
    sf-scale-x-in 0.5s var(--ease-out) both,
    sf-open-failsafe-x 0.01s linear var(--failsafe-delay) forwards;
  animation-delay: calc(var(--hero-delay-detail) + 0.15s), var(--failsafe-delay);
}
.js.sf-pre:not(.sf-reveal) .hero__detail-rule {
  animation-play-state: paused, running;
}

/* ===== Ken Burns: T0 から再生開始 ===== */
.hero__slide.is-active {
  animation:
    sf-ken-burns var(--dur-kenburns) var(--ease-soft) forwards,
    sf-open-failsafe 0.01s linear var(--failsafe-delay) forwards;
  transform-origin: center center;
  will-change: opacity, transform;
}
.js.sf-pre:not(.sf-reveal) .hero__slide.is-active {
  animation-play-state: paused, running;
}

/* ===== ヒーロー3枚クロスフェード (page-home) =====
 * 純CSS・無限ループ。各スライドは「フェードイン 6.67% → 表示 26.7% → フェードアウト 6.67% → 待機」。
 * 周期を3等分した位相を nth-child の delay で与える。1枚目だけフェードイン分を負の delay で
 * 先送りし、t=0 の時点で既に表示され切っている状態にする (でないと初回に一瞬地色が見える)。
 * ⚠ 枚数を変えたらキーフレームの % と下の3つの delay を作り直すこと。
 * ⚠ sf-open-failsafe (opacity:1 forwards) は意図的に付けない — 付けると 6s 後に
 *   全スライドが固定表示になりループが死ぬ。JS非依存なのでフェイルセーフは不要。
 * ⚠ 上の .is-active ルールより後に置くこと (同詳細度・後勝ちで animation を奪う)。 */
/* ⚠ 表示終了 (40%) は「次のスライドがフェードインし終わる時刻」と一致させること。
   先に消し始めると両方が半透明になり、下地の暗色が透けて一瞬暗転する。
   40% = 次スライドの開始位相 33.33% + フェード 6.67%。 */
@keyframes sf-hero-crossfade {
  0%      { opacity: 0; }
  6.67%   { opacity: 1; }
  40%     { opacity: 1; }
  46.67%  { opacity: 0; }
  100%    { opacity: 0; }
}

.page-home .hero__slide {
  animation: sf-hero-crossfade var(--dur-hero-cycle) var(--ease-soft) infinite;
  will-change: opacity;
}

.page-home .hero__slide:nth-child(1) {
  animation-delay: calc(var(--dur-hero-cycle) * -0.0667);
}
.page-home .hero__slide:nth-child(2) {
  animation-delay: calc(var(--dur-hero-cycle) * 0.2666);
}
.page-home .hero__slide:nth-child(3) {
  animation-delay: calc(var(--dur-hero-cycle) * 0.6);
}

/* ==========================================================================
   ▌ 4. スクロールリビール (JS が .is-visible を付与)
   ========================================================================== */

.js-ready .reveal {
  opacity: 0;
  transform: translateY(var(--rise-rev));
  transition:
    opacity       var(--dur-2) var(--ease-out),
    transform     var(--dur-2) var(--ease-out);
  transition-delay: calc(var(--stagger) * var(--sf-stagger-i, 0));
}

.js-ready .reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* ==========================================================================
   ▌ 5. STRENGTH — カードホバー
   ========================================================================== */

.strength__item {
  transition:
    transform    var(--dur-1) var(--ease-out),
    box-shadow   var(--dur-1) var(--ease-out),
    border-color var(--dur-1) var(--ease-out);
}

.strength__item:hover {
  transform: translateY(-4px);
  box-shadow: 0 8px 24px rgba(19, 49, 79, 0.12);
  border-color: var(--navy);
}

.strength__icon {
  transition: transform var(--dur-2) var(--ease-out);
}

.strength__item.is-visible .strength__icon {
  animation: sf-icon-in var(--dur-2) var(--ease-out) both;
}

/* ==========================================================================
   ▌ 6. SERVICE — カードホバー
   ========================================================================== */

/* .card-arrow は index.html に存在する。.service__card-link の '→' を
   <span class="card-arrow">→</span> で包んだ場合の矢印ナッジを担う。 */
.service__card-img {
  transition: transform var(--dur-3) var(--ease-soft);
}

.service__card:hover .service__card-img {
  transform: scale(var(--zoom-hover-md));
}

.service__card-link {
  position: relative;
  border-bottom: none;
  padding-bottom: 0;
  overflow: hidden;
}

.service__card-link::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 1px;
  background: var(--white);
  transform: scaleX(0.3);
  transform-origin: left center;
  transition: transform var(--dur-2) var(--ease-out);
  opacity: 0.75;
}

.service__card:hover .service__card-link::after,
.service__card-link:hover::after {
  transform: scaleX(1);
  opacity: 1;
}

/* ==========================================================================
   ▌ 7. WORKS — サムネホバー
   ========================================================================== */

.works__thumb {
  transition:
    transform var(--dur-2) var(--ease-soft),
    opacity   var(--dur-1) var(--ease-out);
}

.works-filter__button::after {
  transition: transform var(--dur-1) var(--ease-out);
}

.works__item:hover .works__thumb {
  transform: scale(var(--zoom-hover-sm));
  opacity: 1;
}

/* overflow:hidden の責務は style.css の .works__media に移管済み */

.works__caption {
  transition: color var(--dur-1) var(--ease-out);
}

.works__item:hover .works__caption {
  color: var(--accent-red-ink);
}

/* ==========================================================================
   ▌ 7b. WORKS — 「すべて見る」リンク ホバー
   ========================================================================== */

.works__more-link {
  transition:
    color     var(--dur-1) var(--ease-out),
    transform var(--dur-1) var(--ease-out);
}

/* v7.4 プレーンテキスト化: 背景・ボーダー変化なし。色変化＋微上昇のみ */
.works__more-link:hover,
.works__more-link:focus-visible {
  color: var(--accent-red-ink);
  transform: translateY(-2px);
}

/* ==========================================================================
   ▌ 8. COMPANY — 左パネル微パララックス/微ズーム
   ========================================================================== */

.company__left-bg {
  transform: translateY(var(--sf-parallax-y, 0px)) scale(var(--zoom-company));
  will-change: transform;
}

/* ==========================================================================
   ▌ 9. CONTACT — 金ボタンホバー強調
   ========================================================================== */

.btn--gold:hover,
.btn--gold:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(168, 128, 60, 0.35);
}

/* ==========================================================================
   ▌ 10. 共通マイクロインタラクション
   ========================================================================== */

.btn {
  transition:
    background   var(--dur-1) var(--ease-out),
    border-color var(--dur-1) var(--ease-out),
    color        var(--dur-1) var(--ease-out),
    transform    var(--dur-1) var(--ease-out),
    box-shadow   var(--dur-1) var(--ease-out);
}

.js-ready .site-footer {
  opacity: 0;
  transform: translateY(var(--rise-sm));
  transition:
    opacity   var(--dur-2) var(--ease-out),
    transform var(--dur-2) var(--ease-out);
}

.js-ready .site-footer.is-visible {
  opacity: 1;
  transform: none;
}

/* ==========================================================================
   ▌ 11. マイクロトランジション — style.css から移管
   ========================================================================== */

.site-footer__nav-link {
  transition: opacity var(--dur-0) var(--ease-out);
}

/* ==========================================================================
   ▌ 12. prefers-reduced-motion — 全アニメ無効・即時表示
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {

  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration:        0.01ms !important;
    animation-iteration-count: 1      !important;
    transition-duration:       0.01ms !important;
    animation-delay:           0ms    !important;
    transition-delay:          0ms    !important;
  }

  /* 見出し行・サブコピー・lead・side-note・detail 即時表示 */
  .js .hero__logo,
  .js .hero__heading-line,
  .js .hero__sub,
  .js .hero__lead,
  .js .hero__side-note,
  .js .hero__detail {
    opacity: 1;
    filter: none;
    animation: none;
  }

  /* hero__lead 下線・detail-rule 即時表示 */
  .js .hero__lead::after {
    animation: none;
    transform: scaleX(1);
  }
  .js .hero__detail-rule {
    animation: none;
    transform: scaleX(1);
  }

  /* reveal 即時表示 */
  .js-ready .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }

  /* 3D入場 即時表示 (詳細度が §4b より高いため確実に上書き) */
  .js-ready .service__grid .service__card.reveal,
  .js-ready .works__grid   .works__item.reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }

  /* フッター即時表示 */
  .js-ready .site-footer {
    opacity: 1;
    transform: none;
    transition: none;
  }

  /* Ken Burns・クロスフェード停止: 先頭スライドのみ静止表示 */
  .hero__slide.is-active {
    opacity: 1;
    animation: none;
  }

  .page-home .hero__slide + .hero__slide {
    opacity: 0;
    animation: none;
  }

}

/* ==========================================================================
   ▌ 13. FORM — フォーカス・ホバー演出 (contact.html)
   ========================================================================== */

.form__control {
  transition:
    border-color var(--dur-1) var(--ease-out),
    box-shadow   var(--dur-1) var(--ease-out);
}

.form__control:focus-visible {
  border-color: var(--navy);
  box-shadow: 0 0 0 3px rgba(19, 49, 79, 0.12);
  outline: none;
}

.form__submit-row .btn--primary {
  transition:
    background   var(--dur-1) var(--ease-out),
    border-color var(--dur-1) var(--ease-out),
    transform    var(--dur-1) var(--ease-out),
    box-shadow   var(--dur-1) var(--ease-out);
}

.form__submit-row .btn--primary:hover,
.form__submit-row .btn--primary:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(19, 49, 79, 0.18);
}

/* ==========================================================================
   ▌ 14. 採用アニメ — 02 / 04 / 05 / 09
   ========================================================================== */

/* ---- 02 SECTION LABEL: 英字ラベルのフェード＋赤下線ドローイン ---- */
.section-label { position: relative; }

.js-ready .section-label {
  opacity: 0;
  transform: translateY(8px);
  transition:
    opacity   var(--dur-2) var(--ease-out),
    transform var(--dur-2) var(--ease-out);
}

.js-ready .section-label.is-visible {
  opacity: 1;
  transform: none;
}

.section-label::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -8px;
  width: 48px;
  height: 2px;
  background: var(--accent-red);
  transform: translateX(-50%) scaleX(0);
  transform-origin: center;
  transition: transform var(--dur-3) var(--ease-out) 0.1s;
}

.section-label.is-visible::after {
  transform: translateX(-50%) scaleX(1);
}

/* ---- 04 DIRECTIONAL: 方向＋段差リビール ---- */
.js-ready .strength__grid .strength__item.reveal:nth-child(2n) {
  transform: translateY(var(--rise-rev)) scale(0.97);
}
.js-ready .strength__grid .strength__item.reveal.is-visible {
  transform: none;
}

/* ---- 04b 3D入場: service__card / works__item (translateX 方向リビールを置換) ---- */
/* perspective は親グリッド側で設定 (style.css .service__grid / .works__grid) */
.js-ready .service__grid .service__card.reveal,
.js-ready .works__grid   .works__item.reveal {
  transform: translateY(24px) rotateX(var(--card-tilt));
  transition: opacity var(--dur-2) var(--ease-out), transform 0.7s var(--ease-land);
  transition-delay: calc(var(--stagger) * var(--sf-stagger-i, 0));
}
/* .is-visible は §4 の共通ルール(.js-ready .reveal.is-visible { transform: none }) が担う */
.js-ready .service__grid  .service__card.reveal.is-visible,
.js-ready .works__grid    .works__item.reveal.is-visible {
  transform: none;
}

/* モバイル: rotateX なしでシンプルな translateY のみ */
@media (max-width: 900px) {
  .js-ready .service__grid .service__card.reveal,
  .js-ready .works__grid   .works__item.reveal {
    transform: translateY(24px);
  }
}

/* ---- 05 HOVER: 矢印ナッジ ＆ 金ボタンの光沢スイープ ---- */
.card-arrow {
  display: inline-block;
  transition: transform var(--dur-1) var(--ease-out);
}

.service__card:hover .card-arrow,
.service__card-link:focus-visible .card-arrow,
.works__more-link:hover .card-arrow,
.works__more-link:focus-visible .card-arrow,
.btn--outline-navy:hover .card-arrow,
.btn--outline-navy:focus-visible .card-arrow,
.work-detail__nav-next:hover .card-arrow,
.work-detail__nav-next:focus-visible .card-arrow {
  transform: translateX(5px);
}
/* prev 矢印は style.css で rotate(180deg) 済みのため translateX 競合を避け、ナッジなし(コメントで意図明記) */

.btn--gold {
  position: relative;
  overflow: hidden;
}

.btn--gold::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 45%;
  background: linear-gradient(105deg, transparent, rgba(255, 255, 255, 0.45), transparent);
  transform: translateX(-160%) skewX(-16deg);
  transition: transform var(--dur-2) var(--ease-out);
  pointer-events: none;
}

.btn--gold:hover::before,
.btn--gold:focus-visible::before {
  transform: translateX(360%) skewX(-16deg);
}

/* ---- 09 DRAWER: モバイルメニューのスライド＋リンク段差 ---- */
/* will-change は .is-rendered 付与時のみ (非表示時のGPUレイヤ常時確保を解消) */
.site-header__drawer.is-rendered {
  display: flex;
  opacity: 0;
  transform: translateY(-10px);
  transition:
    opacity   var(--dur-1) var(--ease-out),
    transform var(--dur-2) var(--ease-out);
  will-change: transform, opacity;
}

.site-header__drawer.is-rendered.is-open {
  opacity: 1;
  transform: none;
}

.site-header__drawer.is-rendered .site-header__drawer-link {
  opacity: 0;
  transform: translateX(16px);
  transition:
    opacity   var(--dur-1) var(--ease-out),
    transform var(--dur-2) var(--ease-out);
}

.site-header__drawer.is-rendered.is-open .site-header__drawer-link {
  opacity: 1;
  transform: none;
}

.site-header__drawer.is-rendered.is-open .site-header__drawer-link:nth-child(1) { transition-delay: 0.10s; }
.site-header__drawer.is-rendered.is-open .site-header__drawer-link:nth-child(2) { transition-delay: 0.17s; }

/* ==========================================================================
   ▌ §work-detail. 実績詳細ページ入場アニメ (Figma Motion「Work Detail」準拠)
   デュアルアニメ パターン:
     animation: sf-X dur ease delay both, sf-open-failsafe 0.01s linear var(--failsafe-delay) forwards;
   play-state ゲート:
     .js.sf-pre:not(.sf-reveal) .el { animation-play-state: paused, running; }
   ========================================================================== */

/* ---------- パンくず ---------- */
.js .breadcrumb {
  animation:
    sf-fade-in 0.4s var(--ease-out) 0.05s both,
    sf-open-failsafe 0.01s linear var(--failsafe-delay) forwards;
}
.js.sf-pre:not(.sf-reveal) .breadcrumb {
  animation-play-state: paused, running;
}

/* ---------- section-label (詳細ページ内) ---------- */
/* 注意: index/works の .section-label は §14 の transition-based reveal が担う。
         work-detail 内の .section-label は keyframe アニメで制御するため分離。 */
.js .work-detail .section-label {
  animation:
    sf-fade-in 0.4s var(--ease-out) 0.08s both,
    sf-open-failsafe 0.01s linear var(--failsafe-delay) forwards;
}
.js.sf-pre:not(.sf-reveal) .work-detail .section-label {
  animation-play-state: paused, running;
}

/* ---------- タイトル ---------- */
.js .work-detail__title {
  animation:
    sf-fade-up 0.6s var(--ease-out) 0.12s both,
    sf-open-failsafe-move 0.01s linear var(--failsafe-delay) forwards;
}
.js.sf-pre:not(.sf-reveal) .work-detail__title {
  animation-play-state: paused, running;
}

/* ---------- 赤ライン (scaleX 0→1) ---------- */
.js .work-detail__rule {
  transform-origin: left center;
  animation:
    sf-scale-x-in 0.4s var(--ease-out) 0.26s both,
    sf-open-failsafe-x 0.01s linear var(--failsafe-delay) forwards;
}
.js.sf-pre:not(.sf-reveal) .work-detail__rule {
  animation-play-state: paused, running;
}

/* ---------- ギャラリーメイン ---------- */
.js .work-detail .gallery__main {
  animation:
    sf-fade-in 0.6s var(--ease-out) 0.18s both,
    sf-open-failsafe 0.01s linear var(--failsafe-delay) forwards;
}
.js.sf-pre:not(.sf-reveal) .work-detail .gallery__main {
  animation-play-state: paused, running;
}

/* ---------- スペック dl ---------- */
.js .work-detail__spec {
  animation:
    sf-fade-up 0.5s var(--ease-out) 0.30s both,
    sf-open-failsafe-move 0.01s linear var(--failsafe-delay) forwards;
}
.js.sf-pre:not(.sf-reveal) .work-detail__spec {
  animation-play-state: paused, running;
}

/* ---------- スペック行 (stagger 4行) ---------- */
.js .work-detail__row {
  animation:
    sf-fade-up 0.4s var(--ease-out) both,
    sf-open-failsafe-move 0.01s linear var(--failsafe-delay) forwards;
}
.js.sf-pre:not(.sf-reveal) .work-detail__row {
  animation-play-state: paused, running;
}
.work-detail__row:nth-child(1) { animation-delay: calc(0.30s + var(--stagger) * 0), var(--failsafe-delay); }
.work-detail__row:nth-child(2) { animation-delay: calc(0.30s + var(--stagger) * 1), var(--failsafe-delay); }
.work-detail__row:nth-child(3) { animation-delay: calc(0.30s + var(--stagger) * 2), var(--failsafe-delay); }
.work-detail__row:nth-child(4) { animation-delay: calc(0.30s + var(--stagger) * 3), var(--failsafe-delay); }

/* ---------- 説明文 ---------- */
/* デスクトップ(≥901px): desc は grid-area:desc で left カラム下段に独立配置。
   spec と並走するため 0.38s で適切。
   モバイル(≤900px): DOM 順 = 視覚順のため spec 4行目(0.30+0.08×3=0.54s)の後に来る必要がある。
   @media 上書きで spec 完了後 + 0.08s 間隔の 0.62s に引き延ばす。 */
.js .work-detail__desc {
  animation:
    sf-fade-up 0.5s var(--ease-out) 0.38s both,
    sf-open-failsafe-move 0.01s linear var(--failsafe-delay) forwards;
}
.js.sf-pre:not(.sf-reveal) .work-detail__desc {
  animation-play-state: paused, running;
}

/* モバイル: desc ディレイを spec 最終行(0.54s)の後 0.08s 間隔の 0.62s へ上書き */
@media (max-width: 900px) {
  .js .work-detail__desc {
    animation-delay: 0.62s, var(--failsafe-delay);
  }
}

/* ---------- 前後ナビ ---------- */
/* spec F: main.js の revealObserver に委ねる。work-1〜6.html の <nav class="work-detail__nav reveal"> で IO 発火 */
/* 固定遅延キーフレームは廃止。reduced-motion は既存 .js-ready .reveal ルール(animations.css §12a)がカバー */

/* ---------- ギャラリー画像差替トランジション ---------- */
/* work-detail.js が .is-switching を付与してフェードさせる (style.css に transition 定義) */

/* ==========================================================================
   ▌ §work-detail 12b. prefers-reduced-motion — work-detail / breadcrumb
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .breadcrumb,
  .work-detail .section-label,
  .work-detail__title,
  .work-detail__rule,
  .work-detail .gallery__main,
  .work-detail__spec,
  .work-detail__row,
  .work-detail__desc {
    animation: none !important;
    transition: none !important;
    opacity: 1 !important;
    transform: none !important;
  }

  .gallery__main img {
    transition: none !important;
  }

}
