「飲食店・料理」サイトを表現する

湯気・照り・満ちる液体。食欲と温度感を呼び起こす、料理の「美味しそう」を伝える表現テクニック。

このページについて

  • 「料理シーンの表現」とは:湯気の温度感・シズルの照り・液体の動きなど、五感の記憶を呼び起こして食欲につなげる表現。写真の質に依存しがちな飲食サイトで、写真を引き立てる「動きの一手」を加える。
  • こんな時に使う:レストラン・カフェ・ラーメン/うどん店・居酒屋・テイクアウト/デリバリー・食品EC・レシピサービス・グルメメディア。
  • 関連タグ🌺 温かみ(準備中)🌿 癒し
  • AIへの伝え方のコツ:「美味しそうに」では伝わらない。「湯気を3筋、feTurbulenceで揺らがせて」「料理写真の上をハイライトが斜めに流れる」のように、本ページの表現名と数値で指示する。

表現の引き出し

🎨 立ち上る湯気

📝 表現の語彙

日本語: 湯気、立ち上る湯気、ほかほか、湯気がゆらぐ
英語: rising steam, hot vapor, steaming
抽象キーワード: warmth, freshness, appetite

💬 AIへの指示テンプレ

「深い焙煎色の背景に、器のシルエットから湯気が3筋立ち上るアニメーションを作ってください。各筋は縦グラデーションの帯(下が透明→中央が白→上が透明)にblurをかけ、上昇・横の蛇行・拡散(scaleX拡大+opacity漸減)の3アニメを筋ごとに違う周期で合成します。湯気グループ全体にfeTurbulence+feDisplacementMapをかけ、本物の湯気の揺らぎを加えてください。重要: 根元は細く濃く、上昇するほど広がり薄まる物理を守ってください。」

🎯 似合うシーン

ラーメン/うどん/そば店・カフェ・定食屋・鍋料理店・冬季キャンペーン・スープ系商品LP

🔧 実装手法

3筋×3軸合成(上昇/蛇行/拡散)+ feTurbulenceの揺らぎ + 器は陶器グラデ・スープ・リムライト・接地影の多層SVGで立体に描き込む

📄 コード例を見る
html
<div class="steam-stage">
  <!-- 湯気のゆらぎ用フィルター(1デモ1層まで) -->
  <svg width="0" height="0" aria-hidden="true">
    <filter id="steamWobble" x="-30%" y="-30%" width="160%" height="160%">
      <feTurbulence type="fractalNoise" baseFrequency="0.012 0.04"
        numOctaves="2" seed="7" result="noise">
        <animate attributeName="baseFrequency" dur="13s"
          values="0.012 0.04; 0.016 0.05; 0.012 0.04" repeatCount="indefinite" />
      </feTurbulence>
      <feDisplacementMap in="SourceGraphic" in2="noise" scale="10" />
    </filter>
  </svg>

  <div class="heat-glow"></div>

  <div class="steam-group">
    <!-- 上昇・蛇行・拡散を別レイヤーに分けて3軸を独立合成 -->
    <div class="steam-rise s1"><div class="steam-sway sw1"><div class="steam-band b1"></div></div></div>
    <div class="steam-rise s2"><div class="steam-sway sw2"><div class="steam-band b2"></div></div></div>
    <div class="steam-rise s3"><div class="steam-sway sw3"><div class="steam-band b3"></div></div></div>
  </div>

  <!-- 器:影絵にせず、釉薬の明暗・スープ・リムライトの多層グラデで立体に描き込む -->
  <svg class="bowl-svg" viewBox="0 0 220 84" width="220" height="84">
    <defs>
      <!-- 陶器の縦グラデ:上が照らされ、下へ沈む -->
      <linearGradient id="bowlBody" x1="0" y1="0" x2="0" y2="1">
        <stop offset="0%" stop-color="#54402c" />
        <stop offset="30%" stop-color="#3a2718" />
        <stop offset="70%" stop-color="#241710" />
        <stop offset="100%" stop-color="#150d07" />
      </linearGradient>
      <!-- スープ:光源寄り(左上)が明るい琥珀 -->
      <radialGradient id="broth" cx="42%" cy="35%" r="80%">
        <stop offset="0%" stop-color="#eeb766" />
        <stop offset="40%" stop-color="#cd8740" />
        <stop offset="75%" stop-color="#9c5d22" />
        <stop offset="100%" stop-color="#7a4517" />
      </radialGradient>
      <radialGradient id="brothSheen" cx="50%" cy="50%" r="50%">
        <stop offset="0%" stop-color="rgba(255,248,235,0.55)" />
        <stop offset="100%" stop-color="rgba(255,248,235,0)" />
      </radialGradient>
      <radialGradient id="bowlShadow" cx="50%" cy="50%" r="50%">
        <stop offset="0%" stop-color="rgba(0,0,0,0.5)" />
        <stop offset="70%" stop-color="rgba(0,0,0,0)" />
      </radialGradient>
    </defs>
    <!-- 接地影 → 胴 → 高台 → 内壁 → スープ → 薬味 → リムライト → 側面の艶 -->
    <ellipse cx="110" cy="76" rx="80" ry="7" fill="url(#bowlShadow)" />
    <path d="M42 22 Q48 56 84 66 L136 66 Q172 56 178 22 Q110 31 42 22 Z" fill="url(#bowlBody)" />
    <path d="M90 66 L130 66 L126 75 L94 75 Z" fill="#120b06" />
    <!-- 視点を低く取り、汁面は縁の奥にわずかに覗く程度に抑える -->
    <ellipse cx="110" cy="22" rx="68" ry="6.5" fill="#1c1209" />
    <ellipse cx="110" cy="21.5" rx="62" ry="5" fill="url(#broth)" />
    <ellipse cx="94" cy="20" rx="18" ry="2.4" fill="url(#brothSheen)" />
    <rect x="100" y="19.5" width="8" height="2" rx="1" fill="#86a854" transform="rotate(-14 104 20.5)" />
    <rect x="122" y="18.5" width="7" height="2" rx="1" fill="#6f9446" transform="rotate(10 125 19.5)" />
    <path d="M46 23.5 Q110 32 174 23.5" stroke="#d4a574" stroke-width="1.5" opacity="0.55" fill="none" />
    <path d="M52 18 Q110 14.5 168 18" stroke="#e8c194" stroke-width="1" opacity="0.3" fill="none" />
    <path d="M62 32 Q58 48 72 60" stroke="#ffffff" stroke-width="5" opacity="0.06" fill="none" stroke-linecap="round" />
    <path d="M158 32 Q162 48 148 60" stroke="#ffffff" stroke-width="4" opacity="0.04" fill="none" stroke-linecap="round" />
  </svg>
