プレイリスト

6曲分の曲名・アーティスト・再生時間を一覧表示するプレイリスト。再生中の曲は番号がバーアニメーションに切り替わり、総再生時間もヘッダーに表示します。

#css#js#media

ライブデモ

コード

HTML
<!-- プレイリスト: 曲リスト+再生中ハイライト(バーアニメ)+各曲の長さ+総再生時間 -->
<div class="stage">
  <section class="mpl-playlist" aria-label="プレイリスト">
    <header class="mpl-playlist__head">
      <h2 class="mpl-playlist__title">夜想プレイリスト</h2>
      <p class="mpl-playlist__count">6曲 ・ 21分17秒</p>
    </header>

    <ul class="mpl-playlist__list">
      <li class="mpl-playlist__item is-active" data-duration="204">
        <button type="button" class="mpl-playlist__row" aria-current="true">
          <span class="mpl-playlist__index">
            <span class="mpl-playlist__num">1</span>
            <span class="mpl-playlist__eq" aria-hidden="true"><i></i><i></i><i></i></span>
          </span>
          <span class="mpl-playlist__meta">
            <span class="mpl-playlist__name">朝焼けのプレリュード</span>
            <span class="mpl-playlist__artist">Sora Tone</span>
          </span>
          <span class="mpl-playlist__duration">3:24</span>
        </button>
        <span class="mpl-playlist__progress" aria-hidden="true"><span class="mpl-playlist__progress-fill"></span></span>
      </li>

      <li class="mpl-playlist__item" data-duration="242">
        <button type="button" class="mpl-playlist__row" aria-current="false">
          <span class="mpl-playlist__index">
            <span class="mpl-playlist__num">2</span>
            <span class="mpl-playlist__eq" aria-hidden="true"><i></i><i></i><i></i></span>
          </span>
          <span class="mpl-playlist__meta">
            <span class="mpl-playlist__name">硝子の街</span>
            <span class="mpl-playlist__artist">水城かおり</span>
          </span>
          <span class="mpl-playlist__duration">4:02</span>
        </button>
        <span class="mpl-playlist__progress" aria-hidden="true"><span class="mpl-playlist__progress-fill"></span></span>
      </li>

      <li class="mpl-playlist__item" data-duration="171">
        <button type="button" class="mpl-playlist__row" aria-current="false">
          <span class="mpl-playlist__index">
            <span class="mpl-playlist__num">3</span>
            <span class="mpl-playlist__eq" aria-hidden="true"><i></i><i></i><i></i></span>
          </span>
          <span class="mpl-playlist__meta">
            <span class="mpl-playlist__name">潮風とページ</span>
            <span class="mpl-playlist__artist">Blue Note Diner</span>
          </span>
          <span class="mpl-playlist__duration">2:51</span>
        </button>
        <span class="mpl-playlist__progress" aria-hidden="true"><span class="mpl-playlist__progress-fill"></span></span>
      </li>

      <li class="mpl-playlist__item" data-duration="217">
        <button type="button" class="mpl-playlist__row" aria-current="false">
          <span class="mpl-playlist__index">
            <span class="mpl-playlist__num">4</span>
            <span class="mpl-playlist__eq" aria-hidden="true"><i></i><i></i><i></i></span>
          </span>
          <span class="mpl-playlist__meta">
            <span class="mpl-playlist__name">午後三時のワルツ</span>
            <span class="mpl-playlist__artist">ミナモ</span>
          </span>
          <span class="mpl-playlist__duration">3:37</span>
        </button>
        <span class="mpl-playlist__progress" aria-hidden="true"><span class="mpl-playlist__progress-fill"></span></span>
      </li>

      <li class="mpl-playlist__item" data-duration="255">
        <button type="button" class="mpl-playlist__row" aria-current="false">
          <span class="mpl-playlist__index">
            <span class="mpl-playlist__num">5</span>
            <span class="mpl-playlist__eq" aria-hidden="true"><i></i><i></i><i></i></span>
          </span>
          <span class="mpl-playlist__meta">
            <span class="mpl-playlist__name">遠回りの帰り道</span>
            <span class="mpl-playlist__artist">Kenta Ogawa</span>
          </span>
          <span class="mpl-playlist__duration">4:15</span>
        </button>
        <span class="mpl-playlist__progress" aria-hidden="true"><span class="mpl-playlist__progress-fill"></span></span>
      </li>

      <li class="mpl-playlist__item" data-duration="188">
        <button type="button" class="mpl-playlist__row" aria-current="false">
          <span class="mpl-playlist__index">
            <span class="mpl-playlist__num">6</span>
            <span class="mpl-playlist__eq" aria-hidden="true"><i></i><i></i><i></i></span>
          </span>
          <span class="mpl-playlist__meta">
            <span class="mpl-playlist__name">灯りをつけて</span>
            <span class="mpl-playlist__artist">yura</span>
          </span>
          <span class="mpl-playlist__duration">3:08</span>
        </button>
        <span class="mpl-playlist__progress" aria-hidden="true"><span class="mpl-playlist__progress-fill"></span></span>
      </li>
    </ul>
  </section>
