/* MARTA LP FX — 素のHTMLに貼るだけで効く演出。依存ライブラリ0・ビルド0。
 *
 * なぜ自前か（2026-07-14）:
 *   Originkit / React Bits / Aceternity / Magic UI は全部 React + framer-motion 前提で、
 *   アニメの実体が JS ライブラリなので **CSSだけ抜き出す移植も原理的にできない**。
 *   うちの本番LPは .html 137本・package.json 0本。橋を架けるより持つ方が速い。
 *
 * 規約（守らないと lp_lint.py が BLOCK する）:
 *   1. クラス名は必ず .fx-* （既存LPのCSSと衝突させない）
 *   2. prefers-reduced-motion で必ず止める（酔い・アクセシビリティ）
 *   3. モバイル(<=768px)では重い演出を切る（バッテリーと発熱。実際に発熱で痛い目を見ている）
 */

/* ── 1. 光るボーダー ─────────────────────────────
 * 使い方: <div class="fx-glow">…</div>
 * conic-gradient を回すだけ。JS 0行。
 */
@property --fx-angle {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}

/* ⚠️ isolation:isolate を付けてはいけない。
 *    付けると .fx-glow が重なり順の島になり、z-index:-1 の ::before が
 *    「自分の背景より前」に出て **面ごと光る**（＝ボーダーにならない。実装直後に踏んだ）。
 *    position:relative だけにして、::before を自分の背景の裏に沈める。
 *    そのため .fx-glow には必ず不透明な背景が要る（--fx-bg）。 */
