製品ティルト・ヒーロー

左にコピー、右に製品プレビューのUIモックカードを配置。カードはマウス位置に応じてperspectiveで傾き、無操作時はゆっくり揺らぎ続けるSaaS向けヒーローです。

#css#js#hero#3d

ライブデモ

コード

HTML
<!-- 製品ティルト・ヒーロー:左にコピー、右にUIモックカード。マウスに追従して傾く(perspective)。無操作時はゆらぎ -->
<section class="hpt">
  <div class="hpt__bg" aria-hidden="true"></div>
  <div class="hpt__inner">
    <div class="hpt__copy">
      <span class="hpt__kicker">NEW &middot; Design Workspace 3.0</span>
      <h1 class="hpt__title">デザインの意思決定を、<br>チーム全員の共通言語に。</h1>
      <p class="hpt__sub">バラバラだったフィードバックとバージョンを1つのキャンバスへ。マウスを製品プレビューに乗せて動かしてみてください。</p>
      <div class="hpt__cta">
        <a class="hpt__btn hpt__btn--primary" href="#" onclick="return false">無料で試す</a>
        <a class="hpt__btn hpt__btn--ghost" href="#" onclick="return false">機能を見る &rarr;</a>
      </div>
    </div>
    <div class="hpt__stage" id="hptStage">
      <div class="hpt__glow" aria-hidden="true"></div>
      <div class="hpt__card" id="hptCard" role="img" aria-label="製品プレビューのイメージ">
        <div class="hpt__card-head">
          <span class="hpt__dot"></span><span class="hpt__dot"></span><span class="hpt__dot"></span>
          <span class="hpt__card-title">Project &middot; Aurora</span>
        </div>
        <div class="hpt__card-body">
          <div class="hpt__layer" style="--x:8%; --y:14%; --w:52%; --h:34%;"></div>
          <div class="hpt__layer hpt__layer--accent" style="--x:64%; --y:20%; --w:28%; --h:22%;"></div>
          <div class="hpt__layer" style="--x:8%; --y:56%; --w:38%; --h:30%;"></div>
          <div class="hpt__layer hpt__layer--accent" style="--x:50%; --y:60%; --w:42%; --h:26%;"></div>
          <span class="hpt__cursor" aria-hidden="true">&#8598;</span>
        </div>
        <div class="hpt__card-foot">
          <span class="hpt__badge">同期完了</span>
          <span class="hpt__foot-users">&#9679;&#9679;&#9679; 4人が編集中</span>
        </div>
      </div>
    </div>
  </div>
</section>
CSS
* { box-sizing: border-box; }
body {
  margin: 0;
  display: block;
  background: #f5f6fb;
  font-family: "Segoe UI", "Hiragino Sans", system-ui, sans-serif;
}

/* ルート:全幅フル、左右分割の土台 */
.hpt {
  position: relative;
  width: 100%;
  min-height: 100vh;
  overflow: hidden;
  background: #f5f6fb;
  color: #17162a;
}

.hpt__bg {
  position: absolute; inset: 0;
  background:
    radial-gradient(38% 46% at 88% 10%, rgba(99, 102, 241, .14), transparent 62%),
    radial-gradient(32% 40% at 8% 92%, rgba(236, 72, 153, .1), transparent 65%);
}

.hpt__inner {
  position: relative; z-index: 1;
  max-width: 1160px; margin: 0 auto;
  min-height: 100vh;
  padding: 34px 28px;
  display: grid;
  grid-template-columns: 1fr 1.05fr;
  align-items: center;
  gap: 30px;
}