</div>
CSS
/* プレイリスト: 紙のように上品なオフホワイト+ミントのアクセント */
* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  padding: 24px;
  display: grid;
  place-items: center;
  font-family: "Hiragino Sans", "Segoe UI", system-ui, -apple-system, sans-serif;
  background:
    radial-gradient(circle at 10% 8%, #e3f3ec 0%, transparent 45%),
    radial-gradient(circle at 92% 90%, #eef1e0 0%, transparent 48%),
    #fbfaf7;
  color: #23282a;
}

.stage { display: grid; place-items: center; width: 100%; }

.mpl-playlist {
  width: min(420px, 92vw);
  padding: 22px 8px 14px;
  border-radius: 20px;
  background: #ffffff;
  box-shadow: 0 20px 48px rgba(30, 40, 36, .1);
}

.mpl-playlist__head { padding: 0 18px 14px; border-bottom: 1px solid #eef0ec; margin-bottom: 6px; }
.mpl-playlist__title { margin: 0 0 4px; font-size: 16.5px; font-weight: 800; letter-spacing: .01em; }
.mpl-playlist__count { margin: 0; font-size: 12px; color: #8b958e; }

.mpl-playlist__list { list-style: none; margin: 0; padding: 6px; display: grid; gap: 2px; }

.mpl-playlist__item { position: relative; border-radius: 12px; overflow: hidden; }

.mpl-playlist__row {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border: none;
  background: transparent;
  font: inherit;
  text-align: left;
  color: inherit;
  cursor: pointer;
  border-radius: 12px;
  transition: background .16s ease;
}
.mpl-playlist__row:hover { background: #f3f7f2; }
.mpl-playlist__item.is-active .mpl-playlist__row { background: #e8f5ee; }

.mpl-playlist__index {
  position: relative;
  flex: none;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
}
.mpl-playlist__num { font-size: 12.5px; font-variant-numeric: tabular-nums; color: #9aa39c; }
.mpl-playlist__item.is-active .mpl-playlist__num { display: none; }

.mpl-playlist__eq {
  display: none;
  align-items: flex-end;
  gap: 3px;
  height: 15px;
}
.mpl-playlist__item.is-active .mpl-playlist__eq { display: flex; }
.mpl-playlist__eq i {
  display: block;
  width: 3px;
  border-radius: 2px;
  background: #2f9e6b;
  transform: scaleY(.35);
  animation: mpl-bounce 1s ease-in-out infinite;
  animation-play-state: paused;
}
.mpl-playlist__item.is-active.is-playing .mpl-playlist__eq i { animation-play-state: running; }
.mpl-playlist__eq i:nth-child(1) { height: 8px; animation-delay: -.5s; }
.mpl-playlist__eq i:nth-child(2) { height: 14px; animation-delay: -.15s; }
.mpl-playlist__eq i:nth-child(3) { height: 10px; animation-delay: -.8s; }
@keyframes mpl-bounce { 0%, 100% { transform: scaleY(.35); } 50% { transform: scaleY(1); } }

.mpl-playlist__meta { min-width: 0; flex: 1; display: grid; }
.mpl-playlist__name {
  font-size: 13.5px;
  font-weight: 700;
  color: #23282a;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mpl-playlist__item.is-active .mpl-playlist__name { color: #1f7a4f; }
.mpl-playlist__artist { font-size: 11.5px; color: #8b958e; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.mpl-playlist__duration { flex: none; font-size: 11.5px; font-variant-numeric: tabular-nums; color: #9aa39c; }

.mpl-playlist__progress {
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 3px;
  height: 2px;
  border-radius: 2px;
  background: rgba(47, 158, 107, .12);
  display: none;
}
.mpl-playlist__item.is-active .mpl-playlist__progress { display: block; }
.mpl-playlist__progress-fill {
  display: block;
  height: 100%;
  width: 0%;
  border-radius: 2px;
  background: linear-gradient(90deg, #6cc79b, #2f9e6b);
}

@media (prefers-reduced-motion: reduce) {
  .mpl-playlist__row { transition: none; }
  .mpl-playlist__eq i { animation: none; }
}
JavaScript
// プレイリスト: 実音声は使わず、選択中の曲の進捗バーをタイマーで擬似的に進める
(() => {
  const list = document.querySelector('.mpl-playlist__list');
  if (!list) return; // null安全

  const items = Array.from(list.querySelectorAll('.mpl-playlist__item'));
  if (!items.length) return;

  const reduceMotion = window.matchMedia ? window.matchMedia('(prefers-reduced-motion: reduce)').matches : false;

  const TICK_MS = 200;
  const SPEED = 5.5; // デモとして体感しやすい速さで擬似進行させる倍率

  let activeIndex = items.findIndex((li) => li.classList.contains('is-active'));
  if (activeIndex < 0) activeIndex = 0;
  let current = 0;
  let playing = false;
  let timer = null;

  function durationOf(li) { return parseFloat(li.dataset.duration) || 0; }
  function fillOf(li) { return li.querySelector('.mpl-playlist__progress-fill'); }
  function rowOf(li) { return li.querySelector('.mpl-playlist__row'); }

  function renderActiveState() {
    items.forEach((li, i) => {
      const active = i === activeIndex;
      li.classList.toggle('is-active', active);
      li.classList.toggle('is-playing', active && playing);
      const row = rowOf(li);
      if (row) row.setAttribute('aria-current', String(active));
      if (!active) {
        const fill = fillOf(li);
        if (fill) fill.style.width = '0%';
      }
    });
  }

  function renderProgress() {
    const li = items[activeIndex];
    const d = durationOf(li);
    const fill = fillOf(li);
    if (fill) fill.style.width = `${d ? Math.min(100, (current / d) * 100) : 0}%`;
  }

  function setPlaying(next) {
    playing = next;
    items[activeIndex].classList.toggle('is-playing', next);
    clearInterval(timer);
    if (next) {
      timer = setInterval(() => {
        current += (TICK_MS / 1000) * SPEED;
        const d = durationOf(items[activeIndex]);
        if (current >= d) { goTo(activeIndex + 1, true); return; }
        renderProgress();
      }, TICK_MS);
    }
  }

  function goTo(index, keepPlaying) {
    const len = items.length;
    activeIndex = ((index % len) + len) % len;
    current = 0;
    renderActiveState();
    renderProgress();
    setPlaying(keepPlaying !== false);
  }

  items.forEach((li, i) => {
    const row = rowOf(li);
    if (!row) return;
    row.addEventListener('click', () => {
      if (i === activeIndex) { setPlaying(!playing); }
      else { goTo(i, true); }
    });
  });

  renderActiveState();
  renderProgress();
  // カード上でも「生きている」ことが伝わるよう既定で再生。モーション低減設定時は静止状態から開始
  if (!reduceMotion) setPlaying(true);
})();

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

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

# 追加してほしい効果
プレイリスト(チャット & メディア)
6曲分の曲名・アーティスト・再生時間を一覧表示するプレイリスト。再生中の曲は番号がバーアニメーションに切り替わり、総再生時間もヘッダーに表示します。

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

# 参考実装(この見た目・挙動を再現してください)
【HTML】
<!-- プレイリスト: 曲リスト+再生中ハイライト(バーアニメ)+各曲の長さ+総再生時間 -->
<div class="stage">
  <section class="mpl-playlist" aria-label="プレイリスト">
    <header class="mpl-playlist__head">
      <h2 class="mpl-playlist__title">夜想プレイリスト</h2>
      <p class="mpl-playlist__count">6曲 ・ 21分17秒</p>
    </header>

    <ul class="mpl-playlist__list">
      <li class="mpl-playlist__item is-active" data-duration="204">
        <button type="button" class="mpl-playlist__row" aria-current="true">
          <span class="mpl-playlist__index">
            <span class="mpl-playlist__num">1</span>
            <span class="mpl-playlist__eq" aria-hidden="true"><i></i><i></i><i></i></span>
          </span>
          <span class="mpl-playlist__meta">
            <span class="mpl-playlist__name">朝焼けのプレリュード</span>
            <span class="mpl-playlist__artist">Sora Tone</span>
          </span>
          <span class="mpl-playlist__duration">3:24</span>
        </button>
        <span class="mpl-playlist__progress" aria-hidden="true"><span class="mpl-playlist__progress-fill"></span></span>
      </li>

      <li class="mpl-playlist__item" data-duration="242">
        <button type="button" class="mpl-playlist__row" aria-current="false">
          <span class="mpl-playlist__index">
            <span class="mpl-playlist__num">2</span>
            <span class="mpl-playlist__eq" aria-hidden="true"><i></i><i></i><i></i></span>
          </span>
          <span class="mpl-playlist__meta">
            <span class="mpl-playlist__name">硝子の街</span>
            <span class="mpl-playlist__artist">水城かおり</span>
          </span>
          <span class="mpl-playlist__duration">4:02</span>
        </button>
        <span class="mpl-playlist__progress" aria-hidden="true"><span class="mpl-playlist__progress-fill"></span></span>
      </li>

      <li class="mpl-playlist__item" data-duration="171">
        <button type="button" class="mpl-playlist__row" aria-current="false">
          <span class="mpl-playlist__index">
            <span class="mpl-playlist__num">3</span>
            <span class="mpl-playlist__eq" aria-hidden="true"><i></i><i></i><i></i></span>
          </span>
          <span class="mpl-playlist__meta">
            <span class="mpl-playlist__name">潮風とページ</span>
            <span class="mpl-playlist__artist">Blue Note Diner</span>
          </span>
          <span class="mpl-playlist__duration">2:51</span>
        </button>
        <span class="mpl-playlist__progress" aria-hidden="true"><span class="mpl-playlist__progress-fill"></span></span>
      </li>

      <li class="mpl-playlist__item" data-duration="217">
        <button type="button" class="mpl-playlist__row" aria-current="false">
          <span class="mpl-playlist__index">
            <span class="mpl-playlist__num">4</span>
            <span class="mpl-playlist__eq" aria-hidden="true"><i></i><i></i><i></i></span>
          </span>
          <span class="mpl-playlist__meta">
            <span class="mpl-playlist__name">午後三時のワルツ</span>
            <span class="mpl-playlist__artist">ミナモ</span>
          </span>
          <span class="mpl-playlist__duration">3:37</span>
        </button>
        <span class="mpl-playlist__progress" aria-hidden="true"><span class="mpl-playlist__progress-fill"></span></span>
      </li>

      <li class="mpl-playlist__item" data-duration="255">
        <button type="button" class="mpl-playlist__row" aria-current="false">
          <span class="mpl-playlist__index">
            <span class="mpl-playlist__num">5</span>
            <span class="mpl-playlist__eq" aria-hidden="true"><i></i><i></i><i></i></span>
          </span>
          <span class="mpl-playlist__meta">
            <span class="mpl-playlist__name">遠回りの帰り道</span>
            <span class="mpl-playlist__artist">Kenta Ogawa</span>
          </span>
          <span class="mpl-playlist__duration">4:15</span>
        </button>
        <span class="mpl-playlist__progress" aria-hidden="true"><span class="mpl-playlist__progress-fill"></span></span>
      </li>

      <li class="mpl-playlist__item" data-duration="188">
        <button type="button" class="mpl-playlist__row" aria-current="false">
          <span class="mpl-playlist__index">
            <span class="mpl-playlist__num">6</span>
            <span class="mpl-playlist__eq" aria-hidden="true"><i></i><i></i><i></i></span>
          </span>
          <span class="mpl-playlist__meta">
            <span class="mpl-playlist__name">灯りをつけて</span>
            <span class="mpl-playlist__artist">yura</span>
          </span>
          <span class="mpl-playlist__duration">3:08</span>
        </button>
        <span class="mpl-playlist__progress" aria-hidden="true"><span class="mpl-playlist__progress-fill"></span></span>
      </li>
    </ul>
  </section>
</div>

【CSS】
/* プレイリスト: 紙のように上品なオフホワイト+ミントのアクセント */
* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  padding: 24px;
  display: grid;
  place-items: center;
  font-family: "Hiragino Sans", "Segoe UI", system-ui, -apple-system, sans-serif;
  background:
    radial-gradient(circle at 10% 8%, #e3f3ec 0%, transparent 45%),
    radial-gradient(circle at 92% 90%, #eef1e0 0%, transparent 48%),
    #fbfaf7;
  color: #23282a;
}

.stage { display: grid; place-items: center; width: 100%; }

.mpl-playlist {
  width: min(420px, 92vw);
  padding: 22px 8px 14px;
  border-radius: 20px;
  background: #ffffff;
  box-shadow: 0 20px 48px rgba(30, 40, 36, .1);
}

.mpl-playlist__head { padding: 0 18px 14px; border-bottom: 1px solid #eef0ec; margin-bottom: 6px; }
.mpl-playlist__title { margin: 0 0 4px; font-size: 16.5px; font-weight: 800; letter-spacing: .01em; }
.mpl-playlist__count { margin: 0; font-size: 12px; color: #8b958e; }

.mpl-playlist__list { list-style: none; margin: 0; padding: 6px; display: grid; gap: 2px; }

.mpl-playlist__item { position: relative; border-radius: 12px; overflow: hidden; }

.mpl-playlist__row {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border: none;
  background: transparent;
  font: inherit;
  text-align: left;
  color: inherit;
  cursor: pointer;
  border-radius: 12px;
  transition: background .16s ease;
}
.mpl-playlist__row:hover { background: #f3f7f2; }
.mpl-playlist__item.is-active .mpl-playlist__row { background: #e8f5ee; }

.mpl-playlist__index {
  position: relative;
  flex: none;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
}
.mpl-playlist__num { font-size: 12.5px; font-variant-numeric: tabular-nums; color: #9aa39c; }
.mpl-playlist__item.is-active .mpl-playlist__num { display: none; }

.mpl-playlist__eq {
  display: none;
  align-items: flex-end;
  gap: 3px;
  height: 15px;
}
.mpl-playlist__item.is-active .mpl-playlist__eq { display: flex; }
.mpl-playlist__eq i {
  display: block;
  width: 3px;
  border-radius: 2px;
  background: #2f9e6b;
  transform: scaleY(.35);
  animation: mpl-bounce 1s ease-in-out infinite;
  animation-play-state: paused;
}
.mpl-playlist__item.is-active.is-playing .mpl-playlist__eq i { animation-play-state: running; }
.mpl-playlist__eq i:nth-child(1) { height: 8px; animation-delay: -.5s; }
.mpl-playlist__eq i:nth-child(2) { height: 14px; animation-delay: -.15s; }
.mpl-playlist__eq i:nth-child(3) { height: 10px; animation-delay: -.8s; }
@keyframes mpl-bounce { 0%, 100% { transform: scaleY(.35); } 50% { transform: scaleY(1); } }

.mpl-playlist__meta { min-width: 0; flex: 1; display: grid; }
.mpl-playlist__name {
  font-size: 13.5px;
  font-weight: 700;
  color: #23282a;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mpl-playlist__item.is-active .mpl-playlist__name { color: #1f7a4f; }
.mpl-playlist__artist { font-size: 11.5px; color: #8b958e; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.mpl-playlist__duration { flex: none; font-size: 11.5px; font-variant-numeric: tabular-nums; color: #9aa39c; }

.mpl-playlist__progress {
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 3px;
  height: 2px;
  border-radius: 2px;
  background: rgba(47, 158, 107, .12);
  display: none;
}
.mpl-playlist__item.is-active .mpl-playlist__progress { display: block; }
.mpl-playlist__progress-fill {
  display: block;
  height: 100%;
  width: 0%;
  border-radius: 2px;
  background: linear-gradient(90deg, #6cc79b, #2f9e6b);
}

@media (prefers-reduced-motion: reduce) {
  .mpl-playlist__row { transition: none; }
  .mpl-playlist__eq i { animation: none; }
}

【JavaScript】
// プレイリスト: 実音声は使わず、選択中の曲の進捗バーをタイマーで擬似的に進める
(() => {
  const list = document.querySelector('.mpl-playlist__list');
  if (!list) return; // null安全

  const items = Array.from(list.querySelectorAll('.mpl-playlist__item'));
  if (!items.length) return;

  const reduceMotion = window.matchMedia ? window.matchMedia('(prefers-reduced-motion: reduce)').matches : false;

  const TICK_MS = 200;
  const SPEED = 5.5; // デモとして体感しやすい速さで擬似進行させる倍率

  let activeIndex = items.findIndex((li) => li.classList.contains('is-active'));
  if (activeIndex < 0) activeIndex = 0;
  let current = 0;
  let playing = false;
  let timer = null;

  function durationOf(li) { return parseFloat(li.dataset.duration) || 0; }
  function fillOf(li) { return li.querySelector('.mpl-playlist__progress-fill'); }
  function rowOf(li) { return li.querySelector('.mpl-playlist__row'); }

  function renderActiveState() {
    items.forEach((li, i) => {
      const active = i === activeIndex;
      li.classList.toggle('is-active', active);
      li.classList.toggle('is-playing', active && playing);
      const row = rowOf(li);
      if (row) row.setAttribute('aria-current', String(active));
      if (!active) {
        const fill = fillOf(li);
        if (fill) fill.style.width = '0%';
      }
    });
  }

  function renderProgress() {
    const li = items[activeIndex];
    const d = durationOf(li);
    const fill = fillOf(li);
    if (fill) fill.style.width = `${d ? Math.min(100, (current / d) * 100) : 0}%`;
  }

  function setPlaying(next) {
    playing = next;
    items[activeIndex].classList.toggle('is-playing', next);
    clearInterval(timer);
    if (next) {
      timer = setInterval(() => {
        current += (TICK_MS / 1000) * SPEED;
        const d = durationOf(items[activeIndex]);
        if (current >= d) { goTo(activeIndex + 1, true); return; }
        renderProgress();
      }, TICK_MS);
    }
  }

  function goTo(index, keepPlaying) {
    const len = items.length;
    activeIndex = ((index % len) + len) % len;
    current = 0;
    renderActiveState();
    renderProgress();
    setPlaying(keepPlaying !== false);
  }

  items.forEach((li, i) => {
    const row = rowOf(li);
    if (!row) return;
    row.addEventListener('click', () => {
      if (i === activeIndex) { setPlaying(!playing); }
      else { goTo(i, true); }
    });
  });

  renderActiveState();
  renderProgress();
  // カード上でも「生きている」ことが伝わるよう既定で再生。モーション低減設定時は静止状態から開始
  if (!reduceMotion) setPlaying(true);
})();

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

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