.fx-glow {
  position: relative;
  background: var(--fx-bg, #111116);
}

.fx-glow::before {
  content: '';
  position: absolute;
  inset: -2px;
  z-index: -1;
  border-radius: inherit;
  background: conic-gradient(
    from var(--fx-angle),
    transparent 0turn,
    var(--fx-accent, #e8491d) 0.12turn,
    transparent 0.25turn,
    transparent 0.5turn,
    var(--fx-accent, #e8491d) 0.62turn,
    transparent 0.75turn
  );
  animation: fx-spin 4s linear infinite;
}

@keyframes fx-spin {
  to { --fx-angle: 1turn; }
}

/* ── 2. スクロールで浮かび上がる（IntersectionObserver とセット）──
 * 使い方: <section class="fx-rise">…</section> + fx.js
 */
.fx-rise {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity .7s cubic-bezier(.16, 1, .3, 1),
              transform .7s cubic-bezier(.16, 1, .3, 1);
}

.fx-rise.fx-in {
  opacity: 1;
  transform: none;
}

/* ── 3. パーティクル背景 / 流体カーソルの受け皿 ──
 * ⚠️ .fx-particles は「入れ物」に付くクラス。canvas は fx.js が中に差し込む。
 *    入れ物の側を absolute にしてはいけない（レイアウトが崩れて縦に伸びる。実装直後に踏んだ）。
 */
.fx-particles {
  position: relative;
  overflow: hidden;
}

.fx-particles > canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 0;
}

/* 粒より前に文字を出す（背景に沈ませない） */
.fx-particles > *:not(canvas) {
  position: relative;
  z-index: 1;
}

.fx-cursor-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 9999;
}

/* ── 🔴 止めるスイッチ（ここが規約の本体）────────── */

/* 動きが苦手な人・酔う人には一切動かさない */
@media (prefers-reduced-motion: reduce) {
  .fx-glow::before { animation: none; }
  .fx-rise { opacity: 1; transform: none; transition: none; }
  .fx-particles > canvas, .fx-cursor-canvas { display: none; }
}

/* モバイルでは重い演出を切る。バッテリーと発熱。カーソルもそもそも無い */
@media (max-width: 768px) {
  .fx-particles > canvas, .fx-cursor-canvas { display: none; }
  .fx-glow::before { animation-duration: 8s; }
}

/* ── 5. パララックス（スクロールで奥行きを出す）── 2026-07-27 追加
 *
 * 2通りの使い方がある。どちらも「.fx-par の中の [data-fx-par] が動く」だけ。
 *
 * (A) 全面2レイヤー（写真の前景/背景を分ける。文字が被写体の後ろに回る）
 *   <section class="fx-par">
 *     <div class="fx-par-layer" data-fx-par="0.30" aria-hidden="true"><img ...></div>
 *     <div class="fx-par-copy">見出し・CTA</div>
 *     <div class="fx-par-layer fx-par-front" data-fx-par="-0.12" aria-hidden="true"><img ...></div>
 *   </section>
 *
 * (B) 要素ごとの奥行き（既存ヒーローの部品を別々の速さで動かす）
 *   <section class="hero fx-par">
 *     <p class="hero-wordmark" data-fx-par="0.22">…</p>   ← 奥。大きく動く
 *     <div class="laptop"      data-fx-par="0.08">…</div>
 *     <img class="hero-mascots" data-fx-par="-0.14">      ← 手前。逆に動く
 *   </section>
 *
 * 🔴 規約1（事故の再発防止）:
 *   初期状態は「スクロール量0のときの完成構図」でなければならない。
 *   ずらした状態や opacity:0 を初期値にしない。reduced-motion では差分を0に戻すだけなので、
 *   初期値が完成形でないと構図が壊れたまま固まる。
 *   （2026-07-20 marta.monster のマスコットが fill-mode:both で画面外に固まった事故の一般形）
 *
 * 🔴 規約2（2026-07-27 marta-academy.com/biz に当てて判明）:
 *   ずらすのは transform ではなく **translate プロパティ**（独立した変形プロパティ）。
 *   transform を直接書くと、対象が既に持っている transform を消してしまう。
 *   実例: .hero-wordmark は transform: rotate(-3deg) を持っており、
 *         transform で translate3d を当てた瞬間に**傾きが消える**。
 *   `.float` / `.bob` のような transform アニメとも喧嘩しない。
 *
 * 🔴 規約3: レイアウトを起こすプロパティ（top / background-position /
 *   background-attachment: fixed）は使わない。毎フレーム再レイアウトになる。
 */
.fx-par {
  position: relative;
  --fx-par-travel: 120px;        /* 動く最大量。レイヤーはこの分だけ大きく作る */
}

/* 動かす本体。transform を握らないので既存の transform / アニメと共存する */
.fx-par [data-fx-par] { translate: 0 var(--fx-par-y, 0px); }

/* (A) 全面レイヤー用のヘルパー。(B) では使わない */
.fx-par-layer {
  position: absolute;
  left: 0;
  width: 100%;
  /* 🔴 上下に travel 分の「のりしろ」。無いと動いた瞬間に上下へ地の色の帯が出る。
     overflow:hidden だけでは防げない（パララックスで最も多い事故） */
  top: calc(-1 * var(--fx-par-travel));
  height: calc(100% + var(--fx-par-travel) * 2);
  z-index: 0;
  pointer-events: none;          /* CTA のクリックを食わない */
}
.fx-par-layer > img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}

.fx-par-copy  { position: relative; z-index: 1; }  /* 文字は背景の前・前景の裏 */
.fx-par-front { z-index: 2; }                      /* 文字が被写体の後ろに回り込む */
/* 前景は「地面に立っている」ので下端合わせ。cover で引き伸ばさない */
.fx-par-front > img { object-fit: contain; object-position: bottom center; }

/* 🔴 止めるスイッチ ─ 差分を0にするだけ。要素が元から持っている transform /
   位置は一切触らないので、構図が壊れない */
@media (prefers-reduced-motion: reduce) {
  .fx-par [data-fx-par] { translate: none !important; }
}

/* モバイルは切らずに振れ幅を半分（translate は canvas と違い発熱しない）。
   ⚠️ .fx-par の高さに 100vh を使わないこと。iOS の URL バー伸縮で高さが跳ねる */
@media (max-width: 768px) {
  .fx-par { --fx-par-travel: 60px; }
}