.hpt__kicker {
  display: inline-block; padding: 6px 14px; border-radius: 999px;
  background: #fff; border: 1px solid #e4e2f7;
  font-size: 11px; font-weight: 700; letter-spacing: .1em; color: #4f46e5;
  box-shadow: 0 2px 10px rgba(76, 29, 149, .06);
}
.hpt__title {
  margin: 16px 0 0; font-size: clamp(27px, 3.4vw, 38px); font-weight: 800;
  line-height: 1.3; letter-spacing: -.01em; color: #17162a;
}
.hpt__sub { margin: 14px 0 0; max-width: 420px; font-size: 14.5px; line-height: 1.75; color: #5c5a75; }
.hpt__cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 24px; }
.hpt__btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 12px 24px; border-radius: 12px;
  font-size: 14px; font-weight: 700; text-decoration: none;
  transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.hpt__btn--primary {
  color: #fff; background: linear-gradient(135deg, #4f46e5, #7c3aed);
  box-shadow: 0 10px 24px rgba(79, 70, 229, .3);
}
.hpt__btn--primary:hover { transform: translateY(-2px); }
.hpt__btn--ghost { color: #322f4d; background: #fff; border: 1px solid #e4e2f2; }
.hpt__btn--ghost:hover { border-color: #c9c4e6; transform: translateY(-2px); }

/* --- 傾く製品カード --- */
.hpt__stage {
  position: relative; display: grid; place-items: center;
  perspective: 1100px;
}
.hpt__glow {
  position: absolute; width: 70%; height: 70%; border-radius: 50%;
  background: radial-gradient(circle, rgba(124, 58, 237, .22), transparent 70%);
  filter: blur(6px);
  animation: hptGlow 6s ease-in-out infinite;
}
@keyframes hptGlow { 0%, 100% { opacity: .7; } 50% { opacity: 1; } }

.hpt__card {
  position: relative; z-index: 1; width: min(380px, 94%);
  background: #ffffff; border-radius: 20px; padding: 0;
  box-shadow: 0 30px 60px rgba(30, 20, 70, .18), 0 4px 10px rgba(30, 20, 70, .06);
  border: 1px solid #eeecf9;
  transform-style: preserve-3d;
  transform: rotateX(0deg) rotateY(0deg);
  transition: transform .5s ease;
  will-change: transform;
  /* JS未実行時も浮遊感を出す(無操作時のゆらぎのベース) */
  animation: hptIdle 7s ease-in-out infinite;
}
@keyframes hptIdle {
  0%, 100% { transform: rotateX(4deg) rotateY(-6deg) translateY(0); }
  50%      { transform: rotateX(-3deg) rotateY(6deg) translateY(-8px); }
}
.hpt__card.is-active { animation-play-state: paused; transition: transform .08s linear; }

.hpt__card-head {
  display: flex; align-items: center; gap: 6px;
  padding: 14px 16px; border-bottom: 1px solid #f0eef9;
}
.hpt__dot { width: 9px; height: 9px; border-radius: 50%; background: #e3e1f0; }
.hpt__dot:nth-child(1) { background: #f87171; }
.hpt__dot:nth-child(2) { background: #fbbf24; }
.hpt__dot:nth-child(3) { background: #34d399; }
.hpt__card-title { margin-left: 8px; font-size: 12px; font-weight: 700; color: #8b87a0; }

.hpt__card-body {
  position: relative; height: 220px; margin: 14px 16px;
  background: #f7f6fd; border-radius: 12px; overflow: hidden;
}
.hpt__layer {
  position: absolute; left: var(--x); top: var(--y); width: var(--w); height: var(--h);
  border-radius: 10px;
  background: linear-gradient(145deg, #e3e1f7, #cfcbf2);
  box-shadow: 0 6px 14px rgba(76, 29, 149, .08);
}
.hpt__layer--accent { background: linear-gradient(145deg, #a78bfa, #6d28d9); }
.hpt__cursor {
  position: absolute; right: 14%; bottom: 18%; font-size: 20px; color: #4f46e5;
  animation: hptCursor 3.4s ease-in-out infinite;
}
@keyframes hptCursor {
  0%, 100% { transform: translate(0, 0); }
  50%      { transform: translate(-14px, -10px); }
}

.hpt__card-foot {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 16px 16px;
}
.hpt__badge {
  display: inline-block; font-size: 11px; font-weight: 700; color: #166534;
  background: #dcfce7; padding: 5px 11px; border-radius: 999px;
}
.hpt__foot-users { font-size: 10.5px; letter-spacing: .06em; color: #9490ac; }

@media (max-width: 760px) {
  .hpt__inner { grid-template-columns: 1fr; padding: 26px 22px 24px; gap: 22px; min-height: 0; }
  .hpt__copy { order: 1; text-align: left; }
  .hpt__stage { order: 2; }
  .hpt__title { font-size: clamp(23px, 6.4vw, 28px); }
  .hpt__card { width: min(320px, 100%); }
  .hpt__card-body { height: 170px; }
}

@media (prefers-reduced-motion: reduce) {
  .hpt__card, .hpt__glow, .hpt__cursor { animation: none; transform: none; }
}
JavaScript
// 製品ティルト・ヒーロー:マウス位置に応じてカードをperspective傾ける。離れたらCSSのidleゆらぎに戻す。
(() => {
  const stage = document.getElementById('hptStage');
  const card = document.getElementById('hptCard');
  if (!stage || !card) return;

  const MAX_DEG = 12;

  const onMove = (e) => {
    const rect = stage.getBoundingClientRect();
    if (!rect.width || !rect.height) return;
    const px = (e.clientX - rect.left) / rect.width;  // 0..1
    const py = (e.clientY - rect.top) / rect.height;   // 0..1
    const rx = (0.5 - py) * MAX_DEG * 2;
    const ry = (px - 0.5) * MAX_DEG * 2;
    card.classList.add('is-active');
    card.style.transform = `rotateX(${rx.toFixed(2)}deg) rotateY(${ry.toFixed(2)}deg) translateY(-4px)`;
  };

  const onLeave = () => {
    card.classList.remove('is-active');
    card.style.transform = '';
  };

  stage.addEventListener('pointermove', onMove);
  stage.addEventListener('pointerleave', onLeave);
})();

🤖 AIエージェント用プロンプト

このままコピーしてAIに貼り付け「追加する場所」だけ書き換えればOK
あなたは熟練のフロントエンドエンジニアです。私のWebサイトに「製品ティルト・ヒーロー」の効果を追加してください。

# 追加してほしい効果
製品ティルト・ヒーロー(ヒーロー & タイトル)
左にコピー、右に製品プレビューのUIモックカードを配置。カードはマウス位置に応じてperspectiveで傾き、無操作時はゆっくり揺らぎ続けるSaaS向けヒーローです。

# 追加する場所
👉【ここに対象箇所を記入:例「トップのヒーローセクション」「お問い合わせボタン」「記事カードの一覧」など】

# 参考実装(この見た目・挙動を再現してください)
【HTML】
<!-- 製品ティルト・ヒーロー:左にコピー、右にUIモックカード。マウスに追従して傾く(perspective)。無操作時はゆらぎ -->
<section class="hpt">
  <div class="hpt__bg" aria-hidden="true"></div>
  <div class="hpt__inner">
    <div class="hpt__copy">
      <span class="hpt__kicker">NEW &middot; Design Workspace 3.0</span>
      <h1 class="hpt__title">デザインの意思決定を、<br>チーム全員の共通言語に。</h1>
      <p class="hpt__sub">バラバラだったフィードバックとバージョンを1つのキャンバスへ。マウスを製品プレビューに乗せて動かしてみてください。</p>
      <div class="hpt__cta">
        <a class="hpt__btn hpt__btn--primary" href="#" onclick="return false">無料で試す</a>
        <a class="hpt__btn hpt__btn--ghost" href="#" onclick="return false">機能を見る &rarr;</a>
      </div>
    </div>
    <div class="hpt__stage" id="hptStage">
      <div class="hpt__glow" aria-hidden="true"></div>
      <div class="hpt__card" id="hptCard" role="img" aria-label="製品プレビューのイメージ">
        <div class="hpt__card-head">
          <span class="hpt__dot"></span><span class="hpt__dot"></span><span class="hpt__dot"></span>
          <span class="hpt__card-title">Project &middot; Aurora</span>
        </div>
        <div class="hpt__card-body">
          <div class="hpt__layer" style="--x:8%; --y:14%; --w:52%; --h:34%;"></div>
          <div class="hpt__layer hpt__layer--accent" style="--x:64%; --y:20%; --w:28%; --h:22%;"></div>
          <div class="hpt__layer" style="--x:8%; --y:56%; --w:38%; --h:30%;"></div>
          <div class="hpt__layer hpt__layer--accent" style="--x:50%; --y:60%; --w:42%; --h:26%;"></div>
          <span class="hpt__cursor" aria-hidden="true">&#8598;</span>
        </div>
        <div class="hpt__card-foot">
          <span class="hpt__badge">同期完了</span>
          <span class="hpt__foot-users">&#9679;&#9679;&#9679; 4人が編集中</span>
        </div>
      </div>
    </div>
  </div>
</section>

【CSS】
* { box-sizing: border-box; }
body {
  margin: 0;
  display: block;
  background: #f5f6fb;
  font-family: "Segoe UI", "Hiragino Sans", system-ui, sans-serif;
}

/* ルート:全幅フル、左右分割の土台 */
.hpt {
  position: relative;
  width: 100%;
  min-height: 100vh;
  overflow: hidden;
  background: #f5f6fb;
  color: #17162a;
}

.hpt__bg {
  position: absolute; inset: 0;
  background:
    radial-gradient(38% 46% at 88% 10%, rgba(99, 102, 241, .14), transparent 62%),
    radial-gradient(32% 40% at 8% 92%, rgba(236, 72, 153, .1), transparent 65%);
}

.hpt__inner {
  position: relative; z-index: 1;
  max-width: 1160px; margin: 0 auto;
  min-height: 100vh;
  padding: 34px 28px;
  display: grid;
  grid-template-columns: 1fr 1.05fr;
  align-items: center;
  gap: 30px;
}

.hpt__kicker {
  display: inline-block; padding: 6px 14px; border-radius: 999px;
  background: #fff; border: 1px solid #e4e2f7;
  font-size: 11px; font-weight: 700; letter-spacing: .1em; color: #4f46e5;
  box-shadow: 0 2px 10px rgba(76, 29, 149, .06);
}
.hpt__title {
  margin: 16px 0 0; font-size: clamp(27px, 3.4vw, 38px); font-weight: 800;
  line-height: 1.3; letter-spacing: -.01em; color: #17162a;
}
.hpt__sub { margin: 14px 0 0; max-width: 420px; font-size: 14.5px; line-height: 1.75; color: #5c5a75; }
.hpt__cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 24px; }
.hpt__btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 12px 24px; border-radius: 12px;
  font-size: 14px; font-weight: 700; text-decoration: none;
  transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.hpt__btn--primary {
  color: #fff; background: linear-gradient(135deg, #4f46e5, #7c3aed);
  box-shadow: 0 10px 24px rgba(79, 70, 229, .3);
}
.hpt__btn--primary:hover { transform: translateY(-2px); }
.hpt__btn--ghost { color: #322f4d; background: #fff; border: 1px solid #e4e2f2; }
.hpt__btn--ghost:hover { border-color: #c9c4e6; transform: translateY(-2px); }

/* --- 傾く製品カード --- */
.hpt__stage {
  position: relative; display: grid; place-items: center;
  perspective: 1100px;
}
.hpt__glow {
  position: absolute; width: 70%; height: 70%; border-radius: 50%;
  background: radial-gradient(circle, rgba(124, 58, 237, .22), transparent 70%);
  filter: blur(6px);
  animation: hptGlow 6s ease-in-out infinite;
}
@keyframes hptGlow { 0%, 100% { opacity: .7; } 50% { opacity: 1; } }

.hpt__card {
  position: relative; z-index: 1; width: min(380px, 94%);
  background: #ffffff; border-radius: 20px; padding: 0;
  box-shadow: 0 30px 60px rgba(30, 20, 70, .18), 0 4px 10px rgba(30, 20, 70, .06);
  border: 1px solid #eeecf9;
  transform-style: preserve-3d;
  transform: rotateX(0deg) rotateY(0deg);
  transition: transform .5s ease;
  will-change: transform;
  /* JS未実行時も浮遊感を出す(無操作時のゆらぎのベース) */
  animation: hptIdle 7s ease-in-out infinite;
}
@keyframes hptIdle {
  0%, 100% { transform: rotateX(4deg) rotateY(-6deg) translateY(0); }
  50%      { transform: rotateX(-3deg) rotateY(6deg) translateY(-8px); }
}
.hpt__card.is-active { animation-play-state: paused; transition: transform .08s linear; }

.hpt__card-head {
  display: flex; align-items: center; gap: 6px;
  padding: 14px 16px; border-bottom: 1px solid #f0eef9;
}
.hpt__dot { width: 9px; height: 9px; border-radius: 50%; background: #e3e1f0; }
.hpt__dot:nth-child(1) { background: #f87171; }
.hpt__dot:nth-child(2) { background: #fbbf24; }
.hpt__dot:nth-child(3) { background: #34d399; }
.hpt__card-title { margin-left: 8px; font-size: 12px; font-weight: 700; color: #8b87a0; }

.hpt__card-body {
  position: relative; height: 220px; margin: 14px 16px;
  background: #f7f6fd; border-radius: 12px; overflow: hidden;
}
.hpt__layer {
  position: absolute; left: var(--x); top: var(--y); width: var(--w); height: var(--h);
  border-radius: 10px;
  background: linear-gradient(145deg, #e3e1f7, #cfcbf2);
  box-shadow: 0 6px 14px rgba(76, 29, 149, .08);
}
.hpt__layer--accent { background: linear-gradient(145deg, #a78bfa, #6d28d9); }
.hpt__cursor {
  position: absolute; right: 14%; bottom: 18%; font-size: 20px; color: #4f46e5;
  animation: hptCursor 3.4s ease-in-out infinite;
}
@keyframes hptCursor {
  0%, 100% { transform: translate(0, 0); }
  50%      { transform: translate(-14px, -10px); }
}

.hpt__card-foot {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 16px 16px;
}
.hpt__badge {
  display: inline-block; font-size: 11px; font-weight: 700; color: #166534;
  background: #dcfce7; padding: 5px 11px; border-radius: 999px;
}
.hpt__foot-users { font-size: 10.5px; letter-spacing: .06em; color: #9490ac; }

@media (max-width: 760px) {
  .hpt__inner { grid-template-columns: 1fr; padding: 26px 22px 24px; gap: 22px; min-height: 0; }
  .hpt__copy { order: 1; text-align: left; }
  .hpt__stage { order: 2; }
  .hpt__title { font-size: clamp(23px, 6.4vw, 28px); }
  .hpt__card { width: min(320px, 100%); }
  .hpt__card-body { height: 170px; }
}

@media (prefers-reduced-motion: reduce) {
  .hpt__card, .hpt__glow, .hpt__cursor { animation: none; transform: none; }
}

【JavaScript】
// 製品ティルト・ヒーロー:マウス位置に応じてカードをperspective傾ける。離れたらCSSのidleゆらぎに戻す。
(() => {
  const stage = document.getElementById('hptStage');
  const card = document.getElementById('hptCard');
  if (!stage || !card) return;

  const MAX_DEG = 12;

  const onMove = (e) => {
    const rect = stage.getBoundingClientRect();
    if (!rect.width || !rect.height) return;
    const px = (e.clientX - rect.left) / rect.width;  // 0..1
    const py = (e.clientY - rect.top) / rect.height;   // 0..1
    const rx = (0.5 - py) * MAX_DEG * 2;
    const ry = (px - 0.5) * MAX_DEG * 2;
    card.classList.add('is-active');
    card.style.transform = `rotateX(${rx.toFixed(2)}deg) rotateY(${ry.toFixed(2)}deg) translateY(-4px)`;
  };

  const onLeave = () => {
    card.classList.remove('is-active');
    card.style.transform = '';
  };

  stage.addEventListener('pointermove', onMove);
  stage.addEventListener('pointerleave', onLeave);
})();

# 外部ライブラリ
なし(追加ライブラリ不要)

# 守ってほしいこと
- 既存のHTML構造・レイアウト・デザインを壊さないこと。必要に応じてクラス名・色・サイズを私のサイトに合わせて調整してよい。
- クラス名やidが既存と衝突しないよう、必要なら接頭辞で名前空間を分けること。
- レスポンシブ対応と prefers-reduced-motion への配慮を入れること。
- 私のサイトのフレームワーク(React / Vue / 素のHTML など)に合わせて実装すること。不明な場合は素のHTML/CSS/JSで提示し、組み込み手順も説明すること。
- 変更後の確認手順も簡潔に教えてください。