</div>
css
.steam-stage {
  position: relative;
  height: 180px;
  border-radius: 8px;
  overflow: hidden;
  /* 焙煎色の深い茶。湯気の白が最も映える */
  background: linear-gradient(180deg, #2a1f1a 0%, #3d2b22 60%, #4a342a 100%);
}
/* 料理の放つ熱気(暖色の光だまり、周期11sでゆっくり明滅) */
.heat-glow {
  position: absolute;
  left: 50%; bottom: -34px;
  width: 260px; height: 130px;
  margin-left: -130px;
  border-radius: 9999px;
  background: radial-gradient(ellipse,
    rgba(212, 165, 116, 0.14) 0%, rgba(212, 165, 116, 0) 70%);
  animation: heatGlow 11s ease-in-out infinite;
}
@keyframes heatGlow {
  0%, 100% { opacity: 0.5; }
  50%      { opacity: 1; }
}
/* 湯気グループ全体にfeTurbulenceの揺らぎを適用 */
.steam-group {
  position: absolute;
  inset: 0;
  filter: url(#steamWobble);
}
.bowl-svg { position: absolute; left: 50%; bottom: 2px; margin-left: -110px; }

/* 上昇レイヤー:上昇 + 拡散(scaleX拡大 + opacity漸減)。ease-outで立ち上がる */
.steam-rise {
  position: absolute;
  bottom: 60px;
  opacity: 0;
  animation: steamRise 6.5s ease-out infinite;
}
.s1 { left: calc(50% - 34px); animation-duration: 5s;   animation-delay: -1.5s; }
.s2 { left: calc(50% - 6px);  animation-duration: 6.5s; animation-delay: -3.2s; }
.s3 { left: calc(50% + 24px); animation-duration: 8s;   animation-delay: -5.6s; }
/* 根元は細く濃く、上昇するほど広がり薄まる(湯気の物理) */
@keyframes steamRise {
  0%   { transform: translateY(16px) scaleX(0.7); opacity: 0; }
  12%  { opacity: 0.9; }
  60%  { opacity: 0.4; }
  100% { transform: translateY(-88px) scaleX(1.8); opacity: 0; }
}
/* 蛇行レイヤー:横のゆらぎは筋ごとに別周期 */
.steam-sway { animation: steamSway 4.3s ease-in-out infinite; }
.sw1 { animation-duration: 3.7s; animation-delay: -0.7s; }
.sw2 { animation-duration: 4.3s; animation-delay: -1.9s; }
.sw3 { animation-duration: 5.3s; animation-delay: -3.1s; }
@keyframes steamSway {
  0%, 100% { transform: translateX(-6px); }
  50%      { transform: translateX(6px); }
}
/* 湯気の本体:下が透明→中央が白→上が透明の縦グラデーション帯 */
.steam-band {
  height: 90px;
  border-radius: 9999px;
  background: linear-gradient(0deg,
    rgba(255, 250, 240, 0) 0%, rgba(255, 250, 240, 0.5) 30%,
    rgba(255, 250, 240, 0.25) 70%, rgba(255, 250, 240, 0) 100%);
}
.b1 { width: 9px;  filter: blur(4px); }
.b2 { width: 13px; filter: blur(6px); }
.b3 { width: 8px;  filter: blur(5px); }
@media (prefers-reduced-motion: reduce) {
  .heat-glow, .steam-rise, .steam-sway { animation: none; }
}
📖 関連: フィルター(filter)

🎨 シズルの照り

📝 表現の語彙

日本語: シズル感、照り、ツヤ、光が走る、てかり
英語: sizzle, glossy sheen, light sweep, glaze
抽象キーワード: juiciness, temptation, richness

💬 AIへの指示テンプレ

「料理の照り(シズル感)を抽象的に表現してください。照り焼き色のradial-gradient球体(光源は左上)に、2層のハイライトを重ねます: ①左上の固定ハイライト(静止) ②球面を斜めに横切る流れる光の帯(mix-blend-mode: overlay、clip-pathで球内にマスク)。重要: 帯は常時流さず『2.5秒流れて4.5秒静止』のリズムにしてください。時々キラッと光るのが高級感の鍵です。」

🎯 似合うシーン

焼肉/うなぎ/照り焼き系・スイーツ(チョコ・飴がけ)・高級レストラン・食品EC商品画像の演出

🔧 実装手法

光源グラデ+固定ハイライト+皿の照り返し+接触陰影の4層で球を立体化 + clipPathマスクの流れる光(「流れ→静止」の間欠リズム、mix-blend-mode: overlay)

📄 コード例を見る
html
<div class="sizzle-stage">
  <!-- みたらし団子の串。各球は「光源グラデ+固定ハイライト+照り返し+接触陰影」の4層で立体に -->
  <svg class="dango-svg" viewBox="0 0 280 170" width="280" height="170">
    <defs>
      <!-- グレーズ:光源を左上に想定した5段グラデ -->
      <radialGradient id="glaze" cx="36%" cy="28%" r="75%">
        <stop offset="0%" stop-color="#eda44d" />
        <stop offset="20%" stop-color="#cd7a2b" />
        <stop offset="48%" stop-color="#a8551b" />
        <stop offset="78%" stop-color="#743610" />
        <stop offset="100%" stop-color="#521d07" />
      </radialGradient>
      <linearGradient id="stick" x1="0" y1="0" x2="0" y2="1">
        <stop offset="0%" stop-color="#d8b07c" />
        <stop offset="100%" stop-color="#8f6a3c" />
      </linearGradient>
      <radialGradient id="plateSheen" cx="50%" cy="50%" r="50%">
        <stop offset="0%" stop-color="#3f2412" />
        <stop offset="100%" stop-color="rgba(63,36,18,0)" />
      </radialGradient>
      <radialGradient id="dangoShadow" cx="50%" cy="50%" r="50%">
        <stop offset="0%" stop-color="rgba(0,0,0,0.5)" />
        <stop offset="70%" stop-color="rgba(0,0,0,0)" />
      </radialGradient>
      <!-- 皿からの照り返し(バウンスライト)。球の下面に置くと一気に立体になる -->
      <radialGradient id="bounce" cx="50%" cy="50%" r="50%">
        <stop offset="0%" stop-color="rgba(236,150,70,0.4)" />
        <stop offset="100%" stop-color="rgba(236,150,70,0)" />
      </radialGradient>
      <linearGradient id="sweepGrad" x1="0" y1="0" x2="1" y2="0">
        <stop offset="0%" stop-color="rgba(255,255,255,0)" />
        <stop offset="50%" stop-color="rgba(255,255,255,0.85)" />
        <stop offset="100%" stop-color="rgba(255,255,255,0)" />
      </linearGradient>
      <!-- ハイライトは輪郭を持たせず、中心から溶けるグラデで -->
      <radialGradient id="spec" cx="50%" cy="50%" r="50%">
        <stop offset="0%" stop-color="rgba(255,255,255,0.85)" />
        <stop offset="55%" stop-color="rgba(255,255,255,0.28)" />
        <stop offset="100%" stop-color="rgba(255,255,255,0)" />
      </radialGradient>
      <!-- 接触陰影:わずかに陰る程度のフェード -->
      <radialGradient id="contact" cx="50%" cy="50%" r="50%">
        <stop offset="0%" stop-color="rgba(0,0,0,0.18)" />
        <stop offset="100%" stop-color="rgba(0,0,0,0)" />
      </radialGradient>
      <!-- 流れる光は団子3球の形にクリップ -->
      <clipPath id="dangoClip">
        <circle cx="92" cy="86" r="28" />
        <circle cx="140" cy="80" r="30" />
        <circle cx="188" cy="86" r="28" />
      </clipPath>
    </defs>
    <!-- 皿と影 -->
    <ellipse cx="140" cy="132" rx="96" ry="16" fill="#1e1109" />
    <ellipse cx="140" cy="130" rx="84" ry="12" fill="url(#plateSheen)" />
    <path d="M52 136 Q140 152 228 136" stroke="#5f3a1e" stroke-width="1.5" opacity="0.5" fill="none" />
    <ellipse cx="140" cy="122" rx="70" ry="9" fill="url(#dangoShadow)" />
    <!-- タレだまり -->
    <ellipse cx="142" cy="121" rx="24" ry="4.5" fill="#5a2c0c" opacity="0.85" />
    <ellipse cx="136" cy="120" rx="9" ry="1.6" fill="#a8662a" opacity="0.6" />
    <!-- 串 -->
    <polygon points="40,84 26,87 40,90" fill="#c9a268" />
    <rect x="38" y="84" width="212" height="5" rx="2.5" fill="url(#stick)" />
    <!-- 団子3球(中央をひと回り大きく、わずかに高く) -->
    <circle cx="92" cy="86" r="28" fill="url(#glaze)" />
    <circle cx="188" cy="86" r="28" fill="url(#glaze)" />
    <circle cx="140" cy="80" r="30" fill="url(#glaze)" />
    <!-- 球同士の接触陰影(オクルージョン) -->
    <ellipse cx="116" cy="84" rx="7" ry="15" fill="url(#contact)" />
    <ellipse cx="164" cy="84" rx="7" ry="15" fill="url(#contact)" />
    <!-- 皿からの照り返し -->
    <ellipse cx="92" cy="103" rx="16" ry="6" fill="url(#bounce)" />
    <ellipse cx="140" cy="99" rx="18" ry="6.5" fill="url(#bounce)" />
    <ellipse cx="188" cy="103" rx="16" ry="6" fill="url(#bounce)" />
    <!-- タレの滴り -->
    <path d="M138 108 q-1.5 9 0.5 14 q1.5 3.5 3 0 q1 -7 -1 -14 z" fill="#6e3a10" />
    <path d="M139.5 110 q-0.5 6 0.5 10" stroke="rgba(255,255,255,0.3)" stroke-width="0.8" fill="none" />
    <!-- ①固定ハイライト:芯 + 柔らかい広がりの2段(どちらも輪郭なし) -->
    <ellipse cx="83" cy="74" rx="9" ry="5.5" fill="url(#spec)" transform="rotate(-22 83 74)" />
    <ellipse cx="86" cy="78" rx="17" ry="11" fill="url(#spec)" opacity="0.4" transform="rotate(-22 86 78)" />
    <ellipse cx="130" cy="67" rx="9.5" ry="6" fill="url(#spec)" transform="rotate(-22 130 67)" />
    <ellipse cx="133" cy="71" rx="18" ry="11.5" fill="url(#spec)" opacity="0.4" transform="rotate(-22 133 71)" />
    <ellipse cx="179" cy="74" rx="9" ry="5.5" fill="url(#spec)" transform="rotate(-22 179 74)" />
    <ellipse cx="182" cy="78" rx="17" ry="11" fill="url(#spec)" opacity="0.4" transform="rotate(-22 182 78)" />
    <!-- ②流れるハイライト(間欠) -->
    <g clip-path="url(#dangoClip)">
      <rect class="dango-sweep" x="60" y="28" width="24" height="120" fill="url(#sweepGrad)" />
    </g>
  </svg>
  <!-- 焼きたての温度感:立ち上る熱気の微粒 -->
  <div class="heat-mote m1"></div>
  <div class="heat-mote m2"></div>
  <div class="heat-mote m3"></div>
</div>
css
.sizzle-stage {
  position: relative;
  height: 180px;
  border-radius: 8px;
  overflow: hidden;
  /* 温かい暗褐色のスポットライト感 */
  background: radial-gradient(ellipse at 50% 40%, #4a2c1a 0%, #2d1a0e 70%);
}
.dango-svg {
  position: absolute;
  left: 50%; top: 50%;
  margin: -85px 0 0 -140px;
}
/* ②流れるハイライト:duration 7s = 流れ約2.5s + 静止4.5s。
   常時流さず「時々キラッ」が高級感 */
.dango-sweep {
  transform-box: fill-box;
  mix-blend-mode: overlay;
  filter: blur(2px);
  opacity: 0;
  animation: sheenSweep 7s ease-in-out infinite;
}
@keyframes sheenSweep {
  0%   { transform: translateX(-60px) rotate(25deg); opacity: 0; }
  8%   { opacity: 1; }
  35%  { transform: translateX(170px) rotate(25deg); opacity: 0; }
  100% { transform: translateX(170px) rotate(25deg); opacity: 0; } /* 残りは静止 */
}
/* 熱気の微粒:団子の上からゆっくり上昇して消える */
.heat-mote {
  position: absolute;
  width: 4px; height: 4px;
  border-radius: 9999px;
  background: rgba(255, 240, 220, 0.8);
  filter: blur(2px);
  opacity: 0;
  animation: moteRise 7.1s ease-out infinite;
}
.m1 { left: calc(50% - 20px); top: 36px; animation-duration: 5.3s; animation-delay: -1.2s; }
.m2 { left: calc(50% + 2px);  top: 30px; animation-duration: 7.1s; animation-delay: -3.8s; }
.m3 { left: calc(50% + 22px); top: 40px; animation-duration: 9.7s; animation-delay: -6.4s; }
@keyframes moteRise {
  0%   { transform: translateY(0); opacity: 0; }
  15%  { opacity: 0.7; }
  100% { transform: translateY(-34px); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .dango-sweep, .heat-mote { animation: none; }
}
📖 関連: グラデーション

🎨 満ちるドリンク

📝 表現の語彙

日本語: 注がれる、満ちる、液面が上がる、ドリンクが注がれる
英語: filling glass, pouring drink, rising liquid
抽象キーワード: anticipation, refreshment, generosity

💬 AIへの指示テンプレ

「グラスに琥珀色のドリンクが満ちるアニメーションを作ってください。グラスはSVGの台形輪郭、液体はclip-pathでグラス内に収めた矩形で、14秒周期で『満ちる(ease-in-out)→保持→引く』をループします。重要: 液面は水平線ではなく、わずかに傾き揺れる楕円にしてください(rotate±1.5deg、周期2.3秒)。液中から小さな泡が上昇するアクセントも加えます。色は午後のカフェのような暖かい背景に琥珀の液体で。」

🎯 似合うシーン

カフェ・バー・クラフトビール・ジュース/スムージー店・ドリンクメニューページ

🔧 実装手法

clip-pathの液体 + 楕円液面のrotate揺れ + 満ち/保持/引きの3フェーズループ + 開口部の楕円・結露・伝う雫・光だまりの描き込みで奥行きと冷たさを出す

📄 コード例を見る
html
<div class="drink-stage">
  <div class="window-light"></div>
  <div class="glass-shadow"></div>
  <div class="caustic"></div> <!-- グラス越しの光だまり(テーブルの上) -->
  <div class="glass-wrap">
    <!-- グラス内側にclip-pathで液体を収める -->
    <div class="glass-fill-area">
      <div class="liquid">
        <div class="liquid-surface"></div> <!-- 揺れる液面(楕円) -->
        <div class="bubble bb1"></div>
        <div class="bubble bb2"></div>
        <div class="bubble bb3"></div>
        <div class="bubble bb4"></div>
        <div class="bubble bb5"></div>
      </div>
    </div>
    <!-- グラス:楕円の開口部で奥行きを出し、結露・レモンを描き込む -->
    <svg class="glass-svg" viewBox="0 0 100 140" width="100" height="140">
      <defs>
        <radialGradient id="dropGrad" cx="35%" cy="30%" r="70%">
          <stop offset="0%" stop-color="rgba(255,255,255,0.8)" />
          <stop offset="60%" stop-color="rgba(255,255,255,0.25)" />
          <stop offset="100%" stop-color="rgba(255,255,255,0)" />
        </radialGradient>
      </defs>
      <!-- 胴(前面の壁) -->
      <path d="M12 10 C13 55 18 108 24 126 Q50 134 76 126 C82 108 87 55 88 10 Q50 17 12 10 Z"
        fill="rgba(255,255,255,0.16)" stroke="#9c8a72" stroke-width="2" stroke-linecap="round" />
      <!-- 開口部の楕円:これがあるだけで平面が立体になる -->
      <ellipse cx="50" cy="10" rx="38" ry="6.5"
        fill="rgba(255,255,255,0.1)" stroke="#b9a88e" stroke-width="1.5" opacity="0.9" />
      <path d="M12 10 Q50 17.5 88 10" stroke="rgba(255,255,255,0.7)" stroke-width="1.2" opacity="0.6" fill="none" />
      <!-- ガラスの反射(左が強く右は弱く) -->
      <path d="M21 24 C21 62 25 104 29 118" stroke="#ffffff" stroke-width="3.5" opacity="0.5" fill="none" stroke-linecap="round" />
      <path d="M80 24 C80 62 76 104 73 118" stroke="#ffffff" stroke-width="1.5" opacity="0.25" fill="none" stroke-linecap="round" />
      <path d="M26 122 Q50 129 74 122" stroke="rgba(255,255,255,0.45)" stroke-width="1.5" fill="none" />
      <!-- 結露の水滴(冷たさの記号。下半分に散らす) -->
      <circle cx="18" cy="78" r="1.6" fill="url(#dropGrad)" />
      <circle cx="23" cy="95" r="1.2" fill="url(#dropGrad)" />
      <circle cx="30" cy="108" r="1.8" fill="url(#dropGrad)" />
      <circle cx="15" cy="60" r="1.1" fill="url(#dropGrad)" />
      <circle cx="82" cy="70" r="1.5" fill="url(#dropGrad)" />
      <circle cx="81" cy="82" r="2.2" fill="url(#dropGrad)" />
      <circle cx="78" cy="92" r="1.9" fill="url(#dropGrad)" />
      <circle cx="84" cy="104" r="1.2" fill="url(#dropGrad)" />
      <circle cx="74" cy="112" r="1.4" fill="url(#dropGrad)" />
      <circle cx="20" cy="118" r="1.3" fill="url(#dropGrad)" />
      <!-- レモンスライス -->
      <g transform="translate(80,12) rotate(18)">
        <circle r="12.5" fill="#f6d44d" stroke="#e3ad26" stroke-width="1" />
        <circle r="10" fill="#fcf0a4" />
        <ellipse cy="-5.4" rx="2.9" ry="5.6" fill="#f3c93e" opacity="0.85" />
        <ellipse cy="-5.4" rx="2.9" ry="5.6" fill="#f3c93e" opacity="0.85" transform="rotate(60)" />
        <ellipse cy="-5.4" rx="2.9" ry="5.6" fill="#f3c93e" opacity="0.85" transform="rotate(120)" />
        <ellipse cy="-5.4" rx="2.9" ry="5.6" fill="#f3c93e" opacity="0.85" transform="rotate(180)" />
        <ellipse cy="-5.4" rx="2.9" ry="5.6" fill="#f3c93e" opacity="0.85" transform="rotate(240)" />
        <ellipse cy="-5.4" rx="2.9" ry="5.6" fill="#f3c93e" opacity="0.85" transform="rotate(300)" />
      </g>
    </svg>
    <div class="run-drop"></div> <!-- グラスを伝う雫 -->
  </div>
</div>
css
.drink-stage {
  position: relative;
  height: 180px;
  border-radius: 8px;
  overflow: hidden;
  /* 午後のカフェの暖かい光 */
  background: linear-gradient(180deg, #f5ead9 0%, #ecd9bd 100%);
}
/* 窓からの光の帯(静止。空気感を作る) */
.window-light {
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg,
    rgba(255,255,255,0) 30%, rgba(255,255,255,0.35) 46%, rgba(255,255,255,0) 62%);
}
.glass-wrap {
  position: absolute;
  left: 50%; top: 18px;
  width: 100px; height: 140px;
  margin-left: -50px;
}
.glass-svg { position: absolute; inset: 0; }
.glass-shadow {
  position: absolute;
  left: 50%; bottom: 28px;
  width: 116px; height: 12px;
  margin-left: -58px;
  border-radius: 9999px;
  background: rgba(155, 125, 90, 0.35);
  filter: blur(4px);
}
/* グラス越しにテーブルへ落ちる琥珀の光だまり */
.caustic {
  position: absolute;
  left: 50%; bottom: 24px;
  width: 90px; height: 26px;
  margin-left: 8px;
  border-radius: 9999px;
  background: radial-gradient(ellipse,
    rgba(240, 185, 106, 0.45) 0%, rgba(240, 185, 106, 0) 70%);
  filter: blur(3px);
  animation: causticPulse 13s ease-in-out infinite;
}
@keyframes causticPulse {
  0%, 100% { opacity: 0.4; }
  50%      { opacity: 1; }
}
/* グラス内側の形にクリップ */
.glass-fill-area {
  position: absolute;
  inset: 0;
  clip-path: polygon(14% 8%, 86% 8%, 76% 90%, 24% 90%);
}
/* 琥珀・アイスティーの色。14秒周期で「満ちる→保持→引く」 */
.liquid {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, #e09b3f 0%, #c1761f 55%, #a85c14 100%);
  opacity: 0.88;
  transform: translateY(100%);
  animation: pour 14s ease-in-out infinite;
}
@keyframes pour {
  0%   { transform: translateY(100%); } /* 空 */
  45%  { transform: translateY(26%); }  /* 満ちる(ease-in-out) */
  75%  { transform: translateY(26%); }  /* 保持 */
  100% { transform: translateY(100%); } /* 引く */
}
/* 液面:水平な直線ではなく、わずかに傾き揺れる楕円(液体の本物感の主役) */
.liquid-surface {
  position: absolute;
  top: -6px; left: -6%;
  width: 112%; height: 14px;
  border-radius: 9999px;
  background: #e8a94e;
  animation: surfaceSway 2.3s ease-in-out infinite;
}
@keyframes surfaceSway {
  0%, 100% { transform: rotate(-1.5deg) translateY(0); }
  50%      { transform: rotate(1.5deg) translateY(-1px); }
}
/* 液中の泡:上昇 + 横揺れの2軸 */
.bubble {
  position: absolute;
  bottom: 8px;
  border-radius: 9999px;
  background: radial-gradient(circle at 35% 35%,
    rgba(255,255,255,0.9) 0%, rgba(255,255,255,0.2) 70%, rgba(255,255,255,0) 100%);
  opacity: 0;
  animation: bubbleUp 4.3s ease-in-out infinite;
}
.bb1 { left: 18%; width: 5px; height: 5px; animation-duration: 3.1s; animation-delay: -0.4s; }
.bb2 { left: 64%; width: 7px; height: 7px; animation-duration: 4.3s; animation-delay: -1.8s; }
.bb3 { left: 38%; width: 4px; height: 4px; animation-duration: 5.3s; animation-delay: -2.6s; }
.bb4 { left: 80%; width: 5px; height: 5px; animation-duration: 6.1s; animation-delay: -3.9s; }
.bb5 { left: 52%; width: 6px; height: 6px; animation-duration: 3.7s; animation-delay: -1.1s; }
@keyframes bubbleUp {
  0%   { transform: translate(0, 0); opacity: 0; }
  12%  { opacity: 0.8; }
  50%  { transform: translate(3px, -46px); }
  90%  { opacity: 0.6; }
  100% { transform: translate(-2px, -90px); opacity: 0; }
}
/* 結露が時々ひと粒、グラスを伝い落ちる(冷たさの決定打) */
.run-drop {
  position: absolute;
  left: 20%; top: 16%;
  width: 4px; height: 7px;
  border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
  background: rgba(255, 255, 255, 0.55);
  opacity: 0;
  animation: runDown 11s ease-in infinite;
}
@keyframes runDown {
  0%, 54% { transform: translateY(0); opacity: 0; }
  58%  { opacity: 0.7; }
  86%  { opacity: 0.5; }
  100% { transform: translateY(82px); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .liquid, .liquid-surface, .bubble, .caustic, .run-drop { animation: none; }
}
📖 関連: キーフレームアニメーション

🎨 食欲をそそる暖色のゆらめき

📝 表現の語彙

日本語: 暖色のゆらめき、食欲色、炎の気配、温かい光
英語: warm glow, appetizing ambience, flickering warmth
抽象キーワード: appetite, coziness, invitation

💬 AIへの指示テンプレ

「炭火焼きの店の壁に映る火明かりのような、暖色のゆらめき背景を作ってください。深い炭火色のグラデーションベースに、radial-gradientの光レイヤーを3層重ねます。重要: 3層の周期を『遅い大波7秒・中間2.3秒・細かいチラつき0.9秒』と大きく変え、keyframesの中間点も不均等に置いて、炎特有の予測できない明滅(1/fゆらぎ風)にしてください。小さな火の粉が下から上昇して消えるアクセントも加えます。」

🎯 似合うシーン

焼肉/焼き鳥/炉端焼き・居酒屋・BBQ・冬の鍋キャンペーン・燻製/クラフト系食品ブランド

🔧 実装手法

3層radial-gradientの異周期明滅(7s/2.3s/0.9s = 1/fゆらぎ近似)+ 強blurの火柱(scaleY伸縮+skewX揺らぎ)+ 網下で明滅する熾火・肉串の情景SVG + 火の粉と煙の上昇

📄 コード例を見る
tsx
// 火の粉5個。擬似乱数((i * 7919) % 100 方式)で周期・位置・揺れ幅をバラす
const SPARK_COLORS = ["#fde68a", "#fb923c", "#fcd34d", "#fdba74", "#fde68a"];
const sparks = Array.from({ length: 5 }, (_, i) => {
  const j1 = ((i * 7919) % 100) / 100;
  const j2 = ((i * 104729) % 100) / 100;
  return {
    left: 10 + ((i * 41) % 80),        // % 不等間隔
    size: 2 + j1 * 1.5,                // 2〜3.5px
    color: SPARK_COLORS[i],
    dur: 5 + j1 * 6,                   // 5〜11s
    delay: -(j2 * 9),
    sway: (j2 > 0.5 ? 1 : -1) * (6 + j1 * 10), // 横揺れ幅 ±6〜16px
  };
});

<div className="ember-stage">
  {/* 3層の異周期ゆらめき(7s / 2.3s / 0.9s = 1/fゆらぎの近似) */}
  <div className="flicker-slow" />
  <div className="flicker-mid" />
  <div className="flicker-fast" />
  {/* ぼんやりした火柱:強blurの光柱が伸び縮み・揺らぎながら立ち上る */}
  <div className="flame fl1" />
  <div className="flame fl2" />
  <div className="flame fl3" />
  {/* 立ち上る煙(湯気の超低opacity版) */}
  <div className="smoke sm1" />
  <div className="smoke sm2" />
  {sparks.map((s, i) => (
    <div key={i} className="spark"
      style={{ left: `${s.left}%`, width: s.size, height: s.size,
        background: s.color, animationDuration: `${s.dur}s`,
        animationDelay: `${s.delay}s`, "--sx": `${s.sway}px` }} />
  ))}
  {/* 足元を暗く沈め、熾火の光を主役にする */}
  <div className="hearth-dark" />
  {/* 網・熾火・肉串の情景。炭はradialグラデを別周期で明滅させる */}
  <svg className="grill-svg" viewBox="0 0 420 72" width={420} height={72}>
    <defs>
      <radialGradient id="coal" cx="50%" cy="50%" r="50%">
        <stop offset="0%" stopColor="#ffc06a" />
        <stop offset="22%" stopColor="#ff8424" />
        <stop offset="55%" stopColor="#d24a0e" />
        <stop offset="100%" stopColor="rgba(124,45,18,0)" />
      </radialGradient>
      <linearGradient id="meat" x1="0" y1="0" x2="0" y2="1">
        <stop offset="0%" stopColor="#b06334" />
        <stop offset="45%" stopColor="#7a3d1c" />
        <stop offset="100%" stopColor="#46200d" />
      </linearGradient>
      <linearGradient id="stick4" x1="0" y1="0" x2="0" y2="1">
        <stop offset="0%" stopColor="#d3aa72" />
        <stop offset="100%" stopColor="#8f6a3c" />
      </linearGradient>
    </defs>
    {/* 熾火(網の下で明滅) */}
    <ellipse className="coal c1" cx={92}  cy={62} rx={34} ry={11} fill="url(#coal)" />
    <ellipse className="coal c2" cx={176} cy={64} rx={28} ry={10} fill="url(#coal)" />
    <ellipse className="coal c3" cx={252} cy={62} rx={32} ry={11} fill="url(#coal)" />
    <ellipse className="coal c4" cx={330} cy={64} rx={26} ry={9}  fill="url(#coal)" />
    {/* 網(手前ほど太く=遠近) */}
    <rect x={0} y={44} width={420} height={3}   rx={1.5}  fill="#190b04" opacity={0.92} />
    <rect x={0} y={52} width={420} height={3.5} rx={1.75} fill="#150904" opacity={0.95} />
    <rect x={0} y={61} width={420} height={4}   rx={2}    fill="#120703" />
    {/* 肉串A:焼き色グラデ+焦げ目+脂の glint */}
    <g transform="translate(64,18)">
      <polygon points="0,12 -12,14.5 0,17" fill="#caa168" />
      <rect x={0} y={12} width={160} height={4.5} rx={2.25} fill="url(#stick4)" />
      <rect x={16} y={-4} width={36} height={28} rx={9} fill="url(#meat)" />
      <rect x={18} y={18} width={32} height={5} rx={2.5} fill="#240f06" opacity={0.85} />
      <ellipse cx={28} cy={4} rx={4} ry={2.4} fill="#2e1408" opacity={0.7} />
      <ellipse cx={26} cy={0} rx={4.5} ry={1.8} fill="#ffd9a0" opacity={0.4} />
      <rect x={60} y={-3} width={32} height={26} rx={8} fill="url(#meat)" />
      <rect x={62} y={17} width={28} height={5} rx={2.5} fill="#240f06" opacity={0.85} />
      <ellipse cx={78} cy={3} rx={3.5} ry={2} fill="#2e1408" opacity={0.6} />
      <ellipse cx={70} cy={0} rx={4} ry={1.6} fill="#ffd9a0" opacity={0.35} />
      <rect x={100} y={-4} width={37} height={27} rx={9} fill="url(#meat)" />
      <rect x={102} y={17} width={33} height={5} rx={2.5} fill="#240f06" opacity={0.85} />
      <ellipse cx={114} cy={3} rx={4} ry={2.2} fill="#2e1408" opacity={0.7} />
      <ellipse cx={111} cy={-1} rx={4.5} ry={1.8} fill="#ffd9a0" opacity={0.4} />
    </g>
    {/* 肉串B(奥・小さめ) */}
    <g transform="translate(232,30)">
      <polygon points="0,10 -10,12 0,14" fill="#caa168" />
      <rect x={0} y={10} width={150} height={4} rx={2} fill="url(#stick4)" />
      <rect x={14} y={-2} width={30} height={24} rx={8} fill="url(#meat)" />
      <rect x={16} y={17} width={26} height={4.5} rx={2.25} fill="#240f06" opacity={0.85} />
      <ellipse cx={24} cy={3} rx={3.5} ry={2} fill="#2e1408" opacity={0.65} />
      <rect x={52} y={-1} width={27} height={22} rx={7} fill="url(#meat)" />
      <rect x={54} y={16} width={23} height={4.5} rx={2.25} fill="#240f06" opacity={0.85} />
      <ellipse cx={62} cy={2} rx={3} ry={1.8} fill="#2e1408" opacity={0.6} />
      <rect x={88} y={-2} width={31} height={23} rx={8} fill="url(#meat)" />
      <rect x={90} y={16} width={27} height={4.5} rx={2.25} fill="#240f06" opacity={0.85} />
      <ellipse cx={100} cy={2} rx={3.5} ry={2} fill="#2e1408" opacity={0.65} />
    </g>
  </svg>
</div>
css
.ember-stage {
  position: relative;
  height: 180px;
  border-radius: 8px;
  overflow: hidden;
  /* 深い炭火色→明るいオレンジ */
  background: linear-gradient(160deg,
    #7c2d12 0%, #9a3412 30%, #c2410c 60%, #ea580c 100%);
}
/* 遅い大波(周期7s・振幅大)。keyframesの中間点を不均等に置いて不規則に */
.flicker-slow {
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 18% 88%,
    rgba(253, 186, 116, 0.25) 0%, rgba(253, 186, 116, 0) 60%);
  animation: flickerSlow 7s ease-in-out infinite;
}
@keyframes flickerSlow {
  0%   { opacity: 0.2; }
  23%  { opacity: 1; }
  61%  { opacity: 0.45; }
  100% { opacity: 0.2; }
}
/* 中間の揺らぎ(周期2.3s・振幅中) */
.flicker-mid {
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 82% 92%,
    rgba(251, 146, 60, 0.2) 0%, rgba(251, 146, 60, 0) 55%);
  animation: flickerMid 2.3s ease-in-out infinite;
}
@keyframes flickerMid {
  0%   { opacity: 0.25; }
  31%  { opacity: 1; }
  64%  { opacity: 0.5; }
  100% { opacity: 0.25; }
}
/* 細かいチラつき(周期0.9s・振幅ごく小) */
.flicker-fast {
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 55% 80%,
    rgba(254, 215, 170, 0.12) 0%, rgba(254, 215, 170, 0) 45%);
  animation: flickerFast 0.9s ease-in-out infinite;
}
@keyframes flickerFast {
  0%   { opacity: 0.3; }
  27%  { opacity: 1; }
  58%  { opacity: 0.55; }
  100% { opacity: 0.3; }
}
/* ぼんやりした火柱:根元固定のscaleY伸縮 + skewXの揺らぎ + 不均等な明滅。
   強いblurで「炎そのもの」ではなく「炎の気配」に留める */
.flame {
  position: absolute;
  bottom: 30px;
  border-radius: 9999px;
  background: radial-gradient(ellipse at 50% 85%,
    rgba(255, 166, 77, 0.55) 0%, rgba(255, 120, 40, 0.28) 45%, rgba(255, 120, 40, 0) 75%);
  filter: blur(14px);
  transform-origin: bottom center;
  animation: flameWaver 4.7s ease-in-out infinite;
}
.fl1 { left: 14%; width: 70px; height: 130px; animation-duration: 4.1s; animation-delay: -1.3s; }
.fl2 { left: 42%; width: 92px; height: 152px; animation-duration: 5.3s; animation-delay: -2.8s; }
.fl3 { left: 70%; width: 62px; height: 116px; animation-duration: 3.7s; animation-delay: -0.6s; }
@keyframes flameWaver {
  0%   { transform: scaleY(0.86) skewX(0deg);    opacity: 0.55; }
  19%  { transform: scaleY(1.06) skewX(2.5deg);  opacity: 0.9; }
  43%  { transform: scaleY(0.92) skewX(-2deg);   opacity: 0.65; }
  66%  { transform: scaleY(1.12) skewX(1.5deg);  opacity: 1; }
  84%  { transform: scaleY(0.95) skewX(-2.5deg); opacity: 0.7; }
  100% { transform: scaleY(0.86) skewX(0deg);    opacity: 0.55; }
}
/* 炉の足元:下を暗く沈めると熾火の光が主役になる */
.hearth-dark {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 78px;
  background: linear-gradient(0deg,
    rgba(18, 7, 2, 0.92) 0%, rgba(18, 7, 2, 0.55) 45%, rgba(18, 7, 2, 0) 100%);
}
/* 熾火の明滅:層の周期と重ならない素数的periodでバラす */
.coal {
  transform-box: fill-box;
  animation: coalPulse 3.7s ease-in-out infinite;
}
.c1 { animation-duration: 2.7s; animation-delay: -0.9s; }
.c2 { animation-duration: 3.7s; animation-delay: -1.7s; }
.c3 { animation-duration: 3.1s; animation-delay: -0.4s; }
.c4 { animation-duration: 4.3s; animation-delay: -2.2s; }
@keyframes coalPulse {
  0%   { opacity: 0.55; }
  29%  { opacity: 1; }
  63%  { opacity: 0.7; }
  100% { opacity: 0.55; }
}
/* 肉から立ち上る煙(ごく薄く) */
.smoke {
  position: absolute;
  bottom: 44px;
  width: 10px; height: 70px;
  border-radius: 9999px;
  background: linear-gradient(0deg,
    rgba(255, 245, 235, 0) 0%, rgba(255, 245, 235, 0.3) 35%,
    rgba(255, 245, 235, 0.12) 70%, rgba(255, 245, 235, 0) 100%);
  filter: blur(5px);
  opacity: 0;
  animation: smokeRise 7.3s ease-out infinite;
}
.sm1 { left: calc(50% - 96px); animation-duration: 7.3s; animation-delay: -2.4s; }
.sm2 { left: calc(50% + 64px); animation-duration: 9.1s; animation-delay: -5.2s; }
@keyframes smokeRise {
  0%   { transform: translateY(10px) scaleX(0.8); opacity: 0; }
  15%  { opacity: 0.5; }
  100% { transform: translateY(-62px) scaleX(1.6); opacity: 0; }
}
/* 火の粉:熱気でease-out上昇し、左右に揺れて上半分で消える */
.spark {
  position: absolute;
  bottom: 0;
  border-radius: 9999px;
  filter: blur(1px);
  opacity: 0;
  animation: sparkRise 8s ease-out infinite;
}
@keyframes sparkRise {
  0%   { transform: translate(0, 10px); opacity: 0; }
  8%   { opacity: 0.9; }
  60%  { transform: translate(var(--sx), -64px); opacity: 0.5; }
  100% { transform: translate(calc(var(--sx) * -0.6), -112px); opacity: 0; }
}
.grill-svg { position: absolute; left: 50%; bottom: 0; margin-left: -210px; }
@media (prefers-reduced-motion: reduce) {
  .flicker-slow, .flicker-mid, .flicker-fast, .flame, .spark, .coal, .smoke { animation: none; }
}
📖 関連: 透明度(opacity)

よくある質問

料理写真がある場合、これらの表現はどう組み合わせる?

写真を主役に、表現は脇役として重ねるのが鉄則。たとえば料理写真の上端に湯気を1〜2筋(opacity控えめ)、写真の縁に暖色のゆらめきを薄く、など「写真の温度感を1段上げる」使い方が効果的です。表現が写真より目立つと逆効果になります。

湯気のfeTurbulenceが重い場合の代替は?

feTurbulenceを外し、「上昇+蛇行+拡散」の3軸合成だけでも十分湯気らしく見えます。蛇行の周期を筋ごとに変えることが揺らぎ感の本体で、フィルターは仕上げの一手です。モバイルではメディアクエリでフィルターを無効化する分岐も有効です。

「美味しそうな色」はどう選ぶ?

暖色(赤・オレンジ・琥珀・焼き色の茶)が食欲の基本。逆に青系は食欲減退色とされるため、料理の近くでは避けます。背景を深い暖色(焙煎色・炭火色)にすると、料理写真や湯気の白が引き立ちます。彩度は高すぎると安っぽくなるため、深み(暗さ)のある暖色が高級感の鍵です。

AIに料理サイトの演出を頼むときのコツは?

「美味しそうに」「シズル感を出して」だけでは再現性が低いです。本ページの表現名+数値(「湯気3筋、周期5〜8秒でバラして」「ハイライトは2.5秒流れて4.5秒静止」)で指示すると精度が上がります。また「写真より目立たないopacityで」と従属関係を明示するのも重要です。