{
 "name": "WazaScout",
 "description": "HTML表現の手数カタログ（スライド/LP/Webサイト制作用）",
 "updated": "2026-08-11",
 "categories": [
  {
   "key": "scroll",
   "label": "スクロール演出",
   "count": 22
  },
  {
   "key": "text",
   "label": "文字・タイポ演出",
   "count": 38
  },
  {
   "key": "layout",
   "label": "レイアウト設計",
   "count": 31
  },
  {
   "key": "shape",
   "label": "図形・マスク・切り抜き",
   "count": 21
  },
  {
   "key": "motion",
   "label": "アニメーション基礎",
   "count": 23
  },
  {
   "key": "interact",
   "label": "インタラクション・UI操作",
   "count": 26
  },
  {
   "key": "depth",
   "label": "3D・奥行き",
   "count": 19
  },
  {
   "key": "background",
   "label": "背景・雰囲気",
   "count": 27
  },
  {
   "key": "component",
   "label": "UI部品・コンポーネント",
   "count": 38
  },
  {
   "key": "svgfx",
   "label": "SVG表現",
   "count": 47
  },
  {
   "key": "slide",
   "label": "スライド特化",
   "count": 18
  },
  {
   "key": "media",
   "label": "画像・動画",
   "count": 21
  }
 ],
 "useFor": [
  {
   "key": "slide",
   "label": "スライド",
   "count": 120
  },
  {
   "key": "lp",
   "label": "LP",
   "count": 299
  },
  {
   "key": "site",
   "label": "Webサイト",
   "count": 292
  }
 ],
 "entries": [
  {
   "id": "scroll-snap",
   "num": "W-001",
   "name": "CSS Scroll Snap",
   "nameJa": "スクロール吸着",
   "category": "scroll",
   "description": "スクロールを離すと最寄りの要素にピタッと止まる表現。親要素に scroll-snap-type: x mandatory、子要素に scroll-snap-align: center を指定するだけでJS不要で実装できる。",
   "useCase": "カルーセルやフルスクリーンの章送りスライド、LPのセクション送りで、スクロール位置を毎回ジャストな位置に揃えたいときに使う。",
   "code": ".snap-track{\n  display:flex;\n  overflow-x:auto;\n  scroll-snap-type:x mandatory;\n}\n.snap-track>*{\n  flex:0 0 100%;\n  scroll-snap-align:center;\n}",
   "tags": [
    "CSS",
    "スクロール",
    "カルーセル",
    "レイアウト",
    "ぬるっと",
    "スパッと決まる",
    "没入感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"スクロール吸着のデモ\"><style>.ssnp-track{animation:ssnp-move 4.5s cubic-bezier(.7,0,.2,1) infinite}@keyframes ssnp-move{0%,26%{transform:translateX(0)}36%,62%{transform:translateX(-80px)}72%,96%{transform:translateX(-160px)}100%{transform:translateX(0)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g class=\"ssnp-track\"><rect x=\"24\" y=\"32\" width=\"64\" height=\"86\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".9\"/><rect x=\"104\" y=\"32\" width=\"64\" height=\"86\" rx=\"6\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".55\"/><rect x=\"184\" y=\"32\" width=\"64\" height=\"86\" rx=\"6\" fill=\"var(--w-amber,#ffc857)\" opacity=\".8\"/></g><rect x=\"104\" y=\"126\" width=\"32\" height=\"4\" rx=\"2\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".35\"/></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "scroll-text-highlight",
    "carousel-scroll-snap",
    "vertical-scroll-snap",
    "smooth-scroll"
   ]
  },
  {
   "id": "scroll-driven-animation",
   "num": "W-002",
   "name": "Scroll-Driven Animation",
   "nameJa": "スクロール駆動アニメーション",
   "category": "scroll",
   "description": "スクロール量そのものをアニメの再生位置として使うネイティブ表現。animation-timeline: scroll() をCSSに紐付けるだけで、JS計算なしに進捗バーや伸縮演出を作れる。",
   "useCase": "読了プログレスバーやスクロール量に比例した図形の伸縮・回転など、JS計算なしでスクロール連動の動きを作りたい場面。",
   "code": "@keyframes sdrv-grow{ from{transform:scaleX(0)} to{transform:scaleX(1)} }\n.sdrv-bar{\n  transform-origin:left;\n  animation:sdrv-grow linear;\n  animation-timeline:scroll(root);\n}",
   "tags": [
    "CSS",
    "スクロール",
    "アニメーション",
    "進捗",
    "ぬるっと",
    "連動感",
    "最新仕様"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"スクロール駆動アニメーションのデモ\"><style>.sdrv-thumb{animation:sdrv-down 4s linear infinite}@keyframes sdrv-down{0%{transform:translateY(0)}100%{transform:translateY(84px)}}.sdrv-fill{animation:sdrv-grow 4s linear infinite;transform-origin:left}@keyframes sdrv-grow{0%{transform:scaleX(0)}100%{transform:scaleX(1)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"16\" y=\"20\" width=\"10\" height=\"100\" rx=\"5\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".3\"/><rect class=\"sdrv-thumb\" x=\"16\" y=\"20\" width=\"10\" height=\"26\" rx=\"5\" fill=\"var(--w-sub,#94a3c0)\"/><rect x=\"48\" y=\"24\" width=\"176\" height=\"10\" rx=\"5\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".25\"/><rect class=\"sdrv-fill\" x=\"48\" y=\"24\" width=\"176\" height=\"10\" rx=\"5\" fill=\"var(--w-accent,#4fe3c1)\"/><text x=\"48\" y=\"60\" font-family=\"ui-monospace,monospace\" font-size=\"10\" fill=\"var(--w-ink,#e8eef9)\">animation-timeline: scroll()</text><text x=\"48\" y=\"76\" font-family=\"ui-monospace,monospace\" font-size=\"10\" fill=\"var(--w-sub,#94a3c0)\">scroll量 = 再生位置</text></svg>",
   "useFor": [
    "lp"
   ],
   "weight": "脇役",
   "relatedIds": [
    "view-timeline-reveal",
    "scroll-text-highlight",
    "smooth-scroll",
    "scroll-snap"
   ]
  },
  {
   "id": "view-timeline-reveal",
   "num": "W-003",
   "name": "View Timeline Reveal",
   "nameJa": "ビュータイムライン出現",
   "category": "scroll",
   "description": "要素がビューポートに入ってから出るまでの通過区間を再生時間にするネイティブ演出。animation-timeline: view() を使い、IntersectionObserverなしで出現アニメを組める。",
   "useCase": "カード一覧やギャラリーを、スクロールに合わせて個別にふわっと出現させたいがJSを増やしたくない場面。",
   "code": "@keyframes vtln-in{ from{opacity:0; transform:translateY(30px)} to{opacity:1; transform:none} }\n.vtln-card{\n  animation:vtln-in linear both;\n  animation-timeline:view();\n  animation-range:entry 0% cover 40%;\n}",
   "tags": [
    "CSS",
    "スクロール",
    "アニメーション",
    "出現",
    "ふわっと",
    "軽快",
    "最新仕様"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ビュータイムライン出現のデモ\"><style>.vtln-frame{animation:vtln-pass 4.5s linear infinite}@keyframes vtln-pass{0%{transform:translateX(-70px)}100%{transform:translateX(240px)}}.vtln-card{animation:vtln-in 4.5s linear infinite}@keyframes vtln-in{0%,20%{opacity:0;transform:translateY(16px)}40%,60%{opacity:1;transform:translateY(0)}80%,100%{opacity:0;transform:translateY(16px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect class=\"vtln-card\" x=\"80\" y=\"50\" width=\"80\" height=\"60\" rx=\"8\" fill=\"var(--w-accent,#4fe3c1)\"/><rect class=\"vtln-frame\" y=\"20\" width=\"60\" height=\"110\" rx=\"6\" fill=\"none\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"2\" stroke-dasharray=\"4 3\"/></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "scroll-driven-animation",
    "scroll-reveal",
    "clip-path-reveal",
    "scroll-triggered-animation"
   ]
  },
  {
   "id": "sticky-position",
   "num": "W-004",
   "name": "Sticky Positioning",
   "nameJa": "スティッキー固定",
   "category": "scroll",
   "description": "指定した親の範囲内でスクロールしても要素がその場に貼り付いたように見える表現。position: sticky と top だけで実装でき、JSのscrollイベント監視は不要。",
   "useCase": "見出しの追従表示、サイドナビの固定、比較表の先頭列固定など、文脈を保ちながらスクロールさせたい場面。",
   "code": ".stky-heading{\n  position:sticky;\n  top:0;\n  background:var(--w-bg,#101830);\n}",
   "tags": [
    "CSS",
    "スクロール",
    "固定",
    "ナビゲーション",
    "追従感",
    "さりげない",
    "安心感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"スティッキー固定のデモ\"><style>.stky-content{animation:stky-scroll 4s ease-in-out infinite}@keyframes stky-scroll{0%,8%{transform:translateY(0)}50%,58%{transform:translateY(-60px)}100%{transform:translateY(0)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g class=\"stky-content\"><rect x=\"20\" y=\"40\" width=\"200\" height=\"16\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".4\"/><rect x=\"20\" y=\"64\" width=\"160\" height=\"10\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".3\"/><rect x=\"20\" y=\"82\" width=\"180\" height=\"10\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".3\"/><rect x=\"20\" y=\"100\" width=\"140\" height=\"10\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".3\"/><rect x=\"20\" y=\"118\" width=\"170\" height=\"10\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".3\"/></g><rect x=\"0\" y=\"18\" width=\"240\" height=\"26\" fill=\"var(--w-bg,#101830)\"/><rect x=\"20\" y=\"22\" width=\"90\" height=\"18\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\"/><text x=\"120\" y=\"35\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-ink,#e8eef9)\">sticky header</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "overscroll-behavior",
    "smooth-scroll",
    "sticky-header-shrink",
    "scroll-margin-padding"
   ]
  },
  {
   "id": "sticky-header-shrink",
   "num": "W-005",
   "name": "Sticky Header Shrink",
   "nameJa": "ヘッダー縮小演出",
   "category": "scroll",
   "description": "ページ上部から少しスクロールすると、ヘッダーが薄く小さく半透明に変わる表現。scroll判定で is-scrolled クラスを付け、padding や backdrop-filter を transition で変化させる。",
   "useCase": "サイト全体で常時表示するヘッダーを、コンテンツを邪魔せずブランドを見せ続けたいコーポレートサイトやLP。",
   "code": ".shsh-header{\n  padding:24px; transition:.3s;\n}\n.shsh-header.is-scrolled{\n  padding:10px;\n  background:color-mix(in srgb, var(--w-bg,#101830) 80%, transparent);\n  backdrop-filter:blur(8px);\n}",
   "tags": [
    "CSS",
    "JS",
    "スクロール",
    "ヘッダー",
    "上品",
    "さりげない",
    "定番"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ヘッダー縮小演出のデモ\"><style>.shsh-bar{animation:shsh-shrink 4s ease-in-out infinite}@keyframes shsh-shrink{0%,15%{height:40px;opacity:1}50%,100%{height:22px;opacity:.9}}.shsh-logo{animation:shsh-move 4s ease-in-out infinite}@keyframes shsh-move{0%,15%{transform:translateY(0) scale(1)}50%,100%{transform:translateY(-6px) scale(.75)}}.shsh-content{animation:shsh-scroll 4s ease-in-out infinite}@keyframes shsh-scroll{0%,15%{transform:translateY(0)}50%,100%{transform:translateY(-40px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g class=\"shsh-content\"><rect x=\"20\" y=\"60\" width=\"200\" height=\"10\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".3\"/><rect x=\"20\" y=\"78\" width=\"180\" height=\"10\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".3\"/><rect x=\"20\" y=\"96\" width=\"190\" height=\"10\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".3\"/><rect x=\"20\" y=\"114\" width=\"160\" height=\"10\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".3\"/></g><rect class=\"shsh-bar\" x=\"0\" y=\"0\" width=\"240\" height=\"40\" fill=\"var(--w-bg,#101830)\" opacity=\".92\"/><rect class=\"shsh-logo\" x=\"18\" y=\"10\" width=\"40\" height=\"18\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\"/></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "smooth-scroll",
    "scroll-reveal",
    "sticky-position",
    "scrollytelling"
   ]
  },
  {
   "id": "parallax-scroll",
   "num": "W-006",
   "name": "Parallax Scroll",
   "nameJa": "パララックス",
   "category": "scroll",
   "description": "背景と前景を異なる速度で動かして奥行きを演出する表現。perspective と translateZ を使うCSSトリック、またはscrollイベントでtranslateYを変えるJS実装がある。",
   "useCase": "ヒーローセクションの背景に立体感を出したい、世界観を見せたいストーリー性のあるLP導入部で使う。",
   "code": ".plx-scene{ perspective:1px; overflow-y:auto; height:100%; }\n.plx-back{ transform:translateZ(-1px) scale(2); }\n.plx-front{ transform:translateZ(0); }",
   "tags": [
    "CSS",
    "スクロール",
    "奥行き",
    "背景",
    "没入感",
    "ダイナミック",
    "立体感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"パララックスのデモ\"><style>.plx-back{animation:plx-slow 5s ease-in-out infinite}.plx-front{animation:plx-fast 5s ease-in-out infinite}@keyframes plx-slow{0%,100%{transform:translateY(0)}50%{transform:translateY(-10px)}}@keyframes plx-fast{0%,100%{transform:translateY(0)}50%{transform:translateY(-30px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g class=\"plx-back\" opacity=\".5\"><circle cx=\"60\" cy=\"50\" r=\"26\" fill=\"var(--w-sub,#94a3c0)\"/><circle cx=\"170\" cy=\"40\" r=\"18\" fill=\"var(--w-sub,#94a3c0)\"/></g><g class=\"plx-front\"><rect x=\"30\" y=\"90\" width=\"60\" height=\"40\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\"/><rect x=\"150\" y=\"80\" width=\"60\" height=\"50\" rx=\"6\" fill=\"var(--w-amber,#ffc857)\"/></g></svg>",
   "useFor": [
    "lp"
   ],
   "weight": "主役",
   "relatedIds": [
    "parallax-background",
    "horizontal-scroll-section",
    "image-clip-reveal",
    "vertical-scroll-snap"
   ]
  },
  {
   "id": "scroll-reveal",
   "num": "W-007",
   "name": "Scroll Reveal",
   "nameJa": "スクロール出現",
   "category": "scroll",
   "description": "要素が画面に入った瞬間にフェードやスライドで現れる表現。IntersectionObserverで交差を検知し is-visible クラスを付与、CSSのtransitionで動かす。",
   "useCase": "LPの各セクション見出しやカードを、下にスクロールするたびに順番に登場させて視線を誘導したいとき。",
   "code": "const io=new IntersectionObserver(es=>es.forEach(e=>\n  e.isIntersecting&&e.target.classList.add('is-visible')));\ndocument.querySelectorAll('.reveal').forEach(el=>io.observe(el));\n\n.reveal{opacity:0;transform:translateY(24px);transition:.6s}\n.reveal.is-visible{opacity:1;transform:none}",
   "tags": [
    "JS",
    "CSS",
    "スクロール",
    "出現",
    "ふわっと",
    "目を引く",
    "定番"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"スクロール出現のデモ\"><style>.srvl-card{animation:srvl-in 4.5s ease-out infinite}.srvl-card.b{animation-delay:.4s}.srvl-card.c{animation-delay:.8s}@keyframes srvl-in{0%{opacity:0;transform:translateY(20px)}20%,70%{opacity:1;transform:translateY(0)}85%,100%{opacity:0;transform:translateY(20px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect class=\"srvl-card a\" x=\"24\" y=\"30\" width=\"60\" height=\"90\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\"/><rect class=\"srvl-card b\" x=\"90\" y=\"30\" width=\"60\" height=\"90\" rx=\"6\" fill=\"var(--w-amber,#ffc857)\" opacity=\".85\"/><rect class=\"srvl-card c\" x=\"156\" y=\"30\" width=\"60\" height=\"90\" rx=\"6\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".85\"/></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "view-timeline-reveal",
    "sticky-header-shrink",
    "horizontal-scroll-section",
    "starting-style"
   ]
  },
  {
   "id": "scrollytelling",
   "num": "W-008",
   "name": "Scrollytelling",
   "nameJa": "スクロリーテリング",
   "category": "scroll",
   "description": "画面中央にビジュアルを固定し、その脇をテキストが流れていくことで物語を進める表現。position: sticky のビジュアルパネルと、ステップ検知で状態を切り替えるテキストブロックを組み合わせる。",
   "useCase": "サービスの仕組み解説や数値推移の説明など、1つの図をスクロールで少しずつ書き換えながら読ませたい長尺LP。",
   "code": ".sctl-wrap{ display:grid; grid-template-columns:1fr 1fr; }\n.sctl-visual{ position:sticky; top:0; height:100vh; }\n.sctl-steps{ display:flex; flex-direction:column; gap:100vh; }\n/* IntersectionObserverで各stepの通過を検知しvisualの表示を切替 */",
   "tags": [
    "CSS",
    "JS",
    "スクロール",
    "ストーリー",
    "没入感",
    "引き込まれる",
    "解説"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"スクロリーテリングのデモ\"><style>.sctl-shape{animation:sctl-morph 5s ease-in-out infinite}@keyframes sctl-morph{0%,30%{fill:var(--w-accent,#4fe3c1)}35%,63%{fill:var(--w-amber,#ffc857)}68%,100%{fill:var(--w-sub,#94a3c0)}}.sctl-step{opacity:.25}.sctl-step.a{animation:sctl-a 5s ease-in-out infinite}.sctl-step.b{animation:sctl-b 5s ease-in-out infinite}.sctl-step.c{animation:sctl-c 5s ease-in-out infinite}@keyframes sctl-a{0%,30%{opacity:1}35%,100%{opacity:.25}}@keyframes sctl-b{0%,30%{opacity:.25}35%,63%{opacity:1}68%,100%{opacity:.25}}@keyframes sctl-c{0%,63%{opacity:.25}68%,100%{opacity:1}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><circle class=\"sctl-shape\" cx=\"60\" cy=\"75\" r=\"34\"/><rect class=\"sctl-step a\" x=\"120\" y=\"30\" width=\"100\" height=\"10\" rx=\"3\" fill=\"var(--w-ink,#e8eef9)\"/><rect class=\"sctl-step b\" x=\"120\" y=\"70\" width=\"100\" height=\"10\" rx=\"3\" fill=\"var(--w-ink,#e8eef9)\"/><rect class=\"sctl-step c\" x=\"120\" y=\"110\" width=\"100\" height=\"10\" rx=\"3\" fill=\"var(--w-ink,#e8eef9)\"/></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "horizontal-scroll-section",
    "parallax-background",
    "vertical-scroll-snap",
    "scroll-snap"
   ]
  },
  {
   "id": "scroll-text-highlight",
   "num": "W-009",
   "name": "Scroll Text Highlight",
   "nameJa": "スクロール連動テキストハイライト",
   "category": "scroll",
   "description": "文章を読み進める速さに合わせて行や単語がマーカーで塗られていく表現。IntersectionObserverや animation-timeline: view() で交差率を取得し、背景の scaleX を伸ばして塗る。",
   "useCase": "インタビュー記事やコンセプト文で、読み手の視線誘導と読んでいる実感を演出したい縦長セクション。",
   "code": ".sthl-mark{\n  transform-origin:left;\n  transform:scaleX(0);\n  animation:sthl-fill linear both;\n  animation-timeline:view();\n  animation-range:entry 10% cover 50%;\n}\n@keyframes sthl-fill{ to{transform:scaleX(1)} }",
   "tags": [
    "CSS",
    "スクロール",
    "テキスト",
    "強調",
    "ぬるっと",
    "没入感",
    "最新仕様"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"スクロール連動テキストハイライトのデモ\"><style>.sthl-mark{transform-origin:left}.sthl-mark.a{animation:sthl-a 4.5s ease-in-out infinite}.sthl-mark.b{animation:sthl-b 4.5s ease-in-out infinite}.sthl-mark.c{animation:sthl-c 4.5s ease-in-out infinite}@keyframes sthl-a{0%,4%{transform:scaleX(0)}11%,29%{transform:scaleX(1)}36%,100%{transform:scaleX(0)}}@keyframes sthl-b{0%,33%{transform:scaleX(0)}40%,60%{transform:scaleX(1)}67%,100%{transform:scaleX(0)}}@keyframes sthl-c{0%,64%{transform:scaleX(0)}71%,91%{transform:scaleX(1)}98%,100%{transform:scaleX(0)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect class=\"sthl-mark a\" x=\"18\" y=\"38\" width=\"120\" height=\"18\" rx=\"3\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".35\"/><text x=\"20\" y=\"52\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"13\" fill=\"var(--w-ink,#e8eef9)\">読み進めるほど</text><rect class=\"sthl-mark b\" x=\"18\" y=\"68\" width=\"150\" height=\"18\" rx=\"3\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".35\"/><text x=\"20\" y=\"82\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"13\" fill=\"var(--w-ink,#e8eef9)\">文章が色づいていく</text><rect class=\"sthl-mark c\" x=\"18\" y=\"98\" width=\"100\" height=\"18\" rx=\"3\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".35\"/><text x=\"20\" y=\"112\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"13\" fill=\"var(--w-ink,#e8eef9)\">読了体験の演出</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "scroll-snap",
    "scroll-driven-animation",
    "vertical-scroll-snap",
    "smooth-scroll"
   ]
  },
  {
   "id": "reading-progress-bar",
   "num": "W-010",
   "name": "Reading Progress Bar",
   "nameJa": "読了プログレスバー",
   "category": "scroll",
   "description": "記事をどこまで読んだかを画面上部の細いバーで示す表現。scrollイベントで scrollTop / (scrollHeight - clientHeight) を計算し、バーの width に反映する。",
   "useCase": "長文のnote記事やLPの縦長ページで、読者に残り分量を意識させ離脱を防ぎたいときに使う。",
   "code": "addEventListener('scroll',()=>{\n  const h=document.documentElement;\n  const pct=h.scrollTop/(h.scrollHeight-h.clientHeight)*100;\n  bar.style.width=pct+'%';\n});",
   "tags": [
    "JS",
    "スクロール",
    "進捗",
    "ナビゲーション",
    "わかりやすい",
    "定番",
    "ミニマル"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"読了プログレスバーのデモ\"><style>.rdpg-fill{animation:rdpg-grow 4s linear infinite;transform-origin:left}@keyframes rdpg-grow{0%{transform:scaleX(0)}100%{transform:scaleX(1)}}.rdpg-lines{animation:rdpg-up 4s linear infinite}@keyframes rdpg-up{0%{transform:translateY(0)}100%{transform:translateY(-80px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"0\" y=\"0\" width=\"240\" height=\"6\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".25\"/><rect class=\"rdpg-fill\" x=\"0\" y=\"0\" width=\"240\" height=\"6\" fill=\"var(--w-accent,#4fe3c1)\"/><g class=\"rdpg-lines\"><rect x=\"40\" y=\"30\" width=\"160\" height=\"8\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".35\"/><rect x=\"40\" y=\"48\" width=\"140\" height=\"8\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".35\"/><rect x=\"40\" y=\"66\" width=\"150\" height=\"8\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".35\"/><rect x=\"40\" y=\"84\" width=\"120\" height=\"8\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".35\"/><rect x=\"40\" y=\"102\" width=\"145\" height=\"8\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".35\"/><rect x=\"40\" y=\"120\" width=\"130\" height=\"8\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".35\"/></g></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "smooth-scroll",
    "sticky-header-shrink",
    "scroll-reveal",
    "scroll-snap-events"
   ]
  },
  {
   "id": "count-up-on-scroll",
   "num": "W-011",
   "name": "Count-Up on Scroll",
   "nameJa": "スクロール連動カウントアップ",
   "category": "scroll",
   "description": "数字要素が画面に入った瞬間に0から目標値までカウントアップする表現。IntersectionObserverで表示を検知し、requestAnimationFrameで数値をイージング付きに増やしてテキストへ反映する。",
   "useCase": "実績数値や導入社数、削減率などのKPIをLPで印象的に見せたい統計セクションに使う。",
   "code": "const io=new IntersectionObserver(es=>es.forEach(e=>{\n  if(!e.isIntersecting)return;\n  const to=+e.target.dataset.to, t0=performance.now();\n  const tick=t=>{\n    const p=Math.min(1,(t-t0)/1200);\n    const eased=1-Math.pow(1-p,3);\n    e.target.textContent=Math.round(eased*to);\n    if(p<1) requestAnimationFrame(tick);\n  };\n  requestAnimationFrame(tick);\n}));",
   "tags": [
    "JS",
    "スクロール",
    "数字",
    "インパクト",
    "目を引く",
    "説得力",
    "高級感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"スクロール連動カウントアップのデモ\"><style>.cnup-num{opacity:0}.cnup-num.n1{animation:cnup-n1 4s infinite}.cnup-num.n2{animation:cnup-n2 4s infinite}.cnup-num.n3{animation:cnup-n3 4s infinite}.cnup-num.n4{animation:cnup-n4 4s infinite}.cnup-num.n5{animation:cnup-n5 4s infinite}@keyframes cnup-n1{0%,19.5%{opacity:1}20%,100%{opacity:0}}@keyframes cnup-n2{0%,19.5%{opacity:0}20%,39.5%{opacity:1}40%,100%{opacity:0}}@keyframes cnup-n3{0%,39.5%{opacity:0}40%,59.5%{opacity:1}60%,100%{opacity:0}}@keyframes cnup-n4{0%,59.5%{opacity:0}60%,79.5%{opacity:1}80%,100%{opacity:0}}@keyframes cnup-n5{0%,79.5%{opacity:0}80%,99.5%{opacity:1}100%{opacity:0}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g transform=\"translate(120,85) scale(3)\" text-anchor=\"middle\"><text class=\"cnup-num n1\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"14\" font-weight=\"700\" fill=\"var(--w-accent,#4fe3c1)\">0%</text><text class=\"cnup-num n2\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"14\" font-weight=\"700\" fill=\"var(--w-accent,#4fe3c1)\">25%</text><text class=\"cnup-num n3\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"14\" font-weight=\"700\" fill=\"var(--w-accent,#4fe3c1)\">58%</text><text class=\"cnup-num n4\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"14\" font-weight=\"700\" fill=\"var(--w-accent,#4fe3c1)\">86%</text><text class=\"cnup-num n5\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"14\" font-weight=\"700\" fill=\"var(--w-accent,#4fe3c1)\">100%</text></g><text x=\"120\" y=\"128\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"11\" text-anchor=\"middle\" fill=\"var(--w-sub,#94a3c0)\">導入企業数を達成率で表示</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "scroll-reveal",
    "horizontal-scroll-section",
    "custom-cursor",
    "sticky-header-shrink"
   ]
  },
  {
   "id": "horizontal-scroll-section",
   "num": "W-012",
   "name": "Horizontal Scroll Section",
   "nameJa": "横スクロールセクション",
   "category": "scroll",
   "description": "縦スクロール中の1区間だけ中身が横方向に流れる表現。セクション高さをコンテンツ幅分だけ確保し position: sticky で固定した内側を translateX で動かす。",
   "useCase": "ギャラリーや年表、実績一覧を「めくる」ように見せたい、縦一辺倒のLPにリズムを付けたいセクション。",
   "code": ".hscr-outer{ height:300vh; position:relative; }\n.hscr-sticky{ position:sticky; top:0; overflow:hidden; height:100vh; }\n.hscr-track{ display:flex; will-change:transform; }\n/* JS: track.style.transform = `translateX(-${scrollRatio*maxShift}px)` */",
   "tags": [
    "CSS",
    "JS",
    "スクロール",
    "横スクロール",
    "ダイナミック",
    "目を引く",
    "没入感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"横スクロールセクションのデモ\"><style>.hscr-track{animation:hscr-move 4.5s ease-in-out infinite}@keyframes hscr-move{0%,10%{transform:translateX(0)}90%,100%{transform:translateX(-120px)}}.hscr-cursor{animation:hscr-down 4.5s ease-in-out infinite}@keyframes hscr-down{0%,10%{transform:translateY(0)}90%,100%{transform:translateY(70px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g class=\"hscr-track\"><rect x=\"20\" y=\"40\" width=\"70\" height=\"60\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\"/><rect x=\"100\" y=\"40\" width=\"70\" height=\"60\" rx=\"6\" fill=\"var(--w-amber,#ffc857)\"/><rect x=\"180\" y=\"40\" width=\"70\" height=\"60\" rx=\"6\" fill=\"var(--w-sub,#94a3c0)\"/><rect x=\"260\" y=\"40\" width=\"70\" height=\"60\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".6\"/></g><rect x=\"8\" y=\"16\" width=\"8\" height=\"90\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-width=\"2\" opacity=\".4\" rx=\"4\"/><circle class=\"hscr-cursor\" cx=\"12\" cy=\"20\" r=\"5\" fill=\"var(--w-ink,#e8eef9)\"/></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "parallax-background",
    "parallax-scroll",
    "scroll-reveal",
    "scrollytelling"
   ]
  },
  {
   "id": "smooth-scroll",
   "num": "W-013",
   "name": "Smooth Scroll",
   "nameJa": "スムーススクロール",
   "category": "scroll",
   "description": "アンカーリンクやJSでのスクロール移動を、瞬間移動ではなく滑らかな慣性付きの動きにする表現。scroll-behavior: smooth をCSS1行で有効化できる。",
   "useCase": "ページ内ナビの「詳細を見る」リンクや目次クリック時に、移動先までの流れを見せて迷子を防ぎたいとき。",
   "code": "html{\n  scroll-behavior:smooth;\n}",
   "tags": [
    "CSS",
    "スクロール",
    "ナビゲーション",
    "ぬるっと",
    "上品",
    "定番"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"スムーススクロールのデモ\"><style>.sms-content{animation:sms-move 4s cubic-bezier(.22,1,.36,1) infinite}@keyframes sms-move{0%,15%{transform:translateY(0)}85%,100%{transform:translateY(-70px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><polygon points=\"24,20 34,20 29,28\" fill=\"var(--w-amber,#ffc857)\"/><text x=\"40\" y=\"27\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-amber,#ffc857)\">目次リンク</text><g class=\"sms-content\"><rect x=\"24\" y=\"45\" width=\"192\" height=\"10\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".35\"/><rect x=\"24\" y=\"63\" width=\"160\" height=\"10\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".35\"/><rect x=\"24\" y=\"81\" width=\"180\" height=\"10\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".35\"/><rect x=\"24\" y=\"99\" width=\"140\" height=\"16\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\"/><text x=\"34\" y=\"111\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-bg,#101830)\">#target</text></g></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "sticky-header-shrink",
    "scroll-snap",
    "scroll-driven-animation",
    "sticky-position"
   ]
  },
  {
   "id": "overscroll-behavior",
   "num": "W-014",
   "name": "Overscroll Behavior",
   "nameJa": "オーバースクロール制御",
   "category": "scroll",
   "description": "スクロール端に達したときの挙動（親ページへの伝播やバウンス）を制御する表現。overscroll-behavior: contain でモーダル内スクロールが背後のページを巻き込むのを止められる。",
   "useCase": "モーダルやドロワー、チャットの吹き出し欄など、内側だけスクロールさせて背景ページを固定したい場面。",
   "code": ".oscb-modal-body{\n  overflow-y:auto;\n  overscroll-behavior:contain;\n}",
   "tags": [
    "CSS",
    "スクロール",
    "モーダル",
    "制御",
    "さりげない",
    "安心感",
    "実務向け"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"オーバースクロール制御のデモ\"><style>.osb-inner{animation:osb-scroll 4s ease-in-out infinite}@keyframes osb-scroll{0%,15%{transform:translateY(0)}50%,60%{transform:translateY(-46px)}90%,100%{transform:translateY(0)}}.osb-stop{animation:osb-flash 4s ease-in-out infinite}@keyframes osb-flash{0%,47%,100%{opacity:0}52%,58%{opacity:1}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><clipPath id=\"osb-clip\"><rect x=\"50\" y=\"24\" width=\"140\" height=\"102\" rx=\"8\"/></clipPath><rect x=\"50\" y=\"24\" width=\"140\" height=\"102\" rx=\"8\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".08\"/><g class=\"osb-inner\" clip-path=\"url(#osb-clip)\"><rect x=\"62\" y=\"34\" width=\"116\" height=\"14\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".8\"/><rect x=\"62\" y=\"54\" width=\"100\" height=\"10\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/><rect x=\"62\" y=\"70\" width=\"110\" height=\"10\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/><rect x=\"62\" y=\"86\" width=\"90\" height=\"10\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/><rect x=\"62\" y=\"102\" width=\"105\" height=\"10\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/><rect x=\"62\" y=\"118\" width=\"95\" height=\"10\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/></g><rect x=\"50\" y=\"24\" width=\"140\" height=\"102\" rx=\"8\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-width=\"1.5\"/><rect class=\"osb-stop\" x=\"50\" y=\"118\" width=\"140\" height=\"4\" fill=\"var(--w-amber,#ffc857)\"/></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "sticky-position",
    "scroll-margin-padding",
    "sticky-header-shrink",
    "custom-scrollbar"
   ]
  },
  {
   "id": "scroll-margin-padding",
   "num": "W-015",
   "name": "Scroll Margin & Padding",
   "nameJa": "スクロール位置の余白調整",
   "category": "scroll",
   "description": "アンカー移動やスナップで要素が画面端にピッタリ張り付いて隠れるのを防ぐ表現。対象要素に scroll-margin-top、コンテナに scroll-padding-top を指定して停止位置をずらす。",
   "useCase": "固定ヘッダーがある目次ジャンプや章送りで、見出しがヘッダーの下に隠れないよう調整したいとき。",
   "code": ".smgp-section{\n  scroll-margin-top:72px; /* 固定ヘッダー分ずらす */\n}\n.smgp-container{\n  scroll-padding-top:72px;\n}",
   "tags": [
    "CSS",
    "スクロール",
    "アンカー",
    "レイアウト",
    "さりげない",
    "地味に重要",
    "実務向け"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"スクロール位置の余白調整のデモ\"><style>.smgp-target{animation:smgp-move 4s ease-in-out infinite}@keyframes smgp-move{0%,15%{transform:translateY(60px)}45%,100%{transform:translateY(0)}}.smgp-gap{animation:smgp-gap 4s ease-in-out infinite}@keyframes smgp-gap{0%,40%{opacity:0}50%,100%{opacity:1}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"0\" y=\"0\" width=\"240\" height=\"30\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".9\"/><text x=\"12\" y=\"19\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-bg,#101830)\">固定ヘッダー</text><g class=\"smgp-target\"><rect x=\"20\" y=\"46\" width=\"200\" height=\"16\" rx=\"4\" fill=\"var(--w-ink,#e8eef9)\"/></g><rect class=\"smgp-gap\" x=\"20\" y=\"32\" width=\"200\" height=\"12\" fill=\"var(--w-amber,#ffc857)\" opacity=\".3\"/></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "overscroll-behavior",
    "scroll-snap",
    "sticky-position",
    "sticky-header-shrink"
   ]
  },
  {
   "id": "custom-scrollbar",
   "num": "W-016",
   "name": "Custom Scrollbar Styling",
   "nameJa": "スクロールバーのスタイリング",
   "category": "scroll",
   "description": "OS標準の太いスクロールバーを細くブランドカラーに変える表現。標準仕様の scrollbar-width / scrollbar-color と、Chrome系向けの ::-webkit-scrollbar 疑似要素を併用する。",
   "useCase": "コード風UIやギャラリーの横スクロール枠など、スクロールバー自体もデザインの一部として見せたい場面。",
   "code": ".cscr-panel{\n  scrollbar-width:thin;\n  scrollbar-color:var(--w-accent,#4fe3c1) transparent;\n}\n.cscr-panel::-webkit-scrollbar{ width:8px; }\n.cscr-panel::-webkit-scrollbar-thumb{\n  background:var(--w-accent,#4fe3c1); border-radius:4px;\n}",
   "tags": [
    "CSS",
    "スクロール",
    "装飾",
    "ブランディング",
    "こだわり",
    "さりげない",
    "高級感"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"スクロールバーのスタイリングのデモ\"><style>.cscr-thumb{animation:cscr-move 4s ease-in-out infinite}@keyframes cscr-move{0%,10%{transform:translateY(0)}50%,60%{transform:translateY(60px)}100%{transform:translateY(0)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"30\" y=\"20\" width=\"170\" height=\"110\" rx=\"6\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".08\"/><rect x=\"46\" y=\"34\" width=\"140\" height=\"10\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".35\"/><rect x=\"46\" y=\"52\" width=\"120\" height=\"10\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".35\"/><rect x=\"46\" y=\"70\" width=\"130\" height=\"10\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".35\"/><rect x=\"210\" y=\"20\" width=\"8\" height=\"110\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".15\"/><rect class=\"cscr-thumb\" x=\"210\" y=\"24\" width=\"8\" height=\"34\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\"/></svg>",
   "useFor": [
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "outline-text-bg",
    "sticky-position",
    "sticky-header-shrink",
    "overscroll-behavior"
   ]
  },
  {
   "id": "scroll-snap-events",
   "num": "W-017",
   "name": "Scroll Snap Events",
   "nameJa": "スナップイベント検知",
   "category": "scroll",
   "description": "スナップ先の要素が切り替わった瞬間をJSで検知する表現。scrollsnapchange イベントで現在の対象要素を受け取り、ドットナビのアクティブ表示などをスナップと同期させる。",
   "useCase": "フルスクリーンスライドや横スクロールカルーセルで、現在位置を示すページネーションドットをスナップに正確に連動させたいとき。",
   "code": "track.addEventListener('scrollsnapchange',(e)=>{\n  dots.forEach(d=>d.classList.remove('is-active'));\n  const i=[...track.children].indexOf(e.snapTargetInline);\n  dots[i]?.classList.add('is-active');\n});",
   "tags": [
    "JS",
    "スクロール",
    "スナップ",
    "ナビゲーション",
    "きっちり",
    "キビキビ",
    "最新仕様"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"スナップイベント検知のデモ\"><style>.ssev-panel{animation:ssev-move 4.5s steps(3) infinite}@keyframes ssev-move{0%,30%{transform:translateX(0)}31%,63%{transform:translateX(-80px)}64%,96%{transform:translateX(-160px)}100%{transform:translateX(0)}}.ssev-dot.a{animation:ssev-a 4.5s steps(1) infinite}.ssev-dot.b{animation:ssev-b 4.5s steps(1) infinite}.ssev-dot.c{animation:ssev-c 4.5s steps(1) infinite}@keyframes ssev-a{0%,30%{fill:var(--w-accent,#4fe3c1)}31%,100%{fill:var(--w-sub,#94a3c0)}}@keyframes ssev-b{0%,30%{fill:var(--w-sub,#94a3c0)}31%,63%{fill:var(--w-accent,#4fe3c1)}64%,100%{fill:var(--w-sub,#94a3c0)}}@keyframes ssev-c{0%,63%{fill:var(--w-sub,#94a3c0)}64%,96%{fill:var(--w-accent,#4fe3c1)}97%,100%{fill:var(--w-sub,#94a3c0)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect class=\"ssev-panel\" x=\"24\" y=\"20\" width=\"64\" height=\"70\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\"/><rect class=\"ssev-panel\" x=\"104\" y=\"20\" width=\"64\" height=\"70\" rx=\"6\" fill=\"var(--w-amber,#ffc857)\" opacity=\".85\"/><rect class=\"ssev-panel\" x=\"184\" y=\"20\" width=\"64\" height=\"70\" rx=\"6\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".85\"/><circle class=\"ssev-dot a\" cx=\"104\" cy=\"112\" r=\"6\"/><circle class=\"ssev-dot b\" cx=\"120\" cy=\"112\" r=\"6\"/><circle class=\"ssev-dot c\" cx=\"136\" cy=\"112\" r=\"6\"/><text x=\"20\" y=\"135\" font-family=\"ui-monospace,monospace\" font-size=\"9\" fill=\"var(--w-sub,#94a3c0)\">scrollsnapchange → dot更新</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "reading-progress-bar",
    "scroll-spy-nav",
    "arrow-key-nav",
    "smooth-scroll"
   ]
  },
  {
   "id": "gradient-text",
   "num": "W-018",
   "name": "Gradient Text",
   "nameJa": "グラデーション文字",
   "category": "text",
   "description": "見出しの文字部分だけにグラデーションを適用する表現。background-clip: text で背景色を文字の形にくり抜き、color: transparent と組み合わせて実装する。CSSのみで完結する手軽さが魅力。",
   "useCase": "ヒーローセクションの大見出しやロゴ文字に、ブランドカラーの奥行きとグラデーションの高級感を出したいときに使う。",
   "code": ".gtxt-heading{\n  background: linear-gradient(90deg,#4fe3c1,#ffc857);\n  background-clip: text;\n  -webkit-background-clip: text;\n  color: transparent;\n}",
   "tags": [
    "CSS",
    "グラデーション",
    "見出し",
    "高級感",
    "目を引く",
    "ブランド"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"グラデーション文字のデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <defs>\n    <linearGradient id=\"gtxt-grad\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\">\n      <stop offset=\"0\" stop-color=\"var(--w-accent,#4fe3c1)\">\n        <animate attributeName=\"offset\" values=\"0;.5;0\" dur=\"4s\" repeatCount=\"indefinite\"/>\n      </stop>\n      <stop offset=\".5\" stop-color=\"var(--w-amber,#ffc857)\">\n        <animate attributeName=\"offset\" values=\".5;1;.5\" dur=\"4s\" repeatCount=\"indefinite\"/>\n      </stop>\n    </linearGradient>\n  </defs>\n  <g transform=\"translate(120,80) scale(3.4)\">\n    <text x=\"0\" y=\"4\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"13\" font-weight=\"800\" fill=\"url(#gtxt-grad)\">Aa</text>\n  </g>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "gradient-border",
    "duotone-image",
    "text-image-fill",
    "mesh-gradient"
   ]
  },
  {
   "id": "typewriter",
   "num": "W-019",
   "name": "Typewriter Effect",
   "nameJa": "タイプライター演出",
   "category": "text",
   "description": "文字が1文字ずつ左から現れ、末尾のカーソルが点滅し続けるタイピング風の演出。overflow: hidden と width の伸長アニメーション、steps() のイージングで実装する。",
   "useCase": "スライドの冒頭やLPのキャッチコピーで、いままさに言葉が打ち込まれているような臨場感を出したいときに使う。",
   "code": ".twtr-text{\n  overflow: hidden;\n  white-space: nowrap;\n  border-right: 2px solid #4fe3c1;\n  width: 0;\n  animation: twtr-type 3s steps(20,end) forwards,\n             twtr-blink .8s step-end infinite;\n}\n@keyframes twtr-type{ to{ width: 100%; } }\n@keyframes twtr-blink{ 50%{ border-color: transparent; } }",
   "tags": [
    "CSS",
    "アニメーション",
    "見出し",
    "没入感",
    "テンポよく",
    "動的"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"タイプライター演出のデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <defs>\n    <clipPath id=\"twtr-clip\">\n      <rect x=\"0\" y=\"0\" width=\"0\" height=\"150\">\n        <animate attributeName=\"width\" values=\"0;125;125;0;0\" keyTimes=\"0;0.55;0.75;0.8;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n      </rect>\n    </clipPath>\n  </defs>\n  <g clip-path=\"url(#twtr-clip)\">\n    <text x=\"20\" y=\"82\" font-family=\"ui-monospace,monospace\" font-size=\"13\" fill=\"var(--w-ink,#e8eef9)\">Hello, world_</text>\n  </g>\n  <rect y=\"70\" width=\"2.5\" height=\"16\" fill=\"var(--w-accent,#4fe3c1)\">\n    <animate attributeName=\"x\" values=\"20;145;145;20;20\" keyTimes=\"0;0.55;0.75;0.8;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n    <animate attributeName=\"opacity\" values=\"1;0;1;0;1;0;1;0;1\" dur=\"0.9s\" repeatCount=\"indefinite\"/>\n  </rect>\n</svg>",
   "useFor": [
    "slide",
    "lp"
   ],
   "weight": "主役",
   "relatedIds": [
    "stagger-char-reveal",
    "ruby-heading-reveal",
    "blur-reveal-text",
    "clip-path-reveal"
   ]
  },
  {
   "id": "stagger-char-reveal",
   "num": "W-020",
   "name": "Staggered Character Reveal",
   "nameJa": "1文字ずつ時間差出現",
   "category": "text",
   "description": "見出しをJavaScriptで1文字ずつのspanに分割し、animation-delayを文字順にずらして次々とフェードイン＆浮き上がらせる演出。文字が連鎖して現れるリズムが生まれる。",
   "useCase": "スライドのタイトルやLPのキャッチコピーに、テンポよく勢いのある登場演出を付けたいときに使う。",
   "code": "document.querySelectorAll('.schr-title').forEach(el=>{\n  el.innerHTML = [...el.textContent].map((c,i)=>\n    `<span style=\"animation-delay:${i*0.05}s\">${c}</span>`).join('');\n});\n/* CSS */\n.schr-title span{display:inline-block;opacity:0;transform:translateY(12px);\n  animation:schr-in .5s ease forwards}\n@keyframes schr-in{to{opacity:1;transform:translateY(0)}}",
   "tags": [
    "JavaScript",
    "CSS",
    "見出し",
    "ふわっと",
    "テンポよく",
    "動的",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"1文字ずつ時間差出現のデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <style>\n    .schr-ltr{animation:schr-rise 3s ease infinite}\n    @keyframes schr-rise{0%,8%{opacity:0;transform:translateY(10px)}20%,80%{opacity:1;transform:translateY(0)}92%,100%{opacity:0;transform:translateY(10px)}}\n  </style>\n  <g font-family=\"ui-sans-serif,system-ui,sans-serif\" font-weight=\"800\" fill=\"var(--w-ink,#e8eef9)\">\n    <g transform=\"translate(78,84) scale(2)\"><g class=\"schr-ltr\" style=\"animation-delay:0s\"><text x=\"0\" y=\"4\" font-size=\"13\">W</text></g></g>\n    <g transform=\"translate(96,84) scale(2)\"><g class=\"schr-ltr\" style=\"animation-delay:.15s\"><text x=\"0\" y=\"4\" font-size=\"13\">A</text></g></g>\n    <g transform=\"translate(114,84) scale(2)\"><g class=\"schr-ltr\" style=\"animation-delay:.3s\"><text x=\"0\" y=\"4\" font-size=\"13\">Z</text></g></g>\n    <g transform=\"translate(132,84) scale(2)\"><g class=\"schr-ltr\" style=\"animation-delay:.45s\"><text x=\"0\" y=\"4\" font-size=\"13\">A</text></g></g>\n    <g transform=\"translate(150,84) scale(2)\"><g class=\"schr-ltr\" style=\"animation-delay:.6s\"><text x=\"0\" y=\"4\" font-size=\"13\">!</text></g></g>\n  </g>\n</svg>",
   "useFor": [
    "slide",
    "lp"
   ],
   "weight": "主役",
   "relatedIds": [
    "typewriter",
    "scroll-reveal",
    "view-transitions-slide",
    "gradient-text"
   ]
  },
  {
   "id": "blur-reveal-text",
   "num": "W-021",
   "name": "Blur-in Text",
   "nameJa": "ぼかしから浮かぶ文字",
   "category": "text",
   "description": "文字がぼやけた状態から徐々にピントが合うように浮かび上がる演出。filter: blur(10px)を0へ、opacityを0から1へ同時に遷移させて実装する。",
   "useCase": "スライドの切り替え直後や、注目させたい一文をふわっと静かに登場させたいときに使う。",
   "code": ".blrv-text{\n  filter: blur(10px);\n  opacity: 0;\n  animation: blrv-focus 1s ease-out forwards;\n}\n@keyframes blrv-focus{\n  to{ filter: blur(0); opacity: 1; }\n}",
   "tags": [
    "CSS",
    "filter",
    "見出し",
    "ふわっと",
    "没入感",
    "高級感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ぼかしから浮かぶ文字のデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <defs>\n    <filter id=\"blrv-blur\">\n      <feGaussianBlur stdDeviation=\"2.2\">\n        <animate attributeName=\"stdDeviation\" values=\"2.2;2.2;0;0;2.2\" keyTimes=\"0;0.15;0.5;0.85;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n      </feGaussianBlur>\n    </filter>\n  </defs>\n  <g transform=\"translate(120,80) scale(2.6)\">\n    <text x=\"0\" y=\"4\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"13\" font-weight=\"700\" fill=\"var(--w-ink,#e8eef9)\" filter=\"url(#blrv-blur)\">Focus\n      <animate attributeName=\"opacity\" values=\"0;0;1;1;0\" keyTimes=\"0;0.15;0.5;0.85;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n    </text>\n  </g>\n</svg>",
   "useFor": [
    "slide",
    "lp"
   ],
   "weight": "主役",
   "relatedIds": [
    "gradient-text",
    "typewriter",
    "stagger-char-reveal",
    "easing-design"
   ]
  },
  {
   "id": "variable-font-weight",
   "num": "W-022",
   "name": "Variable Font Weight Animation",
   "nameJa": "可変フォントのウェイトアニメ",
   "category": "text",
   "description": "可変フォントのウェイト軸を連続的に動かし、文字が細字から太字へなめらかに変化する演出。font-variation-settings の\"wght\"値をtransitionで滑らかに動かす。",
   "useCase": "対応フォント使用時に、見出しの強調やホバー時のインタラクションを上質になめらかに見せたいときに使う。",
   "code": ".vfwt-title{\n  font-variation-settings: \"wght\" 300;\n  transition: font-variation-settings .6s ease;\n}\n.vfwt-title:hover{\n  font-variation-settings: \"wght\" 800;\n}",
   "tags": [
    "CSS",
    "可変フォント",
    "ホバー",
    "ぬるっと",
    "高級感",
    "動的"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"可変フォントのウェイトアニメのデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <style>\n    .vfwt-thin{animation:vfwt-thin 3s ease-in-out infinite}\n    .vfwt-bold{animation:vfwt-bold 3s ease-in-out infinite}\n    @keyframes vfwt-thin{0%,100%{opacity:1}50%{opacity:0}}\n    @keyframes vfwt-bold{0%,100%{opacity:0}50%{opacity:1}}\n  </style>\n  <g transform=\"translate(120,80) scale(3)\">\n    <text class=\"vfwt-thin\" x=\"0\" y=\"4\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"13\" font-weight=\"100\" fill=\"var(--w-accent,#4fe3c1)\">Ag</text>\n    <text class=\"vfwt-bold\" x=\"0\" y=\"4\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"13\" font-weight=\"900\" fill=\"var(--w-accent,#4fe3c1)\">Ag</text>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "card-flip",
    "page-turn",
    "clip-path-shapes",
    "filter-effects"
   ]
  },
  {
   "id": "text-stroke-outline",
   "num": "W-023",
   "name": "Text Stroke Outline",
   "nameJa": "縁取り文字",
   "category": "text",
   "description": "文字の塗りを消して輪郭線だけを見せる、または太い縁取りを付ける演出。-webkit-text-stroke と paint-order: stroke fill を組み合わせて塗りの上に線が乗らないようにする。",
   "useCase": "見出しを写真や動画の上に重ねるとき、背景に負けず視認性とデザイン性を両立させたいときに使う。",
   "code": ".tstk-title{\n  color: #ffc857;\n  -webkit-text-stroke: 2px #4fe3c1;\n  paint-order: stroke fill;\n}",
   "tags": [
    "CSS",
    "縁取り",
    "見出し",
    "目を引く",
    "パキッと",
    "ダイナミック"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"縁取り文字のデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <style>\n    .tstk-txt{animation:tstk-fill 4s ease-in-out infinite}\n    @keyframes tstk-fill{0%,15%{fill-opacity:0}50%,65%{fill-opacity:1}100%{fill-opacity:0}}\n  </style>\n  <g transform=\"translate(120,80) scale(3)\">\n    <text class=\"tstk-txt\" x=\"0\" y=\"4\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"13\" font-weight=\"800\" paint-order=\"stroke\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"0.8\" fill=\"var(--w-amber,#ffc857)\" fill-opacity=\"0\">Aa</text>\n  </g>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "gradient-text",
    "neon-glow-text",
    "marker-highlight",
    "blend-difference-text"
   ]
  },
  {
   "id": "neon-glow-text",
   "num": "W-024",
   "name": "Neon Glow Text",
   "nameJa": "ネオン発光",
   "category": "text",
   "description": "文字自体が発光しているように見せる演出。text-shadow を色とぼかし半径を変えて何層も重ね、明滅アニメーションでネオンサインの点灯感まで再現する。",
   "useCase": "夜景・エンタメ・ゲーム系のLPやサムネイルタイトルで、強く目を引くネオン風の文字を作りたいときに使う。",
   "code": ".neon-title{\n  color: #fff;\n  text-shadow:\n    0 0 4px #4fe3c1,\n    0 0 12px #4fe3c1,\n    0 0 24px #4fe3c1,\n    0 0 48px #4fe3c1;\n  animation: neon-flicker 2.6s infinite;\n}\n@keyframes neon-flicker{ 20%{ opacity:.4; } }",
   "tags": [
    "CSS",
    "text-shadow",
    "発光",
    "没入感",
    "目を引く",
    "ダイナミック"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ネオン発光のデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <defs>\n    <filter id=\"neon-glow-filter\" x=\"-80%\" y=\"-80%\" width=\"260%\" height=\"260%\">\n      <feGaussianBlur stdDeviation=\"1.4\" result=\"blur\"/>\n      <feMerge><feMergeNode in=\"blur\"/><feMergeNode in=\"SourceGraphic\"/></feMerge>\n    </filter>\n  </defs>\n  <style>\n    .neon-txt{animation:neon-flicker 2.6s ease-in-out infinite}\n    @keyframes neon-flicker{0%,19%,21%,100%{opacity:1}20%{opacity:.35}}\n  </style>\n  <g transform=\"translate(120,80) scale(2.6)\">\n    <text class=\"neon-txt\" x=\"0\" y=\"4\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"13\" font-weight=\"800\" fill=\"var(--w-accent,#4fe3c1)\" filter=\"url(#neon-glow-filter)\">NEON</text>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "blend-difference-text",
    "horizontal-scroll-section",
    "text-stroke-outline",
    "long-shadow-text"
   ]
  },
  {
   "id": "marker-highlight",
   "num": "W-025",
   "name": "Marker Highlight",
   "nameJa": "蛍光マーカー線が引かれる",
   "category": "text",
   "description": "テキストの下に蛍光ペンで線を引くような色帯がスッと伸びる演出。linear-gradient の背景を background-size: 0%から100%へアニメーションさせて実装する。",
   "useCase": "note記事やLPの本文中で、読者の目を止めたい重要なキーワードに視線を誘導したいときに使う。",
   "code": ".mark-word{\n  background: linear-gradient(#ffc857,#ffc857) no-repeat;\n  background-size: 0% 40%;\n  background-position: 0 88%;\n  transition: background-size .8s ease;\n}\n.mark-word.is-in{ background-size: 100% 40%; }",
   "tags": [
    "CSS",
    "background",
    "強調",
    "目を引く",
    "パキッと",
    "高級感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"蛍光マーカー線が引かれるのデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"26\" y=\"72\" width=\"0\" height=\"15\" fill=\"var(--w-amber,#ffc857)\" opacity=\".55\">\n    <animate attributeName=\"width\" values=\"0;0;76;76;0\" keyTimes=\"0;0.1;0.5;0.85;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </rect>\n  <text x=\"30\" y=\"83\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"13\" font-weight=\"700\" fill=\"var(--w-ink,#e8eef9)\">Highlight</text>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "gradient-text",
    "text-stroke-outline",
    "text-extrude",
    "gradient-border"
   ]
  },
  {
   "id": "vertical-writing",
   "num": "W-026",
   "name": "Vertical Writing Mode",
   "nameJa": "縦書き",
   "category": "text",
   "description": "文字を上から下へ、行を右から左へ流す日本語の縦組みレイアウト。writing-mode: vertical-rl と text-orientation: mixed で実装し、和文らしい読みの流れを作る。",
   "useCase": "和風・エディトリアル系のデザインや、詩的な一文を情緒的に見せたいスライド・LPの一部で使う。",
   "code": ".vwrt-text{\n  writing-mode: vertical-rl;\n  text-orientation: mixed;\n  letter-spacing: .05em;\n  line-height: 1.8;\n}",
   "tags": [
    "CSS",
    "レイアウト",
    "和風",
    "高級感",
    "さりげない",
    "日本語"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"縦書きのデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"13\" fill=\"var(--w-ink,#e8eef9)\">\n    <text x=\"175\" y=\"30\"><tspan x=\"175\" dy=\"0\">縦</tspan><tspan x=\"175\" dy=\"20\">書</tspan><tspan x=\"175\" dy=\"20\">き</tspan><tspan x=\"175\" dy=\"20\">組</tspan></text>\n    <text x=\"115\" y=\"30\"><tspan x=\"115\" dy=\"0\">の</tspan><tspan x=\"115\" dy=\"20\">例</tspan><tspan x=\"115\" dy=\"20\">で</tspan><tspan x=\"115\" dy=\"20\">す</tspan></text>\n  </g>\n  <circle r=\"4\" fill=\"var(--w-accent,#4fe3c1)\">\n    <animateMotion dur=\"4s\" repeatCount=\"indefinite\" path=\"M175,26 L175,106 L115,26 L115,106\"/>\n  </circle>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "text-orientation-upright",
    "text-emphasis-dots",
    "text-combine-upright",
    "hanging-punctuation"
   ]
  },
  {
   "id": "line-clamp",
   "num": "W-027",
   "name": "Line Clamp Truncation",
   "nameJa": "行数制限省略",
   "category": "text",
   "description": "指定した行数を超えた文章を末尾の「…」で省略して切り詰める演出。display: -webkit-box と -webkit-line-clamp、overflow: hidden の組み合わせで実装する。",
   "useCase": "カード一覧やニュース欄で、説明文の長さをそろえて見た目のガタつきを防ぎたいときに使う。",
   "code": ".lclp-desc{\n  display: -webkit-box;\n  -webkit-line-clamp: 3;\n  -webkit-box-orient: vertical;\n  overflow: hidden;\n}",
   "tags": [
    "CSS",
    "レイアウト",
    "省略",
    "カード",
    "さりげない",
    "すっきり",
    "整列"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"行数制限省略のデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g fill=\"var(--w-sub,#94a3c0)\">\n    <rect x=\"20\" y=\"30\" width=\"200\" height=\"8\" rx=\"4\" opacity=\".5\"/>\n    <rect x=\"20\" y=\"46\" width=\"190\" height=\"8\" rx=\"4\" opacity=\".5\"/>\n    <rect x=\"20\" y=\"62\" width=\"200\" height=\"8\" rx=\"4\" opacity=\".5\"/>\n    <rect x=\"20\" y=\"78\" width=\"180\" height=\"8\" rx=\"4\" opacity=\".5\"/>\n    <rect x=\"20\" y=\"94\" width=\"140\" height=\"8\" rx=\"4\" opacity=\".5\"/>\n  </g>\n  <rect x=\"20\" y=\"78\" width=\"200\" height=\"0\" fill=\"var(--w-bg,#101830)\">\n    <animate attributeName=\"height\" values=\"0;0;32;32;0\" keyTimes=\"0;0.2;0.4;0.8;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </rect>\n  <text x=\"150\" y=\"86\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"14\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\"0\">…\n    <animate attributeName=\"opacity\" values=\"0;0;1;1;0\" keyTimes=\"0;0.35;0.45;0.8;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "text-wrap-balance",
    "vertical-writing",
    "palt-tracking",
    "hover-lift-card"
   ]
  },
  {
   "id": "text-wrap-balance",
   "num": "W-028",
   "name": "Balanced Text Wrap",
   "nameJa": "見出しの行バランス調整",
   "category": "text",
   "description": "text-wrap: balanceは見出しの各行を均等に近づけ、text-wrap: prettyは本文末の短すぎる行や不自然な改行を減らす。用途の異なる2値を、見出しと本文で使い分ける。",
   "useCase": "複数行見出しの形を整え、本文では読みやすい改行を選ばせたい場面。どちらもコンテンツ幅は固定せず、ブラウザへ改行位置の最適化を任せる。",
   "code": "h1, h2, .twbl-title{\n  text-wrap: balance;\n}\np, .twbl-body{\n  text-wrap: pretty;\n}",
   "tags": [
    "CSS",
    "レイアウト",
    "見出し",
    "整列",
    "さりげない",
    "すっきり",
    "読みやすさ"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"balanceとprettyの比較のデモ\">\n  <style>.twb-arrow{animation:twb-pulse 3s ease-in-out infinite}@keyframes twb-pulse{0%,100%{opacity:.2}50%{opacity:1}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <text x=\"25\" y=\"34\" font-family=\"ui-monospace,monospace\" font-size=\"8\" fill=\"var(--w-sub,#a7b4cd)\">BEFORE</text><text x=\"135\" y=\"34\" font-family=\"ui-monospace,monospace\" font-size=\"8\" fill=\"var(--w-accent,#4fe3c1)\">BALANCE</text><g stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"8\" stroke-linecap=\"round\"><path d=\"M26 52h82M26 70h70M26 88h26\" opacity=\".48\"/><path d=\"M136 52h70M136 70h67M136 88h63\"/></g><path class=\"twb-arrow\" d=\"M113 70h13\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"2\"/>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">before  →  text-wrap: balance</text>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "line-clamp",
    "vertical-writing",
    "palt-tracking",
    "back-to-top"
   ]
  },
  {
   "id": "long-shadow-text",
   "num": "W-029",
   "name": "Long Shadow Text",
   "nameJa": "ロングシャドウ",
   "category": "text",
   "description": "文字から斜め45度方向へ長く伸びる影を付けるフラットデザイン系の演出。text-shadow を1pxずつずらしながら何層も重ねる、または疑似要素で描画する。",
   "useCase": "レトロ・フラットデザイン調のタイトルやバッジで、立体感と遊び心のあるアクセントを出したいときに使う。",
   "code": ".lsdw-title{\n  color: #e8eef9;\n  text-shadow:\n    1px 1px 0 #94a3c0, 2px 2px 0 #94a3c0,\n    3px 3px 0 #94a3c0, 4px 4px 0 #94a3c0,\n    5px 5px 0 #94a3c0, 6px 6px 0 #94a3c0;\n}",
   "tags": [
    "CSS",
    "text-shadow",
    "フラットデザイン",
    "レトロ",
    "目を引く",
    "立体感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ロングシャドウのデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <style>\n    .lsdw-bar{animation:lsdw-grow 3s ease-in-out infinite;transform-origin:0 0}\n    @keyframes lsdw-grow{0%,100%{transform:scale(.5)}50%{transform:scale(1.3)}}\n  </style>\n  <g transform=\"translate(70,88) rotate(45)\">\n    <rect class=\"lsdw-bar\" x=\"0\" y=\"-4\" width=\"46\" height=\"8\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/>\n  </g>\n  <g transform=\"translate(65,88) scale(2.6)\">\n    <text x=\"0\" y=\"4\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"13\" font-weight=\"800\" fill=\"var(--w-ink,#e8eef9)\">GO</text>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "neon-glow-text",
    "text-extrude",
    "crt-scanlines",
    "gradient-text"
   ]
  },
  {
   "id": "blend-difference-text",
   "num": "W-030",
   "name": "Blend Mode Inverted Text",
   "nameJa": "背景差分の反転文字",
   "category": "text",
   "description": "mix-blend-mode: differenceで前景色と背景色の差分を合成し、背景に応じて反転するような見え方を作る。強い視覚効果だが、あらゆる背景で十分な文字コントラストを保証する機能ではないため、本文ではなく装飾へ使い実背景で確認する。",
   "useCase": "大きな装飾見出しやカーソルなどで背景との反転効果を狙う場面。重要な本文や操作ラベルには使わず、通常色の代替表示も用意する。",
   "code": ".bdif-title{\n  color: #fff;\n  mix-blend-mode: difference;\n  isolation: isolate;\n}",
   "tags": [
    "CSS",
    "mix-blend-mode",
    "反転",
    "目を引く",
    "ダイナミック",
    "没入感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"背景差分の反転文字のデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"-20\" y=\"0\" width=\"90\" height=\"150\" fill=\"var(--w-accent,#4fe3c1)\">\n    <animate attributeName=\"x\" values=\"-20;170;-20\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </rect>\n  <g transform=\"translate(120,76) scale(2.6)\">\n    <text x=\"0\" y=\"4\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"13\" font-weight=\"800\" fill=\"var(--w-ink,#e8eef9)\" style=\"mix-blend-mode:difference\">MIX</text>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "neon-glow-text",
    "horizontal-scroll-section",
    "mix-blend-mode",
    "text-stroke-outline"
   ]
  },
  {
   "id": "selection-brand",
   "num": "W-031",
   "name": "Branded Text Selection",
   "nameJa": "::selectionのブランド化",
   "category": "text",
   "description": "ユーザーがテキストをドラッグ選択したときに表示されるハイライト色を、ブラウザ既定の水色からブランドカラーへ変更する演出。::selection疑似要素にbackgroundとcolorを指定するだけで実装できる。",
   "useCase": "コーポレートサイトやポートフォリオで、細部までブランドの世界観を統一したいときに使う。",
   "code": "::selection{\n  background: #4fe3c1;\n  color: #101830;\n}",
   "tags": [
    "CSS",
    "::selection",
    "細部",
    "さりげない",
    "高級感",
    "ブランド"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"::selectionのブランド化のデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"20\" y=\"66\" width=\"0\" height=\"16\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".55\">\n    <animate attributeName=\"width\" values=\"0;0;80;80;0\" keyTimes=\"0;0.1;0.5;0.85;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </rect>\n  <text x=\"20\" y=\"78\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"13\" font-weight=\"600\" fill=\"var(--w-ink,#e8eef9)\">Select this</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "gradient-text",
    "vertical-writing",
    "drop-cap",
    "custom-scrollbar"
   ]
  },
  {
   "id": "text-scramble",
   "num": "W-032",
   "name": "Text Scramble",
   "nameJa": "文字スクランブル",
   "category": "text",
   "description": "文字がランダムな記号でチラつきながら、少しずつ最終的な単語へと収束していく演出。JavaScriptで各文字をランダム文字から正解の文字へ間隔を空けて置き換えていく。",
   "useCase": "数値やキーワードの登場演出、ホバー時のインタラクションにハッカー風の緊張感を出したいときに使う。",
   "code": "function scramble(el, text, ms=30){\n  const chars='!<>-_/[]{}=+*^?#';\n  let frame=0;\n  const iv=setInterval(()=>{\n    el.textContent = text.split('').map((c,i)=>\n      i < frame ? c : chars[Math.random()*chars.length|0]).join('');\n    if(frame++ > text.length) clearInterval(iv);\n  }, ms);\n}",
   "tags": [
    "JavaScript",
    "グリッチ",
    "ホバー",
    "目を引く",
    "ダイナミック",
    "テンポよく"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"文字スクランブルのデモ\">\n  <style>.tsc-noise{animation:tsc-noise 4s steps(1) infinite}@keyframes tsc-noise{0%{opacity:1}12%{opacity:.5}24%{opacity:1}36%{opacity:.55}48%,100%{opacity:0}}.tsc-final{animation:tsc-final 4s steps(1) infinite}@keyframes tsc-final{0%,47%{opacity:0}48%,88%{opacity:1}89%,100%{opacity:0}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g font-family=\"ui-monospace,monospace\" font-size=\"32\" font-weight=\"800\" text-anchor=\"middle\"><text class=\"tsc-noise\" x=\"120\" y=\"85\" fill=\"var(--w-ink,#e8eef9)\">#%?@</text><text class=\"tsc-final\" x=\"120\" y=\"85\" fill=\"var(--w-accent,#4fe3c1)\">WAZA</text></g>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">symbols  →  WAZA</text>\n</svg>",
   "useFor": [
    "slide",
    "lp"
   ],
   "weight": "主役",
   "relatedIds": [
    "magnetic-button",
    "stagger-char-reveal",
    "horizontal-scroll-section",
    "custom-cursor"
   ]
  },
  {
   "id": "drop-cap",
   "num": "W-033",
   "name": "Drop Cap",
   "nameJa": "ドロップキャップ",
   "category": "text",
   "description": "段落の先頭文字だけを数行分の高さに拡大し、雑誌の紙面のような印象的な導入を作る演出。initial-letterプロパティで指定し、非対応環境ではfloatとfont-sizeで代替する。",
   "useCase": "note記事やコラムの冒頭で、読み始めの視線を引きつけて世界観に引き込みたいときに使う。",
   "code": ".dcap-lead::first-letter{\n  initial-letter: 3;\n  font-weight: 800;\n  color: #4fe3c1;\n  margin-right: .08em;\n}\n@supports not (initial-letter: 3) {\n  .dcap-lead::first-letter{\n    float: left;\n    font-size: 3em;\n    line-height: .9;\n    padding-right: .08em;\n  }\n}",
   "tags": [
    "CSS",
    "::first-letter",
    "エディトリアル",
    "高級感",
    "さりげない",
    "導入"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ドロップキャップのデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"16\" y=\"20\" width=\"44\" height=\"74\" fill=\"none\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"1.4\" stroke-dasharray=\"4 3\" opacity=\".4\">\n    <animate attributeName=\"opacity\" values=\".2;.7;.2\" dur=\"3s\" repeatCount=\"indefinite\"/>\n  </rect>\n  <g transform=\"translate(24,84) scale(4.4)\">\n    <text x=\"0\" y=\"0\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"14\" font-weight=\"800\" fill=\"var(--w-ink,#e8eef9)\">T</text>\n  </g>\n  <g fill=\"var(--w-sub,#94a3c0)\">\n    <rect x=\"70\" y=\"32\" width=\"150\" height=\"7\" rx=\"3.5\" opacity=\".6\"/>\n    <rect x=\"70\" y=\"47\" width=\"150\" height=\"7\" rx=\"3.5\" opacity=\".6\"/>\n    <rect x=\"70\" y=\"62\" width=\"110\" height=\"7\" rx=\"3.5\" opacity=\".6\"/>\n    <rect x=\"16\" y=\"100\" width=\"204\" height=\"7\" rx=\"3.5\" opacity=\".4\"/>\n    <rect x=\"16\" y=\"115\" width=\"180\" height=\"7\" rx=\"3.5\" opacity=\".4\"/>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "vertical-writing",
    "selection-brand",
    "custom-scrollbar",
    "outline-text-bg"
   ]
  },
  {
   "id": "palt-tracking",
   "num": "W-034",
   "name": "Proportional Kerning (palt)",
   "nameJa": "詰め組み（palt）",
   "category": "text",
   "description": "全角文字どうしの余白を自動で詰め、字間を美しく整える日本語組版の処理。font-feature-settings: \"palt\" を指定し、letter-spacingをわずかに詰めて仕上げる。",
   "useCase": "見出しやキャッチコピーの字間が間延びして見えるとき、引き締まったプロ組版の印象にしたいときに使う。",
   "code": ".palt-title{\n  font-feature-settings: \"palt\";\n  letter-spacing: -.02em;\n}",
   "tags": [
    "CSS",
    "組版",
    "字間",
    "日本語",
    "高級感",
    "すっきり",
    "整列"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"詰め組み（palt）のデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"13\" font-weight=\"700\" fill=\"var(--w-ink,#e8eef9)\">\n    <text x=\"50\" y=\"80\">詰</text>\n    <text class=\"palt-c2\" x=\"72\" y=\"80\">め</text>\n    <text class=\"palt-c3\" x=\"94\" y=\"80\">組</text>\n    <text class=\"palt-c4\" x=\"116\" y=\"80\">み</text>\n  </g>\n  <style>\n    .palt-c2{animation:palt-x2 4s ease-in-out infinite}\n    .palt-c3{animation:palt-x3 4s ease-in-out infinite}\n    .palt-c4{animation:palt-x4 4s ease-in-out infinite}\n    @keyframes palt-x2{0%,40%{transform:translateX(0)}60%,100%{transform:translateX(-6px)}}\n    @keyframes palt-x3{0%,40%{transform:translateX(0)}60%,100%{transform:translateX(-11px)}}\n    @keyframes palt-x4{0%,40%{transform:translateX(0)}60%,100%{transform:translateX(-16px)}}\n  </style>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "hanging-punctuation",
    "text-spacing-trim",
    "line-break-strict",
    "font-feature-pwid"
   ]
  },
  {
   "id": "grid-template-areas",
   "num": "W-035",
   "name": "CSS Grid (grid-template-areas)",
   "nameJa": "グリッドエリア指定",
   "category": "layout",
   "description": "grid-template-areas でヘッダー・サイド・本文などの領域に名前を付けて配置指定するレイアウト手法。HTMLの記述順序と見た目上の配置を分離でき、コードを見ただけで画面構造が分かる。",
   "useCase": "管理画面やLPのヘッダー/サイドバー/本文/フッターなど、意味のある領域名でレイアウトの骨組みを組みたいとき。",
   "code": ".wrap{\n  display:grid;\n  grid-template-areas:\n    \"head head\"\n    \"side main\"\n    \"foot foot\";\n  grid-template-columns:120px 1fr; gap:12px;\n}\n.head{grid-area:head}\n.side{grid-area:side}\n.main{grid-area:main}\n.foot{grid-area:foot}",
   "tags": [
    "CSS",
    "グリッド",
    "レイアウト",
    "領域指定",
    "整理整頓",
    "見通しが良い",
    "レスポンシブ"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"グリッドエリア指定のデモ\">\n  <style>\n    .gta-r{fill:var(--w-sub,#94a3c0);opacity:.3}\n    .gta-a1{animation:gta-p 4s infinite}\n    .gta-a2{animation:gta-p 4s infinite;animation-delay:1s}\n    .gta-a3{animation:gta-p 4s infinite;animation-delay:2s}\n    .gta-a4{animation:gta-p 4s infinite;animation-delay:3s}\n    @keyframes gta-p{0%,15%,100%{opacity:.3;fill:var(--w-sub,#94a3c0)}5%{opacity:1;fill:var(--w-accent,#4fe3c1)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"gta-r gta-a1\" x=\"20\" y=\"15\" width=\"200\" height=\"25\" rx=\"4\"/>\n  <rect class=\"gta-r gta-a2\" x=\"20\" y=\"45\" width=\"50\" height=\"70\" rx=\"4\"/>\n  <rect class=\"gta-r gta-a3\" x=\"75\" y=\"45\" width=\"145\" height=\"70\" rx=\"4\"/>\n  <rect class=\"gta-r gta-a4\" x=\"20\" y=\"120\" width=\"200\" height=\"15\" rx=\"4\"/>\n  <text x=\"120\" y=\"31\" font-size=\"9\" fill=\"var(--w-ink,#e8eef9)\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\">head</text>\n  <text x=\"45\" y=\"83\" font-size=\"9\" fill=\"var(--w-ink,#e8eef9)\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\">side</text>\n  <text x=\"147\" y=\"83\" font-size=\"9\" fill=\"var(--w-ink,#e8eef9)\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\">main</text>\n  <text x=\"120\" y=\"130\" font-size=\"8\" fill=\"var(--w-ink,#e8eef9)\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\">foot</text>\n</svg>",
   "useFor": [
    "site",
    "lp"
   ],
   "weight": "脇役",
   "relatedIds": [
    "full-bleed-breakout",
    "vertical-embed-override",
    "logical-properties-vertical",
    "coordinate-grid-snap"
   ]
  },
  {
   "id": "subgrid",
   "num": "W-036",
   "name": "Subgrid",
   "nameJa": "サブグリッド",
   "category": "layout",
   "description": "grid-template-rows/columns に subgrid を指定すると、子グリッドが親グリッドのトラック（行・列の区切り）をそのまま引き継ぐ。離れたカード同士でも見出しや価格の高さを厳密に揃えられる。",
   "useCase": "カードを横に並べたとき、画像・タイトル・価格などの段をカード間できっちり同じ高さに揃えたいとき。",
   "code": ".cards{\n  display:grid;\n  grid-template-columns:repeat(3,1fr);\n  grid-template-rows:auto auto auto;\n  gap:16px;\n}\n.card{\n  display:grid;\n  grid-row:span 3;\n  grid-template-rows:subgrid;\n}",
   "tags": [
    "CSS",
    "グリッド",
    "サブグリッド",
    "カード",
    "きっちり",
    "ぴったり揃う",
    "普及中"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"サブグリッドのデモ\">\n  <style>\n    .sbg-row1{fill:var(--w-sub,#94a3c0);opacity:.5}\n    .sbg-row2{fill:var(--w-accent,#4fe3c1);opacity:.85}\n    .sbg-row3{fill:var(--w-sub,#94a3c0);opacity:.5}\n    .sbg-line{stroke:var(--w-amber,#ffc857);stroke-width:1.5;stroke-dasharray:4 3;opacity:0;animation:sbg-l 4s infinite}\n    @keyframes sbg-l{0%,50%{opacity:0}60%,88%{opacity:1}100%{opacity:0}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"sbg-row1\" x=\"20\" y=\"20\" width=\"55\" height=\"20\" rx=\"3\"/>\n  <rect class=\"sbg-row1\" x=\"95\" y=\"20\" width=\"55\" height=\"20\" rx=\"3\"/>\n  <rect class=\"sbg-row1\" x=\"170\" y=\"20\" width=\"55\" height=\"20\" rx=\"3\"/>\n  <rect class=\"sbg-row2\" x=\"20\" y=\"44\" width=\"55\" height=\"12\" rx=\"3\">\n    <animate attributeName=\"height\" values=\"12;12;20;20;12\" keyTimes=\"0;0.4;0.55;0.9;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </rect>\n  <rect class=\"sbg-row2\" x=\"95\" y=\"44\" width=\"55\" height=\"24\" rx=\"3\">\n    <animate attributeName=\"height\" values=\"24;24;20;20;24\" keyTimes=\"0;0.4;0.55;0.9;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </rect>\n  <rect class=\"sbg-row2\" x=\"170\" y=\"44\" width=\"55\" height=\"16\" rx=\"3\">\n    <animate attributeName=\"height\" values=\"16;16;20;20;16\" keyTimes=\"0;0.4;0.55;0.9;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </rect>\n  <rect class=\"sbg-row3\" x=\"20\" y=\"70\" width=\"55\" height=\"14\" rx=\"3\"/>\n  <rect class=\"sbg-row3\" x=\"95\" y=\"70\" width=\"55\" height=\"14\" rx=\"3\"/>\n  <rect class=\"sbg-row3\" x=\"170\" y=\"70\" width=\"55\" height=\"14\" rx=\"3\"/>\n  <line class=\"sbg-line\" x1=\"15\" y1=\"64\" x2=\"225\" y2=\"64\"/>\n  <text x=\"120\" y=\"112\" font-size=\"9\" fill=\"var(--w-sub,#94a3c0)\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\">grid-template-rows: subgrid</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "holy-grail-layout",
    "aspect-ratio",
    "centering-shortcuts",
    "corner-shape"
   ]
  },
  {
   "id": "container-queries",
   "num": "W-037",
   "name": "Container Queries (@container)",
   "nameJa": "コンテナクエリ",
   "category": "layout",
   "description": "container-type:inline-size を親に指定し、@container で自分が置かれた親要素の幅を基準にスタイルを切り替える。画面幅ではなく置き場所の幅に応じてコンポーネントが自分で形を変える。",
   "useCase": "同じカード部品をサイドバーとメインカラムなど幅の違う場所で使い回し、置き場所に応じて自動で見た目を最適化したいとき。",
   "code": ".card-wrap{container-type:inline-size;container-name:card}\n@container card (min-width:320px){\n  .card{grid-template-columns:120px 1fr}\n}\n@container card (max-width:319px){\n  .card{grid-template-columns:1fr}\n}",
   "tags": [
    "CSS",
    "コンテナクエリ",
    "レスポンシブ",
    "コンポーネント",
    "賢い",
    "パッと切替",
    "普及中"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"コンテナクエリのデモ\">\n  <style>\n    .cq-a{animation:cq-a 5s infinite}\n    .cq-b{animation:cq-b 5s infinite}\n    @keyframes cq-a{0%,35%{opacity:1}45%,90%{opacity:0}100%{opacity:1}}\n    @keyframes cq-b{0%,35%{opacity:0}45%,90%{opacity:1}100%{opacity:0}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"cq-a\">\n    <rect x=\"20\" y=\"20\" width=\"200\" height=\"100\" rx=\"6\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-dasharray=\"4 3\"/>\n    <rect x=\"32\" y=\"35\" width=\"60\" height=\"70\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".8\"/>\n    <rect x=\"104\" y=\"45\" width=\"100\" height=\"8\" rx=\"2\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".8\"/>\n    <rect x=\"104\" y=\"60\" width=\"80\" height=\"6\" rx=\"2\" fill=\"var(--w-sub,#94a3c0)\"/>\n    <rect x=\"104\" y=\"72\" width=\"90\" height=\"6\" rx=\"2\" fill=\"var(--w-sub,#94a3c0)\"/>\n    <rect x=\"104\" y=\"90\" width=\"50\" height=\"10\" rx=\"3\" fill=\"var(--w-amber,#ffc857)\"/>\n  </g>\n  <g class=\"cq-b\">\n    <rect x=\"70\" y=\"20\" width=\"100\" height=\"100\" rx=\"6\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-dasharray=\"4 3\"/>\n    <rect x=\"82\" y=\"30\" width=\"76\" height=\"42\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".8\"/>\n    <rect x=\"82\" y=\"78\" width=\"76\" height=\"7\" rx=\"2\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".8\"/>\n    <rect x=\"82\" y=\"90\" width=\"60\" height=\"6\" rx=\"2\" fill=\"var(--w-sub,#94a3c0)\"/>\n    <rect x=\"82\" y=\"102\" width=\"45\" height=\"9\" rx=\"3\" fill=\"var(--w-amber,#ffc857)\"/>\n  </g>\n  <text x=\"120\" y=\"142\" text-anchor=\"middle\" font-size=\"8\" fill=\"var(--w-sub,#94a3c0)\" font-family=\"ui-monospace,monospace\">@container</text>\n</svg>",
   "useFor": [
    "site",
    "lp"
   ],
   "weight": "脇役",
   "relatedIds": [
    "container-style-queries",
    "has-selector",
    "css-nesting",
    "css-scope"
   ]
  },
  {
   "id": "aspect-ratio",
   "num": "W-038",
   "name": "aspect-ratio",
   "nameJa": "縦横比の固定",
   "category": "layout",
   "description": "aspect-ratio プロパティで幅か高さの一方だけ指定すれば、比率どおりにもう一方が自動で決まる。従来 padding-top ハックで作っていた比率固定ボックスが1行で書ける。",
   "useCase": "動画埋め込みやサムネイル、カード画像を、幅が変わっても縦横比を崩さず並べたいとき。",
   "code": ".thumb{\n  width:100%;\n  aspect-ratio:16/9;\n  object-fit:cover;\n}\n.avatar{aspect-ratio:1;border-radius:50%}",
   "tags": [
    "CSS",
    "サムネイル",
    "比率固定",
    "レスポンシブ",
    "崩れない",
    "きっちり"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"縦横比の固定のデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"40\" y=\"30\" width=\"160\" height=\"90\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".8\">\n    <animate attributeName=\"width\" values=\"160;90;160\" keyTimes=\"0;.5;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n    <animate attributeName=\"height\" values=\"90;50.6;90\" keyTimes=\"0;.5;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n    <animate attributeName=\"x\" values=\"40;75;40\" keyTimes=\"0;.5;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n    <animate attributeName=\"y\" values=\"30;50;30\" keyTimes=\"0;.5;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </rect>\n  <text x=\"120\" y=\"138\" font-size=\"10\" fill=\"var(--w-sub,#94a3c0)\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\">aspect-ratio: 16 / 9</text>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "fullscreen-fit-scale",
    "fluid-typography",
    "fluid-spacing",
    "css-shape-function"
   ]
  },
  {
   "id": "bento-grid",
   "num": "W-039",
   "name": "Bento Grid",
   "nameJa": "ベントーグリッド",
   "category": "layout",
   "description": "grid-template-columns と grid-column/grid-row の span を組み合わせ、大小さまざまなマスをお弁当箱のように敷き詰めるレイアウト手法。情報量の差をそのままマスの大きさに変換できる。",
   "useCase": "機能紹介セクションやポートフォリオTOPで、情報量の違うカードを1画面に賑やかに見せたいとき。",
   "code": ".bento{\n  display:grid;\n  grid-template-columns:repeat(4,1fr);\n  grid-auto-rows:60px;\n  gap:10px;\n}\n.big{grid-column:span 2;grid-row:span 2}\n.wide{grid-column:span 2}",
   "tags": [
    "CSS",
    "グリッド",
    "ベントー",
    "ポートフォリオ",
    "賑やか",
    "目を引く",
    "おしゃれ"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ベントーグリッドのデモ\">\n  <style>\n    .bt-b{fill:var(--w-sub,#94a3c0);opacity:.35;animation:bt-p 5.6s infinite}\n    @keyframes bt-p{0%,8%,100%{opacity:.35;fill:var(--w-sub,#94a3c0)}3%{opacity:1;fill:var(--w-accent,#4fe3c1)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"bt-b\" x=\"20\" y=\"20\" width=\"90\" height=\"70\" rx=\"6\" style=\"animation-delay:0s\"/>\n  <rect class=\"bt-b\" x=\"120\" y=\"20\" width=\"45\" height=\"33\" rx=\"6\" style=\"animation-delay:.7s\"/>\n  <rect class=\"bt-b\" x=\"175\" y=\"20\" width=\"45\" height=\"33\" rx=\"6\" style=\"animation-delay:1.4s\"/>\n  <rect class=\"bt-b\" x=\"120\" y=\"61\" width=\"100\" height=\"29\" rx=\"6\" style=\"animation-delay:2.1s\"/>\n  <rect class=\"bt-b\" x=\"20\" y=\"100\" width=\"55\" height=\"34\" rx=\"6\" style=\"animation-delay:2.8s\"/>\n  <rect class=\"bt-b\" x=\"85\" y=\"100\" width=\"55\" height=\"34\" rx=\"6\" style=\"animation-delay:3.5s\"/>\n  <rect class=\"bt-b\" x=\"150\" y=\"100\" width=\"70\" height=\"34\" rx=\"6\" style=\"animation-delay:4.2s\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "mesh-gradient",
    "centering-shortcuts",
    "grid-template-areas",
    "subgrid"
   ]
  },
  {
   "id": "full-bleed-breakout",
   "num": "W-040",
   "name": "Full-Bleed Breakout Grid",
   "nameJa": "マガジン風ブレイクアウト",
   "category": "layout",
   "description": "3列グリッド grid-template-columns:1fr min(65ch,100%) 1fr で本文幅の列を作り、目立たせたい要素だけ grid-column:1/-1 にして画面端まで breakout させる構成。",
   "useCase": "雑誌風の記事LPで、見出し画像だけ画面幅いっぱいに広げ、本文は読みやすい幅に保ちたいとき。",
   "code": ".layout{\n  display:grid;\n  grid-template-columns:\n    1fr min(65ch,100%) 1fr;\n}\n.layout>*{grid-column:2}\n.breakout{grid-column:1/-1}",
   "tags": [
    "CSS",
    "グリッド",
    "マガジン風",
    "ブレイクアウト",
    "大胆",
    "メリハリ",
    "レスポンシブ"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"マガジン風ブレイクアウトのデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <line x1=\"70\" y1=\"10\" x2=\"70\" y2=\"140\" stroke=\"var(--w-sub,#94a3c0)\" stroke-dasharray=\"3 3\" opacity=\".5\"/>\n  <line x1=\"170\" y1=\"10\" x2=\"170\" y2=\"140\" stroke=\"var(--w-sub,#94a3c0)\" stroke-dasharray=\"3 3\" opacity=\".5\"/>\n  <rect x=\"80\" y=\"20\" width=\"80\" height=\"8\" rx=\"2\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".8\"/>\n  <rect x=\"80\" y=\"34\" width=\"80\" height=\"6\" rx=\"2\" fill=\"var(--w-sub,#94a3c0)\"/>\n  <rect x=\"70\" y=\"50\" width=\"100\" height=\"40\" rx=\"4\" fill=\"var(--w-amber,#ffc857)\" opacity=\".85\">\n    <animate attributeName=\"x\" values=\"70;20;70\" keyTimes=\"0;.5;1\" dur=\"4.5s\" repeatCount=\"indefinite\"/>\n    <animate attributeName=\"width\" values=\"100;200;100\" keyTimes=\"0;.5;1\" dur=\"4.5s\" repeatCount=\"indefinite\"/>\n  </rect>\n  <rect x=\"80\" y=\"98\" width=\"80\" height=\"6\" rx=\"2\" fill=\"var(--w-sub,#94a3c0)\"/>\n  <rect x=\"80\" y=\"110\" width=\"60\" height=\"6\" rx=\"2\" fill=\"var(--w-sub,#94a3c0)\"/>\n  <text x=\"120\" y=\"144\" text-anchor=\"middle\" font-size=\"8\" fill=\"var(--w-amber,#ffc857)\" font-family=\"ui-monospace,monospace\">grid-column: 1 / -1</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "grid-template-areas",
    "aspect-ratio",
    "fluid-typography",
    "fluid-spacing"
   ]
  },
  {
   "id": "fluid-typography",
   "num": "W-041",
   "name": "Fluid Typography (clamp())",
   "nameJa": "流体タイポグラフィ",
   "category": "layout",
   "description": "font-size に clamp(最小値, 可変値, 最大値) を使い、ビューポート幅に応じてブレークポイント無しで文字サイズが連続的に変化する。上限と下限を超えて縮み過ぎ・伸び過ぎることもない。",
   "useCase": "見出しをスマホからワイドモニターまで、メディアクエリを書かずに自然に追従させたいとき。",
   "code": "h1{\n  font-size:clamp(1.5rem, 4vw + 1rem, 3.5rem);\n}\np{\n  font-size:clamp(0.95rem, 0.5vw + 0.85rem, 1.125rem);\n}",
   "tags": [
    "CSS",
    "タイポグラフィ",
    "流体",
    "レスポンシブ",
    "なめらか",
    "心地よい"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"流体タイポグラフィのデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"10\" y=\"65\" width=\"220\" height=\"55\" rx=\"6\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-dasharray=\"4 3\">\n    <animate attributeName=\"width\" values=\"220;140;60;140;220\" keyTimes=\"0;.3;.5;.7;1\" dur=\"4.5s\" repeatCount=\"indefinite\"/>\n    <animate attributeName=\"x\" values=\"10;50;90;50;10\" keyTimes=\"0;.3;.5;.7;1\" dur=\"4.5s\" repeatCount=\"indefinite\"/>\n  </rect>\n  <text x=\"120\" y=\"100\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-weight=\"700\" fill=\"var(--w-ink,#e8eef9)\" font-size=\"14\">Aa\n    <animate attributeName=\"font-size\" values=\"14;11;8;11;14\" keyTimes=\"0;.3;.5;.7;1\" dur=\"4.5s\" repeatCount=\"indefinite\"/>\n  </text>\n  <text x=\"120\" y=\"30\" text-anchor=\"middle\" font-size=\"9\" fill=\"var(--w-sub,#94a3c0)\" font-family=\"ui-monospace,monospace\">clamp(1rem, 4vw, 3.5rem)</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "fluid-spacing",
    "text-box-trim",
    "text-autospace",
    "aspect-ratio"
   ]
  },
  {
   "id": "fluid-spacing",
   "num": "W-042",
   "name": "Fluid Spacing",
   "nameJa": "流体スペーシング",
   "category": "layout",
   "description": "padding や gap にも clamp() を使い、余白をビューポート幅に応じて連続的に変化させる手法。ブレークポイントごとに余白を書き分ける手間がなくなる。",
   "useCase": "セクションの余白をスマホでは詰めて、デスクトップではゆったり見せたいとき。",
   "code": ".section{\n  padding-block:clamp(24px, 6vw, 96px);\n  padding-inline:clamp(16px, 5vw, 64px);\n}\n.stack{gap:clamp(8px, 2vw, 24px)}",
   "tags": [
    "CSS",
    "スペーシング",
    "流体",
    "レスポンシブ",
    "ゆったり",
    "なめらか"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"流体スペーシングのデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"20\" y=\"20\" width=\"200\" height=\"110\" rx=\"6\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-dasharray=\"4 3\"/>\n  <rect x=\"28\" y=\"28\" width=\"184\" height=\"94\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".75\">\n    <animate attributeName=\"x\" values=\"28;44;28\" keyTimes=\"0;.5;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n    <animate attributeName=\"y\" values=\"28;44;28\" keyTimes=\"0;.5;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n    <animate attributeName=\"width\" values=\"184;152;184\" keyTimes=\"0;.5;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n    <animate attributeName=\"height\" values=\"94;62;94\" keyTimes=\"0;.5;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </rect>\n  <text x=\"120\" y=\"14\" text-anchor=\"middle\" font-size=\"9\" fill=\"var(--w-sub,#94a3c0)\" font-family=\"ui-monospace,monospace\">padding: clamp()</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "fluid-typography",
    "aspect-ratio",
    "css-shape-function",
    "grid-template-areas"
   ]
  },
  {
   "id": "masonry-columns",
   "num": "W-043",
   "name": "Pseudo Masonry (columns)",
   "nameJa": "擬似マソンリー（columns）",
   "category": "layout",
   "description": "CSS多段組み columns を使い、高さの異なるカードを列ごとに縦詰めに配置する擬似マソンリー。真のグリッドmasonryは仕様策定中のため、現状はcolumnsで代用するのが定番。",
   "useCase": "Pinterest風のギャラリーや、高さの揃わない画像カード一覧を隙間なく詰めたいとき。",
   "code": ".gallery{\n  columns:3 220px;\n  column-gap:12px;\n}\n.gallery>*{\n  break-inside:avoid;\n  margin-bottom:12px;\n}",
   "tags": [
    "CSS",
    "マソンリー",
    "ギャラリー",
    "段組み",
    "詰まって見える",
    "リズミカル",
    "Pinterest風"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"擬似マソンリーのデモ\">\n  <style>\n    .ms-b{fill:var(--w-accent,#4fe3c1);animation:ms-p 5s infinite}\n    @keyframes ms-p{0%,10%,100%{opacity:.3}4%{opacity:1}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"ms-b\" x=\"20\" y=\"20\" width=\"55\" height=\"30\" rx=\"4\" style=\"animation-delay:0s\"/>\n  <rect class=\"ms-b\" x=\"20\" y=\"54\" width=\"55\" height=\"45\" rx=\"4\" style=\"animation-delay:.45s\"/>\n  <rect class=\"ms-b\" x=\"20\" y=\"103\" width=\"55\" height=\"20\" rx=\"4\" style=\"animation-delay:.9s\"/>\n  <rect class=\"ms-b\" x=\"95\" y=\"20\" width=\"55\" height=\"50\" rx=\"4\" style=\"animation-delay:1.5s\"/>\n  <rect class=\"ms-b\" x=\"95\" y=\"74\" width=\"55\" height=\"35\" rx=\"4\" style=\"animation-delay:1.95s\"/>\n  <rect class=\"ms-b\" x=\"170\" y=\"20\" width=\"55\" height=\"25\" rx=\"4\" style=\"animation-delay:2.6s\"/>\n  <rect class=\"ms-b\" x=\"170\" y=\"49\" width=\"55\" height=\"40\" rx=\"4\" style=\"animation-delay:3.05s\"/>\n  <rect class=\"ms-b\" x=\"170\" y=\"93\" width=\"55\" height=\"30\" rx=\"4\" style=\"animation-delay:3.5s\"/>\n</svg>",
   "useFor": [
    "site",
    "lp"
   ],
   "weight": "主役",
   "relatedIds": [
    "grid-lanes",
    "ring-gallery",
    "carousel-3d",
    "content-visibility"
   ]
  },
  {
   "id": "centering-shortcuts",
   "num": "W-044",
   "name": "Centering Shortcuts",
   "nameJa": "中央寄せの最短手",
   "category": "layout",
   "description": "place-content:center や place-items:center、margin:auto など、要素を上下左右中央に揃える最短のCSS手段をまとめた定石。position:absoluteの計算いらずで一発で決まる。",
   "useCase": "モーダルやローディング表示、ヒーローセクションの中身を1行で確実に中央揃えしたいとき。",
   "code": ".center-grid{\n  display:grid;\n  place-items:center;\n  min-height:100dvh;\n}\n.center-flex{\n  display:flex;\n  align-items:center;\n  justify-content:center;\n}",
   "tags": [
    "CSS",
    "中央寄せ",
    "グリッド",
    "フレックス",
    "一発で決まる",
    "安心"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"中央寄せの最短手のデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"20\" y=\"20\" width=\"200\" height=\"110\" rx=\"6\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-dasharray=\"4 3\"/>\n  <line x1=\"120\" y1=\"20\" x2=\"120\" y2=\"130\" stroke=\"var(--w-sub,#94a3c0)\" stroke-dasharray=\"2 4\" opacity=\".5\"/>\n  <line x1=\"20\" y1=\"75\" x2=\"220\" y2=\"75\" stroke=\"var(--w-sub,#94a3c0)\" stroke-dasharray=\"2 4\" opacity=\".5\"/>\n  <circle cx=\"40\" cy=\"40\" r=\"12\" fill=\"var(--w-amber,#ffc857)\">\n    <animate attributeName=\"cx\" values=\"40;120;120;40\" keyTimes=\"0;.4;.8;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n    <animate attributeName=\"cy\" values=\"40;75;75;40\" keyTimes=\"0;.4;.8;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n    <animate attributeName=\"r\" values=\"12;12;15;12\" keyTimes=\"0;.4;.6;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </circle>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "holy-grail-layout",
    "safe-area-inset",
    "grid-template-areas",
    "subgrid"
   ]
  },
  {
   "id": "grid-stack",
   "num": "W-045",
   "name": "Grid Stack Overlay",
   "nameJa": "グリッドで要素を重ねる",
   "category": "layout",
   "description": "同じ grid-area（または grid-row/column:1/1）を複数の子要素に指定し、position:absoluteを使わずグリッドの1マスへ重ね配置する。ドキュメントの流れの中で重ねられるのが利点。",
   "useCase": "画像の上にタイトルやグラデーションを重ねるヒーロー画像・カードのオーバーレイを組みたいとき。",
   "code": ".stack{\n  display:grid;\n}\n.stack>*{\n  grid-area:1/1;\n}\n.stack img{width:100%;height:100%;object-fit:cover}\n.stack .overlay{align-self:end;padding:16px}",
   "tags": [
    "CSS",
    "グリッド",
    "重ね",
    "オーバーレイ",
    "position不要",
    "スタイリッシュ",
    "奥行き感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"グリッドで要素を重ねるのデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"30\" y=\"20\" width=\"180\" height=\"100\" rx=\"6\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-dasharray=\"4 3\"/>\n  <rect x=\"30\" y=\"20\" width=\"180\" height=\"100\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".25\"/>\n  <rect x=\"30\" width=\"180\" height=\"30\" fill=\"var(--w-bg,#101830)\" opacity=\".75\">\n    <animate attributeName=\"y\" values=\"150;90;90;150\" keyTimes=\"0;.3;.8;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </rect>\n  <text x=\"40\" font-size=\"10\" fill=\"var(--w-ink,#e8eef9)\" font-family=\"ui-monospace,monospace\">grid-area: 1 / 1\n    <animate attributeName=\"y\" values=\"170;110;110;170\" keyTimes=\"0;.3;.8;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "centering-shortcuts",
    "grid-template-areas",
    "subgrid",
    "bento-grid"
   ]
  },
  {
   "id": "holy-grail-layout",
   "num": "W-046",
   "name": "Holy Grail App Shell",
   "nameJa": "ホーリーグレイル型アプリシェル",
   "category": "layout",
   "description": "grid-template でヘッダー・フッター固定、左右サイドバー固定、中央だけ1frで伸縮するアプリの定番シェル構成を1宣言で組む。かつてfloatやtableで苦労した構成がGridなら一発。",
   "useCase": "管理画面やチャットアプリなど、ヘッダー/サイド2本/本文/フッターを持つ画面の土台を作るとき。",
   "code": ".shell{\n  display:grid;\n  grid-template:\n    \"head head head\" auto\n    \"nav  main  aside\" 1fr\n    \"foot foot foot\" auto\n    / 160px 1fr 160px;\n  height:100dvh;\n}",
   "tags": [
    "CSS",
    "グリッド",
    "アプリシェル",
    "管理画面",
    "土台",
    "きっちり",
    "安心"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ホーリーグレイル型アプリシェルのデモ\">\n  <style>\n    .hg-main{animation:hg-b 3s ease-in-out infinite}\n    @keyframes hg-b{0%,100%{opacity:.35}50%{opacity:.85}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"20\" y=\"15\" width=\"200\" height=\"18\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/>\n  <rect x=\"20\" y=\"38\" width=\"45\" height=\"80\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/>\n  <rect x=\"175\" y=\"38\" width=\"45\" height=\"80\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/>\n  <rect class=\"hg-main\" x=\"70\" y=\"38\" width=\"100\" height=\"80\" rx=\"3\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <rect x=\"20\" y=\"123\" width=\"200\" height=\"12\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/>\n  <text x=\"120\" y=\"82\" text-anchor=\"middle\" font-size=\"9\" fill=\"var(--w-bg,#101830)\" font-family=\"ui-monospace,monospace\">1fr</text>\n</svg>",
   "useFor": [
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "centering-shortcuts",
    "subgrid",
    "aspect-ratio",
    "safe-area-inset"
   ]
  },
  {
   "id": "dvh-svh",
   "num": "W-047",
   "name": "Dynamic Viewport Units (dvh/svh)",
   "nameJa": "動的ビューポート単位（dvh/svh）",
   "category": "layout",
   "description": "モバイルはアドレスバーの出し入れで100vhの基準が揺れる。dvh（実表示に追従）・svh（最小時基準）・lvh（最大時基準）を使い分ければ、その揺れを吸収できる。",
   "useCase": "スマホでヒーローセクションやモーダルの高さを画面ぴったりに保ち、下に隙間や見切れを作りたくないとき。",
   "code": ".hero{\n  height:100vh; /* NG: アドレスバーで揺れる */\n  height:100dvh; /* OK: 実表示領域に追従 */\n}",
   "tags": [
    "CSS",
    "ビューポート",
    "モバイル",
    "dvh",
    "ガタつかない",
    "ぴったり",
    "普及中"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"動的ビューポート単位のデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"15\" y=\"15\" width=\"85\" height=\"110\" rx=\"8\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\"/>\n  <rect x=\"140\" y=\"15\" width=\"85\" height=\"110\" rx=\"8\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\"/>\n  <rect x=\"15\" y=\"15\" width=\"85\" fill=\"var(--w-amber,#ffc857)\" opacity=\".7\">\n    <animate attributeName=\"height\" values=\"0;14;14;0\" keyTimes=\"0;.3;.7;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </rect>\n  <rect x=\"140\" y=\"15\" width=\"85\" fill=\"var(--w-amber,#ffc857)\" opacity=\".7\">\n    <animate attributeName=\"height\" values=\"0;14;14;0\" keyTimes=\"0;.3;.7;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </rect>\n  <rect x=\"15\" y=\"29\" width=\"85\" height=\"96\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".55\"/>\n  <rect x=\"140\" width=\"85\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\">\n    <animate attributeName=\"y\" values=\"15;29;29;15\" keyTimes=\"0;.3;.7;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n    <animate attributeName=\"height\" values=\"110;96;96;110\" keyTimes=\"0;.3;.7;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </rect>\n  <text x=\"57\" y=\"140\" text-anchor=\"middle\" font-size=\"9\" fill=\"var(--w-sub,#94a3c0)\" font-family=\"ui-monospace,monospace\">100vh</text>\n  <text x=\"182\" y=\"140\" text-anchor=\"middle\" font-size=\"9\" fill=\"var(--w-accent,#4fe3c1)\" font-family=\"ui-monospace,monospace\">100dvh</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "subgrid",
    "container-queries",
    "has-selector",
    "has-selector-interact"
   ]
  },
  {
   "id": "logical-properties",
   "num": "W-048",
   "name": "Logical Properties",
   "nameJa": "論理プロパティ",
   "category": "layout",
   "description": "margin-inline や padding-block、border-inline-start のように、top/leftなど物理方向でなく書字方向を基準に余白・罫線を指定するプロパティ群。directionが変わってもCSSを書き換えずに反転する。",
   "useCase": "多言語サイトや将来のRTL対応を見据えて、余白・罫線の指定を書き換え不要にしておきたいとき。",
   "code": ".card{\n  padding-block:16px;\n  padding-inline:24px;\n  margin-inline-start:auto;\n  border-inline-start:4px solid var(--accent);\n}",
   "tags": [
    "CSS",
    "論理プロパティ",
    "多言語",
    "RTL対応",
    "反転しても崩れない",
    "スマート"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"論理プロパティのデモ\">\n  <style>\n    .lp-a{animation:lp-a 5s infinite}\n    .lp-b{animation:lp-b 5s infinite}\n    @keyframes lp-a{0%,40%{opacity:1}50%,90%{opacity:0}100%{opacity:1}}\n    @keyframes lp-b{0%,40%{opacity:0}50%,90%{opacity:1}100%{opacity:0}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"lp-a\">\n    <rect x=\"40\" y=\"35\" width=\"160\" height=\"80\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".25\"/>\n    <rect x=\"40\" y=\"35\" width=\"6\" height=\"80\" fill=\"var(--w-accent,#4fe3c1)\"/>\n    <rect x=\"56\" y=\"50\" width=\"90\" height=\"8\" rx=\"2\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".8\"/>\n    <rect x=\"56\" y=\"66\" width=\"70\" height=\"6\" rx=\"2\" fill=\"var(--w-sub,#94a3c0)\"/>\n    <text x=\"120\" y=\"130\" text-anchor=\"middle\" font-size=\"9\" fill=\"var(--w-sub,#94a3c0)\" font-family=\"ui-monospace,monospace\">direction: ltr</text>\n  </g>\n  <g class=\"lp-b\">\n    <rect x=\"40\" y=\"35\" width=\"160\" height=\"80\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".25\"/>\n    <rect x=\"194\" y=\"35\" width=\"6\" height=\"80\" fill=\"var(--w-accent,#4fe3c1)\"/>\n    <rect x=\"94\" y=\"50\" width=\"90\" height=\"8\" rx=\"2\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".8\"/>\n    <rect x=\"114\" y=\"66\" width=\"70\" height=\"6\" rx=\"2\" fill=\"var(--w-sub,#94a3c0)\"/>\n    <text x=\"120\" y=\"130\" text-anchor=\"middle\" font-size=\"9\" fill=\"var(--w-amber,#ffc857)\" font-family=\"ui-monospace,monospace\">direction: rtl</text>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "has-selector-interact",
    "grid-lanes",
    "content-visibility",
    "container-style-queries"
   ]
  },
  {
   "id": "has-selector",
   "num": "W-049",
   "name": ":has() Layout Branching",
   "nameJa": ":has()でレイアウト分岐",
   "category": "layout",
   "description": "親要素が特定の子を持つかどうかで自分自身のスタイルを変える :has() 疑似クラス。画像の有無やフォームのエラー状態など、JSのクラス切り替え無しで条件付きレイアウトが組める。",
   "useCase": "画像付き投稿だけ2カラムにする、フォームにエラーがある時だけ枠を強調するなど条件分岐レイアウトをCSSだけで組みたいとき。",
   "code": ".card{grid-template-columns:1fr}\n.card:has(img){\n  grid-template-columns:96px 1fr;\n}\nform:has(:invalid){\n  border-color:var(--danger);\n}",
   "tags": [
    "CSS",
    "疑似クラス",
    "条件分岐",
    "JS不要",
    "賢い",
    "スッと切り替わる",
    "普及中"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\":has()でレイアウト分岐のデモ\">\n  <style>\n    .hs-a{animation:hs-a 4.5s infinite}\n    .hs-b{animation:hs-b 4.5s infinite}\n    @keyframes hs-a{0%,35%{opacity:1}45%,90%{opacity:0}100%{opacity:1}}\n    @keyframes hs-b{0%,35%{opacity:0}45%,90%{opacity:1}100%{opacity:0}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"30\" y=\"30\" width=\"180\" height=\"90\" rx=\"6\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-dasharray=\"4 3\"/>\n  <g class=\"hs-a\">\n    <rect x=\"42\" y=\"50\" width=\"156\" height=\"8\" rx=\"2\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".8\"/>\n    <rect x=\"42\" y=\"66\" width=\"130\" height=\"6\" rx=\"2\" fill=\"var(--w-sub,#94a3c0)\"/>\n    <rect x=\"42\" y=\"80\" width=\"140\" height=\"6\" rx=\"2\" fill=\"var(--w-sub,#94a3c0)\"/>\n  </g>\n  <g class=\"hs-b\">\n    <rect x=\"42\" y=\"45\" width=\"60\" height=\"60\" rx=\"4\" fill=\"var(--w-amber,#ffc857)\" opacity=\".85\"/>\n    <rect x=\"114\" y=\"50\" width=\"84\" height=\"8\" rx=\"2\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".8\"/>\n    <rect x=\"114\" y=\"66\" width=\"70\" height=\"6\" rx=\"2\" fill=\"var(--w-sub,#94a3c0)\"/>\n    <rect x=\"114\" y=\"80\" width=\"75\" height=\"6\" rx=\"2\" fill=\"var(--w-sub,#94a3c0)\"/>\n  </g>\n  <text x=\"120\" y=\"140\" text-anchor=\"middle\" font-size=\"9\" fill=\"var(--w-accent,#4fe3c1)\" font-family=\"ui-monospace,monospace\">:has(img)</text>\n</svg>",
   "useFor": [
    "site",
    "lp"
   ],
   "weight": "脇役",
   "relatedIds": [
    "container-queries",
    "subgrid",
    "dvh-svh",
    "has-selector-interact"
   ]
  },
  {
   "id": "flex-grid-gap",
   "num": "W-050",
   "name": "Gap for Flex/Grid",
   "nameJa": "gapで余白統一",
   "category": "layout",
   "description": "子要素のmarginを個別に計算するのをやめ、flexやgridの gap プロパティで要素間の間隔を一括指定する。最後の要素だけ余白が余る・親のパディングと二重になる事故がなくなる。",
   "useCase": "ボタン列やカード一覧の隙間を、子要素のmargin管理なしで均等にきれいに揃えたいとき。",
   "code": ".row{\n  display:flex;\n  gap:12px;\n}\n.grid{\n  display:grid;\n  grid-template-columns:repeat(auto-fill,minmax(120px,1fr));\n  gap:16px;\n}",
   "tags": [
    "CSS",
    "flex",
    "グリッド",
    "gap",
    "余白統一",
    "きれいに並ぶ",
    "すっきり"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"gapで余白統一のデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"20\" y=\"45\" width=\"36\" height=\"60\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\"/>\n  <rect y=\"45\" width=\"36\" height=\"60\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\">\n    <animate attributeName=\"x\" values=\"62;74;62\" keyTimes=\"0;.5;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </rect>\n  <rect y=\"45\" width=\"36\" height=\"60\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\">\n    <animate attributeName=\"x\" values=\"104;128;104\" keyTimes=\"0;.5;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </rect>\n  <rect y=\"45\" width=\"36\" height=\"60\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\">\n    <animate attributeName=\"x\" values=\"146;182;146\" keyTimes=\"0;.5;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </rect>\n  <line x1=\"56\" y1=\"118\" x2=\"62\" y2=\"118\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"2\" stroke-dasharray=\"3 2\">\n    <animate attributeName=\"x2\" values=\"62;74;62\" keyTimes=\"0;.5;1\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </line>\n  <text x=\"120\" y=\"135\" text-anchor=\"middle\" font-size=\"9\" fill=\"var(--w-sub,#94a3c0)\" font-family=\"ui-monospace,monospace\">gap</text>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "reading-flow",
    "centering-shortcuts",
    "text-spacing-trim",
    "font-feature-pwid"
   ]
  },
  {
   "id": "safe-area-inset",
   "num": "W-051",
   "name": "Safe Area Insets",
   "nameJa": "セーフエリア対応",
   "category": "layout",
   "description": "env(safe-area-inset-top/bottom/left/right) を使い、ノッチや丸角、ホームインジケーターに被らないよう端末側が教えてくれる分だけパディングを足す。数値をハードコードしなくていい。",
   "useCase": "iPhoneのノッチ・丸角・ホームバーに、固定ヘッダーやボトムナビの中身が隠されないようにしたいとき。",
   "code": ".bottom-nav{\n  padding-bottom:calc(12px + env(safe-area-inset-bottom));\n}\n.header{\n  padding-top:env(safe-area-inset-top, 0px);\n}",
   "tags": [
    "CSS",
    "iPhone",
    "ノッチ対応",
    "safe-area",
    "はみ出さない",
    "安心"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"セーフエリア対応のデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"70\" y=\"10\" width=\"100\" height=\"130\" rx=\"18\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\"/>\n  <rect x=\"80\" width=\"80\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".8\">\n    <animate attributeName=\"y\" values=\"10;24;24;10\" keyTimes=\"0;.35;.75;1\" dur=\"4.5s\" repeatCount=\"indefinite\"/>\n    <animate attributeName=\"height\" values=\"120;100;100;120\" keyTimes=\"0;.35;.75;1\" dur=\"4.5s\" repeatCount=\"indefinite\"/>\n  </rect>\n  <rect x=\"100\" y=\"10\" width=\"40\" height=\"10\" rx=\"5\" fill=\"var(--w-bg,#101830)\" stroke=\"var(--w-sub,#94a3c0)\"/>\n  <rect x=\"100\" y=\"132\" width=\"40\" height=\"4\" rx=\"2\" fill=\"var(--w-sub,#94a3c0)\"/>\n  <text x=\"120\" y=\"145\" text-anchor=\"middle\" font-size=\"8\" fill=\"var(--w-sub,#94a3c0)\" font-family=\"ui-monospace,monospace\">env(safe-area-inset-*)</text>\n</svg>",
   "useFor": [
    "site",
    "lp"
   ],
   "weight": "脇役",
   "relatedIds": [
    "centering-shortcuts",
    "holy-grail-layout",
    "grid-lanes",
    "content-visibility"
   ]
  },
  {
   "id": "media-preferences",
   "num": "W-052",
   "name": "prefers-* Media Queries",
   "nameJa": "OS設定への追従",
   "category": "layout",
   "description": "prefers-color-scheme でOSのダーク/ライト設定に自動追従し、prefers-reduced-motion でアニメを控えめにする。ユーザーがOS側で選んだ設定を、聞かずに尊重するメディアクエリ。",
   "useCase": "ダークモード端末の利用者や、前庭障害配慮でアニメを減らしたい人に、設定画面を作らず最適な見た目を出したいとき。",
   "code": "@media (prefers-color-scheme:dark){\n  :root{--bg:#101830;--ink:#e8eef9}\n}\n@media (prefers-reduced-motion:reduce){\n  *{animation-duration:0.001ms!important}\n}",
   "tags": [
    "CSS",
    "ダークモード",
    "アクセシビリティ",
    "OS設定",
    "自動追従",
    "気遣い"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"OS設定への追従のデモ\">\n  <style>\n    .mp-a{animation:mp-a 5s infinite}\n    .mp-b{animation:mp-b 5s infinite}\n    @keyframes mp-a{0%,40%{opacity:1}50%,90%{opacity:0}100%{opacity:1}}\n    @keyframes mp-b{0%,40%{opacity:0}50%,90%{opacity:1}100%{opacity:0}}\n    .mp-dot{animation:mp-move 1.2s ease-in-out infinite alternate}\n    @keyframes mp-move{0%{transform:translateX(0)}100%{transform:translateX(30px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"mp-a\">\n    <rect x=\"20\" y=\"20\" width=\"90\" height=\"110\" rx=\"6\" fill=\"var(--w-bg,#101830)\" stroke=\"var(--w-sub,#94a3c0)\"/>\n    <circle cx=\"65\" cy=\"45\" r=\"10\" fill=\"var(--w-accent,#4fe3c1)\"/>\n    <text x=\"65\" y=\"80\" text-anchor=\"middle\" font-size=\"9\" fill=\"var(--w-ink,#e8eef9)\" font-family=\"ui-monospace,monospace\">dark</text>\n  </g>\n  <g class=\"mp-b\">\n    <rect x=\"20\" y=\"20\" width=\"90\" height=\"110\" rx=\"6\" fill=\"var(--w-ink,#e8eef9)\" stroke=\"var(--w-sub,#94a3c0)\"/>\n    <circle cx=\"65\" cy=\"45\" r=\"10\" fill=\"var(--w-amber,#ffc857)\"/>\n    <text x=\"65\" y=\"80\" text-anchor=\"middle\" font-size=\"9\" fill=\"var(--w-bg,#101830)\" font-family=\"ui-monospace,monospace\">light</text>\n  </g>\n  <line x1=\"130\" y1=\"20\" x2=\"130\" y2=\"130\" stroke=\"var(--w-sub,#94a3c0)\" opacity=\".4\"/>\n  <line x1=\"150\" y1=\"75\" x2=\"210\" y2=\"75\" stroke=\"var(--w-sub,#94a3c0)\" stroke-dasharray=\"3 3\" opacity=\".5\"/>\n  <circle class=\"mp-dot\" cx=\"150\" cy=\"75\" r=\"8\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <text x=\"180\" y=\"115\" text-anchor=\"middle\" font-size=\"9\" fill=\"var(--w-sub,#94a3c0)\" font-family=\"ui-monospace,monospace\">motion</text>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "reading-flow",
    "css-scroll-controls",
    "customizable-select",
    "contrast-color"
   ]
  },
  {
   "id": "clip-path-polygon",
   "num": "W-053",
   "name": "Clip-path Polygon Slice",
   "nameJa": "斜め切り (ポリゴンクリップ)",
   "category": "shape",
   "description": "要素を任意の多角形で切り抜く。clip-path: polygon(x y, ...)で頂点座標を指定し、四角形を斜めにカットしたセクション境界や見出し背景を作る。",
   "useCase": "LPのセクション境界やヒーロー背景を斜めにカットして動きのある印象に。画像への適用でも効果的。",
   "code": ".cppg-hero {\n  clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%);\n}",
   "tags": [
    "CSS",
    "clip-path",
    "LP",
    "セクション",
    "斜め",
    "ダイナミック",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"斜め切り(ポリゴンクリップ)のデモ\">\n  <style>\n    .cppg-top{animation:cppg-shift 4s ease-in-out infinite}\n    @keyframes cppg-shift{0%,100%{transform:translateY(0)}50%{transform:translateY(-10px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <polygon points=\"0,95 240,70 240,150 0,150\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".35\"/>\n  <polygon class=\"cppg-top\" points=\"0,80 240,55 240,0 0,0\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".9\"/>\n  <line x1=\"0\" y1=\"80\" x2=\"240\" y2=\"55\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"2\" stroke-dasharray=\"4 3\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "mix-blend-mode",
    "text-stroke-outline",
    "neon-glow-text",
    "blend-difference-text"
   ]
  },
  {
   "id": "clip-path-shapes",
   "num": "W-054",
   "name": "Clip-path Basic Shapes",
   "nameJa": "円形・矩形の切り抜き (inset/circle)",
   "category": "shape",
   "description": "clip-path: circle()やinset()で画像や要素を円形・角丸矩形に切り抜く。ホバーで半径や位置を変えると形が滑らかに変形する。",
   "useCase": "プロフィール画像を丸く切り抜く、カード画像をホバーで拡大する円形マスク演出などに使う。",
   "code": ".cpsh-avatar {\n  clip-path: circle(50%);\n  transition: clip-path .4s ease;\n}\n.cpsh-avatar:hover {\n  clip-path: circle(65%);\n}",
   "tags": [
    "CSS",
    "clip-path",
    "ホバー",
    "円形",
    "トリミング",
    "ぬるっと",
    "さりげない"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"円形・矩形の切り抜きのデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"60\" y=\"20\" width=\"120\" height=\"110\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".25\"/>\n  <circle cx=\"120\" cy=\"75\" r=\"38\" fill=\"var(--w-accent,#4fe3c1)\">\n    <animate attributeName=\"r\" values=\"38;50;38\" dur=\"3.5s\" repeatCount=\"indefinite\"/>\n  </circle>\n  <circle cx=\"120\" cy=\"75\" r=\"50\" fill=\"none\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"1.5\" stroke-dasharray=\"3 3\" opacity=\".7\"/>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "caption-slide-in",
    "filter-effects",
    "variable-font-weight",
    "hover-pause"
   ]
  },
  {
   "id": "clip-path-reveal",
   "num": "W-055",
   "name": "Clip-path Reveal Animation",
   "nameJa": "クリップパスでリビール表示",
   "category": "shape",
   "description": "clip-path: inset()やpolygon()の値をtransitionやkeyframesで変化させ、要素が徐々に現れる/隠れるリビール演出を作る。",
   "useCase": "スクロール表示や画像ホバー時に、カーテンが開くように要素を出現させたいときに使う。",
   "code": ".cprv-panel {\n  clip-path: inset(0 100% 0 0);\n  transition: clip-path .8s cubic-bezier(.7,0,.2,1);\n}\n.cprv-panel.is-visible {\n  clip-path: inset(0 0 0 0);\n}",
   "tags": [
    "CSS",
    "clip-path",
    "スクロール",
    "リビール",
    "アニメーション",
    "ふわっと",
    "没入感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"クリップパスでリビール表示のデモ\">\n  <style>\n    .cprv-mask{animation:cprv-wipe 3s ease-in-out infinite}\n    @keyframes cprv-wipe{0%{width:0px}45%,55%{width:240px}100%{width:0px}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <text x=\"120\" y=\"80\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"28\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".3\">REVEAL</text>\n  <clipPath id=\"cprv-clip\"><rect class=\"cprv-mask\" x=\"0\" y=\"0\" height=\"150\"/></clipPath>\n  <g clip-path=\"url(#cprv-clip)\">\n    <text x=\"120\" y=\"80\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"28\" fill=\"var(--w-accent,#4fe3c1)\">REVEAL</text>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "view-timeline-reveal",
    "image-clip-reveal",
    "vertical-scroll-snap",
    "typewriter"
   ]
  },
  {
   "id": "svg-clip-path",
   "num": "W-056",
   "name": "SVG clipPath Element",
   "nameJa": "SVGクリップパスで自由形状に切り抜く",
   "category": "shape",
   "description": "SVGの<clipPath>要素に任意のパスや図形を定義し、CSSからclip-path: url(#id)で画像やdivを星形・波形など自由な輪郭に切り抜く。",
   "useCase": "ロゴ型・星型・特殊アイコン型に画像をトリミングしたいバナーやカードに使う。",
   "code": "<svg width=\"0\" height=\"0\">\n  <clipPath id=\"star-clip\" clipPathUnits=\"objectBoundingBox\">\n    <path d=\"M.5 0 .62 .35 1 .38 .7 .6 .82 1 .5 .78 .18 1 .3 .6 0 .38 .38 .35Z\"/>\n  </clipPath>\n</svg>\n<img class=\"scp-img\" style=\"clip-path:url(#star-clip)\" src=\"photo.jpg\">",
   "tags": [
    "SVG",
    "clip-path",
    "マスク",
    "自由形状",
    "バナー",
    "目を引く",
    "高級感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"SVGクリップパスで自由形状に切り抜くのデモ\">\n  <style>\n    .scpe-fill{animation:scpe-pulse 3.5s ease-in-out infinite}\n    @keyframes scpe-pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.08)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <clipPath id=\"scpe-star\">\n    <path d=\"M120 25 132 63 172 63 140 86 152 124 120 101 88 124 100 86 68 63 108 63Z\"/>\n  </clipPath>\n  <g clip-path=\"url(#scpe-star)\">\n    <rect class=\"scpe-fill\" x=\"50\" y=\"15\" width=\"140\" height=\"120\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  </g>\n  <path d=\"M120 25 132 63 172 63 140 86 152 124 120 101 88 124 100 86 68 63 108 63Z\" fill=\"none\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"1.5\" opacity=\".6\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "svg-text-mask",
    "mask-reveal",
    "svg-mask-type",
    "clip-path-polygon"
   ]
  },
  {
   "id": "mask-gradient-fade",
   "num": "W-057",
   "name": "Mask Gradient Fade",
   "nameJa": "マスクでグラデーションフェード",
   "category": "shape",
   "description": "mask-image: linear-gradient()で要素の端を透明に自然にぼかす。画像やテキストブロックの端をふわっと消すのに使う。",
   "useCase": "長文テキストの下端フェードアウトや、画像の端を背景に馴染ませるヒーロー演出に使う。",
   "code": ".mgfd-fade {\n  mask-image: linear-gradient(to bottom, #000 70%, transparent 100%);\n  -webkit-mask-image: linear-gradient(to bottom, #000 70%, transparent 100%);\n}",
   "tags": [
    "CSS",
    "mask",
    "グラデーション",
    "フェード",
    "ぼかし",
    "ふわっと",
    "さりげない"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"マスクでグラデーションフェードのデモ\">\n  <style>\n    .mgfd-bar{animation:mgfd-move 4s ease-in-out infinite}\n    @keyframes mgfd-move{0%,100%{transform:translateY(0)}50%{transform:translateY(-14px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <defs>\n    <linearGradient id=\"mgfd-grad\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n      <stop offset=\"55%\" stop-color=\"var(--w-accent,#4fe3c1)\" stop-opacity=\"1\"/>\n      <stop offset=\"100%\" stop-color=\"var(--w-accent,#4fe3c1)\" stop-opacity=\"0\"/>\n    </linearGradient>\n  </defs>\n  <g class=\"mgfd-bar\">\n    <rect x=\"30\" y=\"30\" width=\"180\" height=\"90\" fill=\"url(#mgfd-grad)\"/>\n  </g>\n  <line x1=\"20\" y1=\"115\" x2=\"220\" y2=\"115\" stroke=\"var(--w-sub,#94a3c0)\" stroke-width=\"1\" stroke-dasharray=\"3 3\" opacity=\".5\"/>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "tooltip",
    "tilt-shift",
    "skeleton-shimmer",
    "gradient-animation"
   ]
  },
  {
   "id": "svg-text-mask",
   "num": "W-058",
   "name": "SVG Text Mask",
   "nameJa": "文字型に画像を切り抜く",
   "category": "shape",
   "description": "SVGの<mask>要素に白文字テキストを描き、画像や動画を重ねることで文字の内側だけをくり抜いて見せる。CSSのbackground-clip:textより柔軟で動画にも使える。",
   "useCase": "動画を文字の形にくり抜くタイトル演出や、写真をロゴ文字に流し込む特別感のある見出しに使う。",
   "code": "<svg viewBox=\"0 0 400 120\">\n  <mask id=\"stm-cutout\">\n    <rect width=\"100%\" height=\"100%\" fill=\"#000\"/>\n    <text x=\"20\" y=\"90\" font-size=\"90\" font-weight=\"900\" fill=\"#fff\">WAZA</text>\n  </mask>\n  <image href=\"photo.jpg\" width=\"400\" height=\"120\" mask=\"url(#stm-cutout)\"/>\n</svg>",
   "tags": [
    "SVG",
    "mask",
    "テキスト",
    "文字",
    "写真",
    "高級感",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"文字型に画像を切り抜くのデモ\">\n  <style>\n    .stmk-fill{animation:stmk-shift 3s linear infinite}\n    @keyframes stmk-shift{0%{transform:translateX(-20px)}100%{transform:translateX(20px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <mask id=\"stmk-m\">\n    <text x=\"14\" y=\"100\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"72\" font-weight=\"900\" fill=\"var(--w-ink,#e8eef9)\">AK</text>\n  </mask>\n  <g mask=\"url(#stmk-m)\">\n    <rect class=\"stmk-fill\" x=\"-20\" y=\"20\" width=\"280\" height=\"110\" fill=\"var(--w-accent,#4fe3c1)\"/>\n    <rect class=\"stmk-fill\" x=\"100\" y=\"20\" width=\"20\" height=\"110\" fill=\"var(--w-amber,#ffc857)\"/>\n  </g>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "svg-clip-path",
    "text-image-fill",
    "text-on-path",
    "gradient-border"
   ]
  },
  {
   "id": "shape-outside",
   "num": "W-059",
   "name": "Shape Outside Wrap",
   "nameJa": "図形に沿った回り込みテキスト",
   "category": "shape",
   "description": "float要素にshape-outside: circle()やurl(image.png)を指定し、テキストを円形や画像の輪郭に沿って回り込ませる。",
   "useCase": "雑誌風レイアウトで、丸い画像やイラストの輪郭に沿って本文テキストを流し込みたい記事ページに使う。",
   "code": ".shpo-figure {\n  float: left;\n  width: 160px;\n  shape-outside: circle(50%);\n  clip-path: circle(50%);\n  margin: 0 16px 8px 0;\n}",
   "tags": [
    "CSS",
    "shape-outside",
    "回り込み",
    "テキスト",
    "レイアウト",
    "こなれ感",
    "さりげない"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"図形に沿った回り込みテキストのデモ\">\n  <style>\n    .shpo-line{animation:shpo-in 3s ease-in-out infinite}\n    .shpo-line:nth-child(2){animation-delay:.15s}\n    .shpo-line:nth-child(3){animation-delay:.3s}\n    .shpo-line:nth-child(4){animation-delay:.45s}\n    .shpo-line:nth-child(5){animation-delay:.6s}\n    .shpo-line:nth-child(6){animation-delay:.75s}\n    .shpo-line:nth-child(7){animation-delay:.9s}\n    @keyframes shpo-in{0%,100%{opacity:.25}50%{opacity:1}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <circle cx=\"55\" cy=\"60\" r=\"38\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\"/>\n  <g fill=\"var(--w-ink,#e8eef9)\">\n    <rect class=\"shpo-line\" x=\"85\" y=\"24\" width=\"139\" height=\"6\" rx=\"3\" opacity=\".5\"/>\n    <rect class=\"shpo-line\" x=\"96\" y=\"38\" width=\"128\" height=\"6\" rx=\"3\" opacity=\".5\"/>\n    <rect class=\"shpo-line\" x=\"101\" y=\"52\" width=\"123\" height=\"6\" rx=\"3\" opacity=\".5\"/>\n    <rect class=\"shpo-line\" x=\"100\" y=\"66\" width=\"124\" height=\"6\" rx=\"3\" opacity=\".5\"/>\n    <rect class=\"shpo-line\" x=\"93\" y=\"80\" width=\"131\" height=\"6\" rx=\"3\" opacity=\".5\"/>\n    <rect class=\"shpo-line\" x=\"30\" y=\"104\" width=\"190\" height=\"6\" rx=\"3\" opacity=\".5\"/>\n    <rect class=\"shpo-line\" x=\"30\" y=\"118\" width=\"190\" height=\"6\" rx=\"3\" opacity=\".5\"/>\n  </g>\n</svg>",
   "useFor": [
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "vertical-writing",
    "scroll-margin-padding",
    "line-clamp",
    "text-wrap-balance"
   ]
  },
  {
   "id": "organic-blob",
   "num": "W-060",
   "name": "Organic Blob Shape",
   "nameJa": "有機的なブロブ形状",
   "category": "shape",
   "description": "border-radiusに8つの%値（水平4つ/垂直4つ）を指定し、不規則な有機的ブロブ形状を作る。keyframesで数値を変化させると柔らかく蠢く。",
   "useCase": "背景装飾やアイコン台紙に、角丸四角より柔らかく親しみやすい形を出したいときに使う。",
   "code": ".blob-shape {\n  border-radius: 42% 58% 65% 35% / 45% 40% 60% 55%;\n  animation: blob-morph 6s ease-in-out infinite;\n}\n@keyframes blob-morph {\n  50% { border-radius: 60% 40% 35% 65% / 55% 65% 35% 45%; }\n}",
   "tags": [
    "CSS",
    "border-radius",
    "ブロブ",
    "背景装飾",
    "有機的",
    "ふわっと",
    "柔らかい",
    "親しみ"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"有機的なブロブ形状のデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <path fill=\"var(--w-accent,#4fe3c1)\" opacity=\".9\">\n    <animate attributeName=\"d\" dur=\"5s\" repeatCount=\"indefinite\"\n      values=\"M120,30 C160,32 185,60 182,90 C179,120 145,132 115,128 C85,124 62,105 63,75 C64,45 88,28 120,30Z;\n              M118,25 C155,20 190,50 188,82 C186,114 155,135 118,133 C81,131 55,108 58,76 C61,44 89,30 118,25Z;\n              M120,30 C160,32 185,60 182,90 C179,120 145,132 115,128 C85,124 62,105 63,75 C64,45 88,28 120,30Z\"/>\n  </path>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "lava-blob",
    "clip-path-reveal",
    "mask-gradient-fade",
    "speech-bubble"
   ]
  },
  {
   "id": "gradient-border",
   "num": "W-061",
   "name": "Gradient Border",
   "nameJa": "グラデーション枠線",
   "category": "shape",
   "description": "border-imageや、背景を二重に重ねるbackground-origin: border-boxの手法でグラデーションの枠線を作る。border-imageはborder-radiusと併用できないため、角丸にしたい場合は背景を二重に重ねる技法を使う。",
   "useCase": "カードやボタンの縁を単色より華やかなグラデーション枠にして、高級感や特別感を出したいときに使う。",
   "code": ".gbdr-card {\n  border: 3px solid transparent;\n  border-radius: 16px;\n  background:\n    linear-gradient(var(--w-bg,#101830), var(--w-bg,#101830)) padding-box,\n    linear-gradient(135deg, var(--w-accent,#4fe3c1), var(--w-amber,#ffc857)) border-box;\n}",
   "tags": [
    "CSS",
    "border",
    "グラデーション",
    "カード",
    "縁取り",
    "高級感",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"グラデーション枠線のデモ\">\n  <style>\n    .gbdr-grad{animation:gbdr-spin 4s linear infinite;transform-origin:120px 75px}\n    @keyframes gbdr-spin{to{transform:rotate(360deg)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <defs>\n    <linearGradient id=\"gbdr-g\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\n      <stop offset=\"0%\" stop-color=\"var(--w-accent,#4fe3c1)\"/>\n      <stop offset=\"100%\" stop-color=\"var(--w-amber,#ffc857)\"/>\n    </linearGradient>\n  </defs>\n  <g class=\"gbdr-grad\">\n    <rect x=\"50\" y=\"30\" width=\"140\" height=\"90\" rx=\"14\" fill=\"none\" stroke=\"url(#gbdr-g)\" stroke-width=\"6\"/>\n  </g>\n  <rect x=\"56\" y=\"36\" width=\"128\" height=\"78\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "gradient-text",
    "mesh-gradient",
    "duotone-image",
    "text-image-fill"
   ]
  },
  {
   "id": "conic-gradient-chart",
   "num": "W-062",
   "name": "Conic Gradient Pie Chart",
   "nameJa": "円錐グラデーションで円グラフ",
   "category": "shape",
   "description": "background: conic-gradient()で角度ごとに色を割り当て、画像やJSなしに円グラフ・ローディングリングを描く。%指定でCSS変数から動的に更新できる。",
   "useCase": "ダッシュボードの割合表示、料金プラン比較、進捗リングなどをCSSだけで軽量に描きたいときに使う。",
   "code": ".cgcp-pie {\n  width: 100px; height: 100px; border-radius: 50%;\n  background: conic-gradient(\n    var(--w-accent,#4fe3c1) 0% 65%,\n    var(--w-amber,#ffc857) 65% 100%\n  );\n}",
   "tags": [
    "CSS",
    "conic-gradient",
    "グラフ",
    "データ可視化",
    "円グラフ",
    "パッと切替",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"円錐グラデーションで円グラフのデモ\">\n  <style>\n    .cgcp-ring{animation:cgcp-fill 4s ease-in-out infinite}\n    @keyframes cgcp-fill{0%{stroke-dasharray:0 220}60%,100%{stroke-dasharray:143 220}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <circle cx=\"120\" cy=\"75\" r=\"35\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-width=\"18\" opacity=\".3\"/>\n  <circle class=\"cgcp-ring\" cx=\"120\" cy=\"75\" r=\"35\" fill=\"none\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"18\" stroke-dasharray=\"0 220\" transform=\"rotate(-90 120 75)\"/>\n  <text x=\"120\" y=\"80\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"14\" fill=\"var(--w-ink,#e8eef9)\">65%</text>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "ripple-effect",
    "svg-line-area-chart",
    "bar-chart-grid-vs-svg",
    "svg-radar-chart"
   ]
  },
  {
   "id": "mix-blend-mode",
   "num": "W-063",
   "name": "Mix Blend Mode",
   "nameJa": "画像合成 (ブレンドモード)",
   "category": "shape",
   "description": "mix-blend-modeプロパティで要素と背景の色をscreen/multiply/differenceなどの計算式で合成し、写真やテキストに特殊な色重なり効果を出す。",
   "useCase": "見出しテキストを写真の上に重ねて自然に馴染ませたり、2枚の画像をアート的に掛け合わせたい演出に使う。",
   "code": ".mbmd-text {\n  mix-blend-mode: difference;\n  color: var(--w-ink,#e8eef9);\n}\n.mbmd-layer {\n  mix-blend-mode: screen;\n}",
   "tags": [
    "CSS",
    "mix-blend-mode",
    "合成",
    "写真",
    "アート",
    "ダイナミック",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"画像合成(ブレンドモード)のデモ\">\n  <style>\n    .mbmd-a{animation:mbmd-move 4s ease-in-out infinite}\n    @keyframes mbmd-move{0%,100%{transform:translateX(-18px)}50%{transform:translateX(18px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <circle cx=\"120\" cy=\"75\" r=\"42\" fill=\"var(--w-amber,#ffc857)\" opacity=\".8\"/>\n  <circle class=\"mbmd-a\" cx=\"120\" cy=\"75\" r=\"42\" fill=\"var(--w-accent,#4fe3c1)\" style=\"mix-blend-mode:difference\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "blend-difference-text",
    "clip-path-polygon",
    "duotone-image",
    "text-stroke-outline"
   ]
  },
  {
   "id": "glassmorphism",
   "num": "W-064",
   "name": "Glassmorphism",
   "nameJa": "すりガラス (グラスモーフィズム)",
   "category": "shape",
   "description": "backdrop-filter: blur()と半透明背景を組み合わせ、背後の内容が透けて見えるすりガラス風パネルを作る。淡い枠線を添えると質感が増す。",
   "useCase": "ナビゲーションバーやモーダル、カード型UIに透明感と奥行きを持たせたいデザインに使う。",
   "code": ".glsm-panel {\n  background: rgba(255,255,255,.12);\n  backdrop-filter: blur(16px) saturate(160%);\n  -webkit-backdrop-filter: blur(16px) saturate(160%);\n  border: 1px solid rgba(255,255,255,.25);\n  border-radius: 16px;\n}",
   "tags": [
    "CSS",
    "backdrop-filter",
    "すりガラス",
    "半透明",
    "UI",
    "高級感",
    "没入感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"すりガラス(グラスモーフィズム)のデモ\">\n  <style>\n    .glsm-blob{animation:glsm-drift 4.5s ease-in-out infinite}\n    .glsm-blob2{animation:glsm-drift 4.5s ease-in-out infinite;animation-delay:.6s}\n    @keyframes glsm-drift{0%,100%{transform:translate(0,0)}50%{transform:translate(20px,-10px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <defs>\n    <filter id=\"glsm-blur\" x=\"-60%\" y=\"-60%\" width=\"220%\" height=\"220%\">\n      <feGaussianBlur stdDeviation=\"6\"/>\n    </filter>\n  </defs>\n  <g filter=\"url(#glsm-blur)\">\n    <circle class=\"glsm-blob\" cx=\"70\" cy=\"60\" r=\"30\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".8\"/>\n    <circle class=\"glsm-blob2\" cx=\"160\" cy=\"100\" r=\"26\" fill=\"var(--w-amber,#ffc857)\" opacity=\".8\"/>\n  </g>\n  <rect x=\"40\" y=\"45\" width=\"160\" height=\"75\" rx=\"14\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".14\"/>\n  <rect x=\"40\" y=\"45\" width=\"160\" height=\"75\" rx=\"14\" fill=\"none\" stroke=\"var(--w-ink,#e8eef9)\" opacity=\".3\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "blur-reveal-text",
    "glass-depth",
    "aurora-background",
    "vertical-scroll-snap"
   ]
  },
  {
   "id": "filter-effects",
   "num": "W-065",
   "name": "CSS Filter Effects",
   "nameJa": "フィルター効果 (ぼかし・彩度・影)",
   "category": "shape",
   "description": "filter: blur()/saturate()/drop-shadow()等を単体または複数組み合わせ、画像の質感を非破壊で加工する。hover遷移でtransitionを付けると変化が滑らか。",
   "useCase": "サムネイル画像のホバーで鮮やかにする、非アクティブなカードをグレーアウトするなどの状態表現に使う。",
   "code": ".fltr-img {\n  filter: grayscale(60%) blur(1px);\n  transition: filter .4s ease;\n}\n.fltr-img:hover {\n  filter: grayscale(0%) blur(0) saturate(130%)\n    drop-shadow(0 8px 16px rgba(0,0,0,.35));\n}",
   "tags": [
    "CSS",
    "filter",
    "ホバー",
    "画像加工",
    "ぬるっと",
    "くっきり",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"フィルター効果(ぼかし・彩度・影)のデモ\">\n  <style>\n    .fltr-shape{animation:fltr-mix 3.5s ease-in-out infinite}\n    @keyframes fltr-mix{0%,100%{filter:blur(0px) saturate(.2) drop-shadow(0 2px 0 var(--w-bg,#101830))}50%{filter:blur(3px) saturate(1.4) drop-shadow(0 10px 6px var(--w-bg,#101830))}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"fltr-shape\" x=\"70\" y=\"35\" width=\"100\" height=\"70\" rx=\"10\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <text x=\"120\" y=\"132\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"9\" fill=\"var(--w-sub,#94a3c2)\">blur・saturate・shadow</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "hover-zoom",
    "clip-path-shapes",
    "duotone-image",
    "variable-font-weight"
   ]
  },
  {
   "id": "wave-divider",
   "num": "W-066",
   "name": "SVG Wave Divider",
   "nameJa": "波形のセクション区切り",
   "category": "shape",
   "description": "セクション境界にSVGの<path>で波形を描画し、直線区切りより柔らかい印象のセクション切り替えを作る。position: absoluteで下端に重ねる。",
   "useCase": "LPでヒーローと次セクションの境目、フッター上部などを柔らかい曲線で繋ぎたいときに使う。",
   "code": "<svg class=\"wvdv-divider\" viewBox=\"0 0 1440 100\" preserveAspectRatio=\"none\">\n  <path d=\"M0,40 C360,100 1080,0 1440,50 L1440,100 L0,100 Z\"\n        fill=\"var(--w-bg,#101830)\"/>\n</svg>",
   "tags": [
    "SVG",
    "divider",
    "波形",
    "セクション",
    "LP",
    "柔らかい",
    "さりげない"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"波形のセクション区切りのデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect width=\"240\" height=\"70\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".25\"/>\n  <path fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\">\n    <animate attributeName=\"d\" dur=\"4s\" repeatCount=\"indefinite\"\n      values=\"M0,70 C60,90 180,50 240,72 L240,150 L0,150 Z;\n              M0,78 C60,55 180,95 240,68 L240,150 L0,150 Z;\n              M0,70 C60,90 180,50 240,72 L240,150 L0,150 Z\"/>\n  </path>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "clip-path-polygon",
    "wave-divider-bg",
    "text-on-path",
    "progress-ring"
   ]
  },
  {
   "id": "speech-bubble",
   "num": "W-067",
   "name": "Speech Bubble Shape",
   "nameJa": "吹き出し・三角形",
   "category": "shape",
   "description": "角丸の四角にborderやclip-pathで三角形の尻尾を付け足し、会話やツールチップの吹き出し形状を作る。擬似要素::afterに三角形を配置するのが定番。",
   "useCase": "FAQやチャットUI、キャラクターのセリフ表示、ツールチップの補足説明に使う。",
   "code": ".spbb-bubble {\n  position: relative;\n  border-radius: 16px;\n  background: var(--w-ink,#e8eef9);\n}\n.spbb-bubble::after {\n  content: \"\";\n  position: absolute; left: 24px; bottom: -10px;\n  border: 10px solid transparent;\n  border-top-color: var(--w-ink,#e8eef9);\n}",
   "tags": [
    "CSS",
    "擬似要素",
    "吹き出し",
    "チャット",
    "三角形",
    "親しみ",
    "パッと切替"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"吹き出し・三角形のデモ\">\n  <style>\n    .spbb-bubble{animation:spbb-pop 3s ease-in-out infinite;transform-origin:120px 65px}\n    @keyframes spbb-pop{0%,20%{transform:scale(0)}35%{transform:scale(1.08)}45%,80%{transform:scale(1)}100%{transform:scale(0)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"spbb-bubble\">\n    <rect x=\"40\" y=\"25\" width=\"160\" height=\"80\" rx=\"16\" fill=\"var(--w-accent,#4fe3c1)\"/>\n    <polygon points=\"70,105 70,125 95,105\" fill=\"var(--w-accent,#4fe3c1)\"/>\n    <rect x=\"58\" y=\"45\" width=\"120\" height=\"8\" rx=\"4\" fill=\"var(--w-bg,#101830)\" opacity=\".5\"/>\n    <rect x=\"58\" y=\"62\" width=\"90\" height=\"8\" rx=\"4\" fill=\"var(--w-bg,#101830)\" opacity=\".5\"/>\n  </g>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "details-content",
    "conic-gradient-chart",
    "ripple-effect",
    "target-css-toggle"
   ]
  },
  {
   "id": "duotone-image",
   "num": "W-068",
   "name": "Duotone Image Effect",
   "nameJa": "デュオトーン (二色化) 画像",
   "category": "shape",
   "description": "filter: grayscale()+セピア調整、またはmix-blend-modeとグラデーションレイヤーを重ねてグレースケール画像を2色のトーンに変換する。",
   "useCase": "ブランドカラーに写真を統一したいセクション背景や、モノトーンで統一感を出したいギャラリーに使う。",
   "code": ".dtnm-wrap { position: relative; }\n.dtnm-wrap img { filter: grayscale(100%) contrast(1.1); display: block; }\n.dtnm-wrap::before {\n  content: \"\"; position: absolute; inset: 0;\n  background: linear-gradient(135deg, var(--w-accent,#4fe3c1), var(--w-amber,#ffc857));\n  mix-blend-mode: color;\n}",
   "tags": [
    "CSS",
    "mix-blend-mode",
    "デュオトーン",
    "画像加工",
    "ブランド",
    "高級感",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"デュオトーン(二色化)画像のデモ\">\n  <style>\n    .dtnm-over{animation:dtnm-in 3.5s ease-in-out infinite}\n    @keyframes dtnm-in{0%,100%{opacity:0}50%{opacity:.9}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <defs>\n    <linearGradient id=\"dtnm-g\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\n      <stop offset=\"0%\" stop-color=\"var(--w-amber,#ffc857)\"/>\n      <stop offset=\"100%\" stop-color=\"var(--w-accent,#4fe3c1)\"/>\n    </linearGradient>\n  </defs>\n  <rect x=\"55\" y=\"25\" width=\"130\" height=\"100\" rx=\"8\" fill=\"var(--w-sub,#94a3c2)\" opacity=\".6\"/>\n  <rect class=\"dtnm-over\" x=\"55\" y=\"25\" width=\"130\" height=\"100\" rx=\"8\" fill=\"url(#dtnm-g)\" style=\"mix-blend-mode:color\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "gradient-text",
    "gradient-border",
    "mix-blend-mode",
    "filter-effects"
   ]
  },
  {
   "id": "text-image-fill",
   "num": "W-069",
   "name": "Background Clip Text Fill",
   "nameJa": "画像で文字を塗る",
   "category": "shape",
   "description": "background-clip: textとcolor: transparentを使い、太字テキストの内側に写真やグラデーション画像を流し込んで塗りつぶす。",
   "useCase": "インパクトある見出しに写真やグラデーションを組み込み、単色テキストより目を引くタイトルにしたいときに使う。",
   "code": ".tifl-title {\n  background: url('texture.jpg') center/cover;\n  background-clip: text;\n  -webkit-background-clip: text;\n  color: transparent;\n  font-weight: 900;\n}",
   "tags": [
    "CSS",
    "background-clip",
    "テキスト",
    "画像",
    "見出し",
    "目を引く",
    "高級感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"画像で文字を塗るのデモ\">\n  <style>\n    .tifl-grad{animation:tifl-slide 3s ease-in-out infinite}\n    @keyframes tifl-slide{0%,100%{transform:translateX(-15px)}50%{transform:translateX(15px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <clipPath id=\"tifl-c\">\n    <text x=\"14\" y=\"98\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"64\" font-weight=\"900\">FILL</text>\n  </clipPath>\n  <g clip-path=\"url(#tifl-c)\">\n    <rect class=\"tifl-grad\" x=\"-15\" y=\"20\" width=\"270\" height=\"110\" fill=\"var(--w-amber,#ffc857)\"/>\n    <rect class=\"tifl-grad\" x=\"90\" y=\"20\" width=\"40\" height=\"110\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  </g>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "text-image-mask",
    "gradient-text",
    "svg-text-mask",
    "gradient-border"
   ]
  },
  {
   "id": "transition-basics",
   "num": "W-070",
   "name": "Transition Basics (Targeted Properties)",
   "nameJa": "トランジション設計（プロパティ限定）",
   "category": "motion",
   "description": "transition: allで全プロパティを対象にせず、transform・box-shadowなど動かしたいプロパティだけをtransition-propertyで指定して意図しない再計算やバグを防ぐ基本設計。",
   "useCase": "ボタンやカードのホバー演出で複数プロパティを同時に動かしつつ、無関係な変化まで一緒にアニメしてしまうのを防ぎたい場面。",
   "code": ".btn {\n  transition-property: transform, box-shadow, background-color;\n  transition-duration: .25s, .25s, .4s;\n  transition-timing-function: ease-out;\n}\n.btn:hover {\n  transform: translateY(-4px);\n  box-shadow: 0 12px 24px rgba(0,0,0,.2);\n}",
   "tags": [
    "CSS",
    "transition",
    "ホバー",
    "基礎",
    "パフォーマンス",
    "さりげない",
    "きびきび"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"トランジション設計（プロパティ限定）のデモ\">\n  <style>\n    .tbas-card{animation:tbas-move 3s ease-in-out infinite}\n    .tbas-shadow{animation:tbas-shadow 3s ease-in-out infinite}\n    @keyframes tbas-move{0%,100%{transform:translateY(0)}50%{transform:translateY(-18px)}}\n    @keyframes tbas-shadow{0%,100%{opacity:.5;transform:scaleX(1)}50%{opacity:.15;transform:scaleX(.7)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <ellipse class=\"tbas-shadow\" cx=\"120\" cy=\"112\" rx=\"46\" ry=\"10\" fill=\"var(--w-ink,#e8eef9)\"/>\n  <rect class=\"tbas-card\" x=\"80\" y=\"46\" width=\"80\" height=\"56\" rx=\"8\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <text x=\"120\" y=\"132\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#94a3c0)\">transform + shadow</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "hover-pause",
    "reduced-motion",
    "hover-focus-states",
    "tooltip"
   ]
  },
  {
   "id": "keyframes-multistep",
   "num": "W-071",
   "name": "Multi-step @keyframes",
   "nameJa": "多段@keyframesアニメ",
   "category": "motion",
   "description": "0%・20%・45%・65%のように複数の中間ステップを@keyframesに置き、単純な往復ではない弾むような複雑な軌跡を作る技法。",
   "useCase": "ロゴのアテンション演出やアイコンのバウンド、注目を集めたいCTAボタンの揺れ演出などに使う。",
   "code": "@keyframes kfms-bounce {\n  0% { transform: translateY(0) scale(1); }\n  20% { transform: translateY(-24px) scale(1.05); }\n  45% { transform: translateY(0) scale(.95); }\n  65% { transform: translateY(-8px) scale(1.02); }\n  100% { transform: translateY(0) scale(1); }\n}\n.icon { animation: kfms-bounce 1.8s ease-in-out infinite; }",
   "tags": [
    "CSS",
    "keyframes",
    "基礎",
    "バウンド",
    "目を引く",
    "ダイナミック"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"多段@keyframesアニメのデモ\">\n  <style>\n    .kfms-ball{animation:kfms-bounce 2.4s cubic-bezier(.3,.6,.3,1) infinite}\n    @keyframes kfms-bounce{0%{transform:translateY(0)}20%{transform:translateY(-46px)}45%{transform:translateY(0)}65%{transform:translateY(-16px)}80%{transform:translateY(0)}100%{transform:translateY(0)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <ellipse cx=\"120\" cy=\"118\" rx=\"30\" ry=\"6\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".3\"/>\n  <circle class=\"kfms-ball\" cx=\"120\" cy=\"100\" r=\"20\" fill=\"var(--w-accent,#4fe3c1)\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "offset-path",
    "property-custom-animate",
    "infinite-loop-motion",
    "text-stroke-outline"
   ]
  },
  {
   "id": "easing-design",
   "num": "W-072",
   "name": "Easing Design (cubic-bezier / linear() Spring)",
   "nameJa": "イージング設計（スプリング風含む）",
   "category": "motion",
   "description": "動きの緩急をcubic-bezier()で作り込み、さらにlinear()関数で振動するような値を並べてバネのオーバーシュートを表現する。既定のeaseより意図の伝わる速度曲線を選ぶ。",
   "useCase": "モーダルの出現やボタンのプレス演出など、安っぽく見えない動きの質感をCSSだけで作りたい場面。",
   "code": ".pop {\n  transform: scale(.8);\n  transition: transform .5s\n    linear(0, .42 8%, 1.12 30%, .94 52%, 1.03 68%, 1 100%);\n}\n.pop.is-open { transform: scale(1); }",
   "tags": [
    "CSS",
    "イージング",
    "基礎",
    "スプリング",
    "ふわっと",
    "高級感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"イージング設計（スプリング風含む）のデモ\">\n  <style>\n    .ezdn-linear{animation:ezdn-lin 3s linear infinite}\n    .ezdn-spring{animation:ezdn-spr 3s infinite}\n    @keyframes ezdn-lin{0%{transform:translateX(0)}100%{transform:translateX(160px)}}\n    @keyframes ezdn-spr{0%{transform:translateX(0)}60%{transform:translateX(176px)}75%{transform:translateX(150px)}88%{transform:translateX(166px)}100%{transform:translateX(160px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <line x1=\"40\" y1=\"55\" x2=\"200\" y2=\"55\" stroke=\"var(--w-sub,#94a3c0)\" stroke-width=\"1\" opacity=\".3\"/>\n  <circle class=\"ezdn-linear\" cx=\"40\" cy=\"55\" r=\"8\" fill=\"var(--w-sub,#94a3c0)\"/>\n  <line x1=\"40\" y1=\"100\" x2=\"200\" y2=\"100\" stroke=\"var(--w-sub,#94a3c0)\" stroke-width=\"1\" opacity=\".3\"/>\n  <circle class=\"ezdn-spring\" cx=\"40\" cy=\"100\" r=\"8\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <text x=\"120\" y=\"130\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-ink,#e8eef9)\">linear vs spring</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "blur-reveal-text",
    "gradient-animation",
    "pricing-card-hover-lift",
    "keyframes-multistep"
   ]
  },
  {
   "id": "starting-style",
   "num": "W-073",
   "name": "@starting-style Entry Animation",
   "nameJa": "@starting-styleで出現アニメ",
   "category": "motion",
   "description": "displayやvisibilityが変わる要素でも、@starting-styleに開始値を書くだけでtransitionが出現の瞬間から効くようにする仕組み。JSでの初期値制御が不要になる。",
   "useCase": "モーダルやトースト通知、ドロップダウンをパッと出さず、フェード＋拡大しながら現れさせたい場面。",
   "code": "@starting-style {\n  .toast[open] { opacity: 0; transform: translateY(12px) scale(.94); }\n}\n.toast[open] {\n  opacity: 1; transform: translateY(0) scale(1);\n  transition: opacity .3s, transform .3s, display .3s allow-discrete;\n}",
   "tags": [
    "CSS",
    "starting-style",
    "モーダル",
    "出現",
    "ふわっと",
    "目を引く"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"@starting-styleで出現アニメのデモ\">\n  <style>\n    .sst-toast{animation:sst-in 3s ease-out infinite}\n    @keyframes sst-in{0%{opacity:0;transform:translateY(16px) scale(.9)}15%,70%{opacity:1;transform:translateY(0) scale(1)}85%,100%{opacity:0;transform:translateY(16px) scale(.9)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"sst-toast\" x=\"50\" y=\"55\" width=\"140\" height=\"40\" rx=\"8\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".9\"/>\n  <text x=\"120\" y=\"79\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"11\" fill=\"var(--w-bg,#101830)\">Saved</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "scroll-reveal",
    "animation-composition",
    "allow-discrete",
    "infinite-loop-motion"
   ]
  },
  {
   "id": "view-transitions-spa",
   "num": "W-074",
   "name": "View Transitions API (Same-Document)",
   "nameJa": "View Transitions API（同一ページ内）",
   "category": "motion",
   "description": "document.startViewTransition()でDOM更新前後のスナップショットを撮り、要素を自動でクロスフェード・モーフさせる。view-transition-nameで個別要素も指定できる。",
   "useCase": "SPAのフィルタ切替やタブ切替、ギャラリーのグリッド⇔詳細表示の遷移を複雑な実装なしで滑らかにしたい場面。",
   "code": "document.startViewTransition(() => {\n  updateDOM();\n});\n\n/* CSS */\n.card { view-transition-name: card-1; }\n::view-transition-old(card-1),\n::view-transition-new(card-1) { animation-duration: .4s; }",
   "tags": [
    "CSS",
    "JavaScript",
    "View Transitions",
    "SPA",
    "ぬるっと",
    "没入感"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"View Transitions API（同一ページ内）のデモ\">\n  <style>\n    .vtsp-card{animation:vtsp-morph 3.6s ease-in-out infinite;transform-origin:24px 30px}\n    @keyframes vtsp-morph{0%,20%{transform:translate(0,0) scale(1)}50%,80%{transform:translate(46px,-10px) scale(1.8)}100%{transform:translate(0,0) scale(1)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"24\" y=\"30\" width=\"56\" height=\"56\" rx=\"8\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".25\"/>\n  <rect class=\"vtsp-card\" x=\"24\" y=\"30\" width=\"56\" height=\"56\" rx=\"8\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <text x=\"150\" y=\"120\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#94a3c0)\">grid to detail</text>\n</svg>",
   "useFor": [
    "site",
    "lp"
   ],
   "weight": "主役",
   "relatedIds": [
    "view-transitions-mpa",
    "parallax-card-image",
    "page-turn",
    "scroll-snap"
   ]
  },
  {
   "id": "view-transitions-mpa",
   "num": "W-075",
   "name": "Cross-Document View Transitions",
   "nameJa": "View Transitions（ページ遷移・MPA）",
   "category": "motion",
   "description": "通常のページ遷移（aタグのクリック）でも@view-transitionルールとview-transition-nameだけでフェードやモーフの遷移を付けられるMPA向けAPI。JS不要。",
   "useCase": "静的サイトやブログ・ECのページ遷移を、フルリロードの白フラッシュではなく画像や見出しが繋がって見える遷移にしたい場面。",
   "code": "@view-transition { navigation: auto; }\nimg.hero { view-transition-name: hero-image; }\n::view-transition-old(hero-image),\n::view-transition-new(hero-image) { animation-duration: .5s; }",
   "tags": [
    "CSS",
    "View Transitions",
    "ページ遷移",
    "MPA",
    "ぬるっと",
    "没入感"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"View Transitions（ページ遷移・MPA）のデモ\">\n  <style>\n    .vtmp-pageA{animation:vtmp-a 4s ease-in-out infinite}\n    .vtmp-pageB{animation:vtmp-b 4s ease-in-out infinite}\n    .vtmp-hero{animation:vtmp-hero 4s ease-in-out infinite}\n    @keyframes vtmp-a{0%,40%{opacity:1}55%,100%{opacity:0}}\n    @keyframes vtmp-b{0%,40%{opacity:0}55%,100%{opacity:1}}\n    @keyframes vtmp-hero{0%,40%{transform:translate(0,0) scale(1)}55%,100%{transform:translate(90px,10px) scale(.6)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"vtmp-pageA\">\n    <rect x=\"14\" y=\"14\" width=\"212\" height=\"122\" rx=\"8\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".12\"/>\n    <text x=\"30\" y=\"34\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#94a3c0)\">page A</text>\n  </g>\n  <g class=\"vtmp-pageB\">\n    <rect x=\"14\" y=\"14\" width=\"212\" height=\"122\" rx=\"8\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".12\"/>\n    <text x=\"180\" y=\"34\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#94a3c0)\">page B</text>\n  </g>\n  <rect class=\"vtmp-hero\" x=\"30\" y=\"50\" width=\"60\" height=\"60\" rx=\"8\" fill=\"var(--w-amber,#ffc857)\"/>\n</svg>",
   "useFor": [
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "view-transitions-spa",
    "view-transition-class",
    "scroll-snap",
    "scroll-text-highlight"
   ]
  },
  {
   "id": "flip-technique",
   "num": "W-076",
   "name": "FLIP Technique",
   "nameJa": "FLIPテクニック",
   "category": "motion",
   "description": "First・Last・Invert・Playの略。要素移動前後の位置差分をtransformで逆算し一瞬で戻してから0へアニメすることで、レイアウト変更を滑らかに見せる手法。",
   "useCase": "リスト並べ替え、カード追加・削除、グリッドのフィルタリングなど、レイアウトが飛ぶ変化を動いたように見せたい場面。",
   "code": "const first = el.getBoundingClientRect();\nmoveInDOM();\nconst last = el.getBoundingClientRect();\nconst dx = first.left - last.left, dy = first.top - last.top;\nel.animate([\n  { transform: `translate(${dx}px, ${dy}px)` },\n  { transform: 'translate(0, 0)' }\n], { duration: 300, easing: 'ease-out' });",
   "tags": [
    "JavaScript",
    "FLIP",
    "レイアウト",
    "並べ替え",
    "ぬるっと",
    "ダイナミック"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"FLIPテクニックのデモ\">\n  <style>\n    .flip-a{animation:flip-swapA 3s ease-in-out infinite}\n    .flip-b{animation:flip-swapB 3s ease-in-out infinite}\n    @keyframes flip-swapA{0%,40%{transform:translateX(0)}60%,100%{transform:translateX(120px)}}\n    @keyframes flip-swapB{0%,40%{transform:translateX(0)}60%,100%{transform:translateX(-120px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"40\" y=\"60\" width=\"50\" height=\"34\" rx=\"6\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".25\"/>\n  <rect x=\"150\" y=\"60\" width=\"50\" height=\"34\" rx=\"6\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".25\"/>\n  <rect class=\"flip-a\" x=\"40\" y=\"60\" width=\"50\" height=\"34\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <rect class=\"flip-b\" x=\"150\" y=\"60\" width=\"50\" height=\"34\" rx=\"6\" fill=\"var(--w-amber,#ffc857)\"/>\n</svg>",
   "useFor": [
    "site",
    "lp"
   ],
   "weight": "脇役",
   "relatedIds": [
    "magnetic-button",
    "view-transitions-spa",
    "web-animations-api",
    "text-scramble"
   ]
  },
  {
   "id": "offset-path",
   "num": "W-077",
   "name": "Motion Along a Path (offset-path)",
   "nameJa": "offset-pathでパス移動",
   "category": "motion",
   "description": "offset-pathにSVGパスやshape()を指定し、offset-distanceをアニメさせることで要素を曲線に沿って動かす。offset-rotateで進行方向へ向きも追従できる。",
   "useCase": "アイコンやアバターが曲線を描いて移動する装飾、プロセス図の上を進むポインター、遊び心のあるローディング演出に使う。",
   "code": ".dot {\n  offset-path: path('M10,80 C60,10 180,10 230,80');\n  offset-rotate: auto;\n  animation: opth-run 3s linear infinite;\n}\n@keyframes opth-run { to { offset-distance: 100%; } }",
   "tags": [
    "CSS",
    "offset-path",
    "パスアニメ",
    "軌道",
    "ダイナミック",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"offset-pathでパス移動のデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <path d=\"M20,110 C70,30 170,30 220,110\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-width=\"2\" opacity=\".4\"/>\n  <circle r=\"7\" fill=\"var(--w-accent,#4fe3c1)\">\n    <animateMotion dur=\"3s\" repeatCount=\"indefinite\" rotate=\"auto\" path=\"M20,110 C70,30 170,30 220,110\"/>\n  </circle>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "keyframes-multistep",
    "property-custom-animate",
    "text-stroke-outline",
    "neon-glow-text"
   ]
  },
  {
   "id": "animation-composition",
   "num": "W-078",
   "name": "animation-composition",
   "nameJa": "animation-compositionで複数アニメ合成",
   "category": "motion",
   "description": "同じプロパティ（例: transform）を狙う複数の@keyframesを animation-composition: add / accumulate で足し合わせ、ベースの動きに一時的な演出を重ねられる。",
   "useCase": "常時ゆれる浮遊アニメの上にホバー時だけ追加でバウンドさせるなど、ベースアニメと演出を独立管理したい場面。",
   "code": "@keyframes acmp-float { 50% { transform: translateY(-6px); } }\n@keyframes acmp-nudge { 50% { transform: translateX(10px); } }\n.chip { animation: acmp-float 2.4s ease-in-out infinite; }\n.chip:hover {\n  animation: acmp-float 2.4s ease-in-out infinite,\n             acmp-nudge .6s ease-in-out infinite;\n  animation-composition: add;\n}",
   "tags": [
    "CSS",
    "composition",
    "合成",
    "浮遊",
    "ふわっと",
    "目を引く"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"animation-compositionで複数アニメ合成のデモ\">\n  <style>\n    .acmp-base{animation:acmp-float 2.4s ease-in-out infinite}\n    .acmp-extra{animation:acmp-float 2.4s ease-in-out infinite, acmp-nudge 1.2s ease-in-out infinite;animation-composition:add}\n    @keyframes acmp-float{0%,100%{transform:translateY(0)}50%{transform:translateY(-14px)}}\n    @keyframes acmp-nudge{0%,100%{transform:translateX(0)}50%{transform:translateX(16px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <circle class=\"acmp-base\" cx=\"70\" cy=\"80\" r=\"18\" fill=\"var(--w-sub,#94a3c0)\"/>\n  <circle class=\"acmp-extra\" cx=\"170\" cy=\"80\" r=\"18\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <text x=\"70\" y=\"120\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"9\" fill=\"var(--w-sub,#94a3c0)\">base</text>\n  <text x=\"170\" y=\"120\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"9\" fill=\"var(--w-accent,#4fe3c1)\">add</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "infinite-loop-motion",
    "starting-style",
    "floating-shadow",
    "scroll-reveal"
   ]
  },
  {
   "id": "stagger-delay",
   "num": "W-079",
   "name": "Staggered Delay Chain",
   "nameJa": "時間差の連鎖（スタガーアニメ）",
   "category": "motion",
   "description": ":nth-child()やCSSカスタムプロパティ（--i）でanimation-delayを要素ごとにずらし、順番に発火して見せる。JSでstyle.setProperty('--i', i)する構成が定番。",
   "useCase": "リストやカードグループの初期表示、ナビゲーションメニューの展開など、要素が波のように順番に現れる演出に使う。",
   "code": ".item {\n  animation: stgd-in .5s ease-out both;\n  animation-delay: calc(var(--i) * 80ms);\n}\n@keyframes stgd-in { from { opacity:0; transform: translateY(12px) } }\n\n/* JS: 要素ごとに --i を注入 */\nels.forEach((el, i) => el.style.setProperty('--i', i));",
   "tags": [
    "CSS",
    "JavaScript",
    "stagger",
    "delay",
    "連鎖",
    "ぱらぱら",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"時間差の連鎖（スタガーアニメ）のデモ\">\n  <style>\n    .stgd-bar{animation:stgd-in 3s ease-out infinite}\n    .stgd-1{animation-delay:0s}\n    .stgd-2{animation-delay:.15s}\n    .stgd-3{animation-delay:.3s}\n    .stgd-4{animation-delay:.45s}\n    .stgd-5{animation-delay:.6s}\n    @keyframes stgd-in{0%,4%{opacity:0;transform:translateY(14px)}16%,80%{opacity:1;transform:translateY(0)}92%,100%{opacity:0;transform:translateY(14px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"stgd-bar stgd-1\" x=\"30\" y=\"60\" width=\"24\" height=\"50\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <rect class=\"stgd-bar stgd-2\" x=\"66\" y=\"60\" width=\"24\" height=\"50\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <rect class=\"stgd-bar stgd-3\" x=\"102\" y=\"60\" width=\"24\" height=\"50\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <rect class=\"stgd-bar stgd-4\" x=\"138\" y=\"60\" width=\"24\" height=\"50\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <rect class=\"stgd-bar stgd-5\" x=\"174\" y=\"60\" width=\"24\" height=\"50\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "ripple-effect",
    "scroll-reveal",
    "horizontal-scroll-section",
    "stagger-char-reveal"
   ]
  },
  {
   "id": "infinite-loop-motion",
   "num": "W-080",
   "name": "Infinite Loop Motion (Float / Pulse / Spin)",
   "nameJa": "無限ループ系（浮遊・脈動・回転）",
   "category": "motion",
   "description": "animation-iteration-count: infiniteで浮遊(translateY往復)・脈動(scale/opacity往復)・回転(rotate)を常時再生し、背景装飾やアイコンに生命感を与える基礎パターン。",
   "useCase": "ヒーローセクションの背景オブジェクト、通知バッジの脈動、ローディングスピナーなど止まらず動き続ける装飾全般。",
   "code": "@keyframes iflp-float { 50% { transform: translateY(-10px); } }\n@keyframes iflp-pulse { 50% { transform: scale(1.15); opacity: .7; } }\n@keyframes iflp-spin  { to { transform: rotate(360deg); } }\n.float { animation: iflp-float 3s ease-in-out infinite; }\n.pulse { animation: iflp-pulse 1.6s ease-in-out infinite; }\n.spin  { animation: iflp-spin 2s linear infinite; }",
   "tags": [
    "CSS",
    "keyframes",
    "浮遊",
    "脈動",
    "回転",
    "ふわっと",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"無限ループ系（浮遊・脈動・回転）のデモ\">\n  <style>\n    .iflp-float{animation:iflp-float 3s ease-in-out infinite}\n    .iflp-pulse{animation:iflp-pulse 1.6s ease-in-out infinite;transform-origin:120px 80px}\n    .iflp-spin{animation:iflp-spin 2.4s linear infinite;transform-origin:190px 80px}\n    @keyframes iflp-float{0%,100%{transform:translateY(0)}50%{transform:translateY(-14px)}}\n    @keyframes iflp-pulse{0%,100%{transform:scale(1);opacity:.9}50%{transform:scale(1.3);opacity:.5}}\n    @keyframes iflp-spin{to{transform:rotate(360deg)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <circle class=\"iflp-float\" cx=\"50\" cy=\"80\" r=\"16\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <circle class=\"iflp-pulse\" cx=\"120\" cy=\"80\" r=\"16\" fill=\"var(--w-amber,#ffc857)\"/>\n  <rect class=\"iflp-spin\" x=\"176\" y=\"66\" width=\"28\" height=\"28\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".85\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "animation-composition",
    "keyframes-multistep",
    "starting-style",
    "cube-3d"
   ]
  },
  {
   "id": "web-animations-api",
   "num": "W-081",
   "name": "Web Animations API (element.animate)",
   "nameJa": "Web Animations API（element.animate）",
   "category": "motion",
   "description": "element.animate(keyframes, options)でCSSを書かずJSからキーフレームアニメを生成・制御する。play/pause/reverse/finishedなど再生制御がしやすい。",
   "useCase": "操作に応じて動的にキーフレームを組み立てたい場合や、アニメ完了を待ってから次の処理をつなげたいインタラクティブなUIに使う。",
   "code": "const anim = card.animate(\n  [{ transform: 'scale(1)' }, { transform: 'scale(1.05)' }, { transform: 'scale(1)' }],\n  { duration: 500, easing: 'ease-out', iterations: Infinity }\n);\nbtn.onclick = () => anim.playState === 'running' ? anim.pause() : anim.play();",
   "tags": [
    "JavaScript",
    "WAAPI",
    "制御",
    "インタラクティブ",
    "きびきび",
    "ぬるっと"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"Web Animations API（element.animate）のデモ\">\n  <style>\n    .waapi-box{animation:waapi-scale 3s ease-in-out infinite;transform-origin:120px 76px}\n    .waapi-icon{animation:waapi-blink 3s steps(1) infinite}\n    @keyframes waapi-scale{0%,45%{transform:scale(1)}22%{transform:scale(1.25)}55%,100%{transform:scale(1)}}\n    @keyframes waapi-blink{0%,45%{opacity:1}46%,100%{opacity:.3}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"waapi-box\" x=\"90\" y=\"46\" width=\"60\" height=\"60\" rx=\"10\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <polygon class=\"waapi-icon\" points=\"30,60 30,100 58,80\" fill=\"var(--w-ink,#e8eef9)\"/>\n</svg>",
   "useFor": [
    "site",
    "lp"
   ],
   "weight": "脇役",
   "relatedIds": [
    "mouse-tilt",
    "view-transitions-spa",
    "flip-technique",
    "will-change-gpu"
   ]
  },
  {
   "id": "hover-pause",
   "num": "W-082",
   "name": "Pause on Hover (animation-play-state)",
   "nameJa": "ホバーで一時停止（animation-play-state）",
   "category": "motion",
   "description": ":hoverでanimation-play-state: pausedを当てるだけで、常時ループ中のアニメを止めて詳細を見やすくする。JS不要の軽量な操作性向上テク。",
   "useCase": "自動再生カルーセルやマーキー、回転するロゴをカーソルを乗せている間だけ止めて読みやすくしたい場面。",
   "code": ".marquee { animation: hvpz-scroll 12s linear infinite; }\n.marquee:hover { animation-play-state: paused; }\n@keyframes hvpz-scroll { to { transform: translateX(-50%) } }",
   "tags": [
    "CSS",
    "play-state",
    "ホバー",
    "マーキー",
    "さりげない",
    "すっと"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ホバーで一時停止（animation-play-state）のデモ\">\n  <style>\n    .hvpz-track{animation:hvpz-scroll 4s linear infinite}\n    @keyframes hvpz-scroll{0%,20%{transform:translateX(0)}55%,75%{transform:translateX(-90px)}100%{transform:translateX(-180px)}}\n    .hvpz-cursor{animation:hvpz-cursor 4s ease-in-out infinite}\n    @keyframes hvpz-cursor{0%,18%{opacity:0}22%,73%{opacity:1}77%,100%{opacity:0}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <text class=\"hvpz-track\" x=\"20\" y=\"80\" font-family=\"ui-monospace,monospace\" font-size=\"13\" fill=\"var(--w-ink,#e8eef9)\">NEW ARRIVAL - SALE - NEW ARRIVAL</text>\n  <polygon class=\"hvpz-cursor\" points=\"150,95 150,112 162,104\" fill=\"var(--w-amber,#ffc857)\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "transition-basics",
    "hover-focus-states",
    "tooltip",
    "hover-lift-card"
   ]
  },
  {
   "id": "interpolate-size",
   "num": "W-083",
   "name": "interpolate-size: allow-keywords",
   "nameJa": "interpolate-sizeでheight: autoへのアニメ",
   "category": "motion",
   "description": "html { interpolate-size: allow-keywords; }を指定すると、heightやwidthのautoなどキーワード値もtransitionの対象になり、高さを逆算する処理が不要になる。",
   "useCase": "アコーディオンやFAQの開閉、可変長リストの展開をJSで高さ計測せずCSSだけでheight: autoへ滑らかにアニメさせたい場面。",
   "code": "html { interpolate-size: allow-keywords; }\n.accordion-body {\n  height: 0;\n  overflow: hidden;\n  transition: height .3s ease;\n}\n.accordion-body[data-open] { height: auto; }",
   "tags": [
    "CSS",
    "interpolate-size",
    "アコーディオン",
    "height",
    "ぬるっと",
    "すっきり"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"interpolate-sizeでheight: autoへのアニメのデモ\">\n  <style>\n    .ipsz-panel{animation:ipsz-grow 3.5s ease-in-out infinite;transform-origin:0 0}\n    @keyframes ipsz-grow{0%,15%{transform:scaleY(.15)}45%,80%{transform:scaleY(1)}100%{transform:scaleY(.15)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"40\" y=\"30\" width=\"160\" height=\"24\" rx=\"6\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/>\n  <g transform=\"translate(40,58)\">\n    <rect class=\"ipsz-panel\" x=\"0\" y=\"0\" width=\"160\" height=\"60\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\"/>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "view-transitions-spa",
    "view-transitions-mpa",
    "allow-discrete",
    "details-content"
   ]
  },
  {
   "id": "allow-discrete",
   "num": "W-084",
   "name": "transition-behavior: allow-discrete",
   "nameJa": "allow-discreteでdisplayをアニメ",
   "category": "motion",
   "description": "transition-propertyにdisplayやcontent-visibilityを含め、transition-behavior: allow-discreteを指定すると、none⇔blockの切り替えも他プロパティと同期してフェードできる。",
   "useCase": "モーダルやツールチップをdisplay: noneで完全に消しつつ、消える直前までopacityのフェードアウトを見せたい場面。",
   "code": ".modal {\n  opacity: 0;\n  display: none;\n  transition: opacity .25s, display .25s allow-discrete;\n}\n.modal[open] { opacity: 1; display: block; }",
   "tags": [
    "CSS",
    "allow-discrete",
    "display",
    "モーダル",
    "ぬるっと",
    "ふわっと"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"allow-discreteでdisplayをアニメのデモ\">\n  <style>\n    .adsc-modal{animation:adsc-fade 3.2s ease-in-out infinite;transform-origin:120px 75px}\n    @keyframes adsc-fade{0%,10%{opacity:0;transform:scale(.9)}30%,70%{opacity:1;transform:scale(1)}90%,100%{opacity:0;transform:scale(.9)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"20\" y=\"20\" width=\"200\" height=\"110\" rx=\"8\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".12\"/>\n  <rect class=\"adsc-modal\" x=\"70\" y=\"50\" width=\"100\" height=\"50\" rx=\"8\" fill=\"var(--w-accent,#4fe3c1)\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "starting-style",
    "easing-design",
    "view-transitions-spa",
    "view-transitions-mpa"
   ]
  },
  {
   "id": "will-change-gpu",
   "num": "W-085",
   "name": "will-change & GPU Compositing Caution",
   "nameJa": "will-changeとGPU合成の注意",
   "category": "motion",
   "description": "will-change: transformで事前にレイヤー分離を促しアニメをなめらかにする一方、多用するとメモリを圧迫するため、アニメ直前に付与し終了後は解除する運用が要点。",
   "useCase": "スクロールに連動する大きな要素や常時アニメする背景装飾で、カクつき（ジャンク）を防ぎつつレイヤー爆発は避けたい場面。",
   "code": ".card { transition: transform .3s; }\n.card:hover {\n  will-change: transform;\n  transform: translateY(-6px);\n}\n\n/* JS: 終了後に解除する運用 */\nel.addEventListener('transitionend', () => {\n  el.style.willChange = 'auto';\n});",
   "tags": [
    "CSS",
    "JavaScript",
    "will-change",
    "GPU",
    "きびきび",
    "なめらか"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"will-changeとGPU合成の注意のデモ\">\n  <style>\n    .wcgp-janky{animation:wcgp-jank 3s steps(5) infinite}\n    .wcgp-smooth{animation:wcgp-move 3s ease-in-out infinite}\n    @keyframes wcgp-jank{0%,100%{transform:translateX(0)}50%{transform:translateX(140px)}}\n    @keyframes wcgp-move{0%,100%{transform:translateX(0)}50%{transform:translateX(140px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <circle class=\"wcgp-janky\" cx=\"30\" cy=\"50\" r=\"10\" fill=\"var(--w-sub,#94a3c0)\"/>\n  <circle class=\"wcgp-smooth\" cx=\"30\" cy=\"100\" r=\"10\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <text x=\"20\" y=\"30\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"9\" fill=\"var(--w-sub,#94a3c0)\">without</text>\n  <text x=\"20\" y=\"130\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"9\" fill=\"var(--w-accent,#4fe3c1)\">will-change</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "view-transitions-spa",
    "web-animations-api",
    "css-custom-highlights",
    "transition-basics"
   ]
  },
  {
   "id": "reduced-motion",
   "num": "W-086",
   "name": "Respecting prefers-reduced-motion",
   "nameJa": "prefers-reduced-motion対応",
   "category": "motion",
   "description": "@media (prefers-reduced-motion: reduce)でアニメ時間を極小化・無効化し、OS設定でアニメを減らしたいユーザーに配慮する。動き系の実装で必ず添える基礎。",
   "useCase": "大きく動く背景演出やパララックスを含むLPやサイト全般で、めまいや不快感に配慮したアクセシビリティ対応が必要な場面。",
   "code": "@media (prefers-reduced-motion: reduce) {\n  *, *::before, *::after {\n    animation-duration: .001ms !important;\n    animation-iteration-count: 1 !important;\n    transition-duration: .001ms !important;\n  }\n}",
   "tags": [
    "CSS",
    "アクセシビリティ",
    "reduced-motion",
    "基礎",
    "さりげない",
    "ひかえめ"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"prefers-reduced-motion対応のデモ\">\n  <style>\n    .rdmo-spin{animation:rdmo-rot 2.4s linear infinite;transform-origin:70px 75px}\n    @keyframes rdmo-rot{to{transform:rotate(360deg)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"rdmo-spin\" x=\"55\" y=\"60\" width=\"30\" height=\"30\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <rect x=\"155\" y=\"60\" width=\"30\" height=\"30\" fill=\"var(--w-amber,#ffc857)\"/>\n  <text x=\"70\" y=\"125\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"9\" fill=\"var(--w-sub,#94a3c0)\">no-preference</text>\n  <text x=\"170\" y=\"125\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"9\" fill=\"var(--w-sub,#94a3c0)\">reduce</text>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "transition-basics",
    "hover-focus-states",
    "keyframes-multistep",
    "easing-design"
   ]
  },
  {
   "id": "property-custom-animate",
   "num": "W-087",
   "name": "@property Registered Custom Property Animation",
   "nameJa": "@propertyでカスタムプロパティをアニメ",
   "category": "motion",
   "description": "@propertyでカスタムプロパティに型(syntax)と初期値を登録すると、通常は補間できないグラデーション角度や色までtransition/animationで滑らかに変化させられる。",
   "useCase": "グラデーションの回転演出や数値カウントアップ表示など、素のCSSでは補間できない値を動かしたい場面。",
   "code": "@property --pcst-angle {\n  syntax: '<angle>';\n  inherits: false;\n  initial-value: 0deg;\n}\n.gradient {\n  background: conic-gradient(from var(--pcst-angle), var(--accent), var(--bg));\n  transition: --pcst-angle 1s linear;\n}\n.gradient:hover { --pcst-angle: 360deg; }",
   "tags": [
    "CSS",
    "@property",
    "カスタムプロパティ",
    "グラデーション",
    "ダイナミック",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"@propertyでカスタムプロパティをアニメのデモ\">\n  <style>\n    @property --pcst-hue{syntax:'&lt;angle&gt;';inherits:false;initial-value:0deg}\n    .pcst-wheel{animation:pcst-spin 3s linear infinite;filter:hue-rotate(var(--pcst-hue))}\n    @keyframes pcst-spin{to{--pcst-hue:360deg}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"pcst-wheel\">\n    <path d=\"M120,75 L120,35 A40,40 0 0,1 154,95 Z\" fill=\"var(--w-accent,#4fe3c1)\"/>\n    <path d=\"M120,75 L154,95 A40,40 0 0,1 86,95 Z\" fill=\"var(--w-amber,#ffc857)\"/>\n    <path d=\"M120,75 L86,95 A40,40 0 0,1 120,35 Z\" fill=\"var(--w-sub,#94a3c0)\"/>\n  </g>\n  <circle cx=\"120\" cy=\"75\" r=\"6\" fill=\"var(--w-bg,#101830)\"/>\n  <text x=\"120\" y=\"128\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"9\" fill=\"var(--w-sub,#94a3c0)\">hue cycles via @property</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "keyframes-multistep",
    "offset-path",
    "gradient-text",
    "text-stroke-outline"
   ]
  },
  {
   "id": "hover-focus-states",
   "num": "W-088",
   "name": "Hover & Focus-Visible States",
   "nameJa": "ホバー・フォーカス状態設計",
   "category": "interact",
   "description": "マウス操作の:hoverとキーボード操作の:focus-visibleを分離し、マウス時は枠線を出さずキーボード操作時だけ明示的なアウトラインを表示する状態設計。",
   "useCase": "ボタン・リンク・フォーム全般で、見た目の綺麗さとキーボード操作のアクセシビリティを両立したい場面。",
   "code": ".btn:hover { background: #2563eb; }\n.btn:focus-visible {\n  outline: 3px solid #93c5fd;\n  outline-offset: 2px;\n}\n.btn:focus:not(:focus-visible) { outline: none; }",
   "tags": [
    "CSS",
    "アクセシビリティ",
    "ホバー",
    "フォーカス",
    "さりげない",
    "基本"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ホバー・フォーカス状態設計のデモ\"><style>.hfs-cur{animation:hfs-cur-move 4s ease-in-out infinite}@keyframes hfs-cur-move{0%,5%{transform:translateY(-55px);opacity:1}20%,40%{transform:translateY(0);opacity:1}50%{transform:translateY(-55px);opacity:0}100%{transform:translateY(-55px);opacity:1}}.hfs-b1{animation:hfs-glow 4s ease-in-out infinite}@keyframes hfs-glow{0%,15%{fill:var(--w-sub,#94a3c0)}25%,42%{fill:var(--w-accent,#4fe3c1)}50%,100%{fill:var(--w-sub,#94a3c0)}}.hfs-kbd{animation:hfs-ring 4s ease-in-out infinite}@keyframes hfs-ring{0%,55%{opacity:0}65%,88%{opacity:1}100%{opacity:0}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect class=\"hfs-b1\" x=\"20\" y=\"60\" width=\"80\" height=\"30\" rx=\"6\"/><text x=\"60\" y=\"80\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\">Hover</text><circle class=\"hfs-cur\" cx=\"60\" cy=\"75\" r=\"5\" fill=\"var(--w-ink,#e8eef9)\"/><rect x=\"140\" y=\"60\" width=\"80\" height=\"30\" rx=\"6\" fill=\"var(--w-sub,#94a3c0)\"/><text x=\"180\" y=\"80\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-ink,#e8eef9)\" text-anchor=\"middle\">Focus</text><g class=\"hfs-kbd\"><rect x=\"136\" y=\"56\" width=\"88\" height=\"38\" rx=\"8\" fill=\"none\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"3\" stroke-dasharray=\"4 3\"/><rect x=\"163\" y=\"24\" width=\"34\" height=\"16\" rx=\"3\" fill=\"var(--w-amber,#ffc857)\"/><text x=\"180\" y=\"36\" font-family=\"ui-monospace,monospace\" font-size=\"9\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\">Tab</text></g><text x=\"120\" y=\"128\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"9\" fill=\"var(--w-sub,#94a3c0)\" text-anchor=\"middle\">mouse vs Tab key</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "tooltip",
    "hover-pause",
    "reduced-motion",
    "hover-lift-card"
   ]
  },
  {
   "id": "has-selector-interact",
   "num": "W-089",
   "name": ":has() Parent Selector",
   "nameJa": ":has()親セレクタ活用",
   "category": "interact",
   "description": "子要素の状態に応じて親要素の見た目を:has()で切り替えるCSSセレクタ。チェック済みの子を持つカードの枠線を強調するなどJS無しで実現できる。",
   "useCase": "カード選択のハイライト、フォームのエラー枠強調など、親の見た目を子の状態で変えたいレイアウト全般。",
   "code": ".card:has(input:checked) {\n  border-color: var(--w-accent, #4fe3c1);\n  background: rgba(79,227,193,.08);\n}\n.form-group:has(:invalid) { outline: 2px solid crimson; }",
   "tags": [
    "CSS",
    "セレクタ",
    "状態管理",
    "普及中",
    "スマート",
    "省コード"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\":has親セレクタ活用のデモ\"><style>.hsl-card{animation:hsl-glow 3.5s ease-in-out infinite}@keyframes hsl-glow{0%,20%{stroke:var(--w-sub,#94a3c0)}40%,80%{stroke:var(--w-accent,#4fe3c1)}100%{stroke:var(--w-sub,#94a3c0)}}.hsl-check{animation:hsl-check 3.5s ease-in-out infinite;opacity:0}@keyframes hsl-check{0%,20%{opacity:0}40%,80%{opacity:1}100%{opacity:0}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect class=\"hsl-card\" x=\"40\" y=\"30\" width=\"160\" height=\"90\" rx=\"10\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-width=\"3\"/><rect x=\"60\" y=\"60\" width=\"18\" height=\"18\" rx=\"4\" fill=\"none\" stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"2\"/><path class=\"hsl-check\" d=\"M63 69 l6 6 l10 -12\" fill=\"none\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"3\" stroke-linecap=\"round\"/><text x=\"150\" y=\"72\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"11\" fill=\"var(--w-ink,#e8eef9)\" text-anchor=\"middle\">Card</text><text x=\"120\" y=\"130\" font-family=\"ui-monospace,monospace\" font-size=\"9\" fill=\"var(--w-sub,#94a3c0)\" text-anchor=\"middle\">:has(input:checked)</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "anchor-positioning",
    "details-summary-accordion",
    "popover-api",
    "css-scroll-controls"
   ]
  },
  {
   "id": "popover-api",
   "num": "W-090",
   "name": "Popover API",
   "nameJa": "Popover API",
   "category": "interact",
   "description": "要素にpopover属性、トリガーにpopovertarget属性を付けるだけでトップレイヤー表示のポップアップを実装できるAPI。外側クリックやEscで自動的に閉じる。",
   "useCase": "メニュー・ヒントカード・簡易通知など、z-index管理やJSの開閉制御を書かずに浮かせたいUI全般。",
   "code": "<button popovertarget=\"menu\">開く</button>\n<div id=\"menu\" popover>\n  <ul><li>編集</li><li>削除</li></ul>\n</div>",
   "tags": [
    "HTML",
    "API",
    "レイヤー",
    "普及中",
    "パッと切替",
    "省コード"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"Popover APIのデモ\"><style>.pop-panel{animation:pop-show 4s ease-in-out infinite;transform-origin:65px 90px}@keyframes pop-show{0%,15%{opacity:0;transform:scale(.85) translateY(6px)}30%,70%{opacity:1;transform:scale(1) translateY(0)}85%,100%{opacity:0;transform:scale(.85) translateY(6px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"30\" y=\"95\" width=\"70\" height=\"26\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\"/><text x=\"65\" y=\"112\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\">開く</text><g class=\"pop-panel\"><rect x=\"30\" y=\"30\" width=\"110\" height=\"55\" rx=\"8\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".95\"/><rect x=\"42\" y=\"42\" width=\"60\" height=\"7\" rx=\"3\" fill=\"var(--w-bg,#101830)\" opacity=\".5\"/><rect x=\"42\" y=\"56\" width=\"80\" height=\"7\" rx=\"3\" fill=\"var(--w-bg,#101830)\" opacity=\".5\"/><rect x=\"42\" y=\"70\" width=\"50\" height=\"7\" rx=\"3\" fill=\"var(--w-bg,#101830)\" opacity=\".5\"/></g><text x=\"180\" y=\"60\" font-family=\"ui-monospace,monospace\" font-size=\"10\" fill=\"var(--w-sub,#94a3c0)\">top-layer</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "details-summary-accordion",
    "dialog-modal",
    "has-selector-interact",
    "anchor-positioning"
   ]
  },
  {
   "id": "dialog-modal",
   "num": "W-091",
   "name": "<dialog> Modal",
   "nameJa": "dialog要素のモーダル",
   "category": "interact",
   "description": "dialog要素の.showModal()でネイティブモーダルを開く。背景は::backdropで暗転し、フォーカストラップとEscでの閉じる挙動が標準で備わっている。",
   "useCase": "確認ダイアログ・フォームモーダル・利用規約表示など、自前でフォーカス管理を書かずにモーダルを作りたい場面。",
   "code": "<dialog id=\"d\"><p>確認しますか？</p><button onclick=\"d.close()\">閉じる</button></dialog>\n<script>d.showModal()</script>",
   "tags": [
    "HTML",
    "API",
    "モーダル",
    "安定",
    "パッと切替",
    "高級感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"dialog要素のモーダルのデモ\"><style>.dlg-back{animation:dlg-dim 4s ease-in-out infinite}@keyframes dlg-dim{0%,15%{opacity:0}30%,70%{opacity:.6}85%,100%{opacity:0}}.dlg-box{animation:dlg-pop 4s ease-in-out infinite;transform-origin:120px 75px}@keyframes dlg-pop{0%,15%{opacity:0;transform:scale(.8)}30%,70%{opacity:1;transform:scale(1)}85%,100%{opacity:0;transform:scale(.8)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"10\" y=\"10\" width=\"100\" height=\"14\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".4\"/><rect x=\"10\" y=\"30\" width=\"140\" height=\"14\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".4\"/><rect class=\"dlg-back\" width=\"240\" height=\"150\" fill=\"var(--w-bg,#101830)\"/><g class=\"dlg-box\"><rect x=\"60\" y=\"45\" width=\"120\" height=\"60\" rx=\"10\" fill=\"var(--w-ink,#e8eef9)\"/><text x=\"120\" y=\"72\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\">確認しますか？</text><rect x=\"95\" y=\"82\" width=\"50\" height=\"16\" rx=\"5\" fill=\"var(--w-accent,#4fe3c1)\"/><text x=\"120\" y=\"94\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"9\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\">閉じる</text></g></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "popover-api",
    "target-css-toggle",
    "command-palette",
    "lightbox-dialog"
   ]
  },
  {
   "id": "anchor-positioning",
   "num": "W-092",
   "name": "CSS Anchor Positioning",
   "nameJa": "アンカーポジショニング",
   "category": "interact",
   "description": "anchor-nameで基準要素を登録し、position-anchor・position-area・anchor()で別要素を相対配置するCSS機能。主要ブラウザの最新版で利用でき、position-try-fallbacksで表示領域外へのはみ出しも回避できる。",
   "useCase": "ドロップダウンやツールチップをトリガーボタンに追従させたいが、ライブラリを使わず素のCSSで完結させたい場面。",
   "code": ".trigger { anchor-name: --btn; }\n.menu {\n  position: absolute;\n  position-anchor: --btn;\n  top: anchor(bottom);\n  left: anchor(left);\n}",
   "tags": [
    "CSS",
    "位置",
    "レイアウト",
    "アンカー",
    "普及中",
    "省コード"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"アンカーポジショニングのデモ\"><style>.apo-group{animation:apo-move 4.5s ease-in-out infinite}@keyframes apo-move{0%,20%{transform:translateX(0)}50%,70%{transform:translateX(90px)}100%{transform:translateX(0)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g class=\"apo-group\"><rect x=\"30\" y=\"30\" width=\"60\" height=\"24\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\"/><text x=\"60\" y=\"46\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"9\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\">anchor</text><line x1=\"60\" y1=\"54\" x2=\"60\" y2=\"66\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"2\" stroke-dasharray=\"3 3\"/><rect x=\"25\" y=\"66\" width=\"70\" height=\"34\" rx=\"6\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".9\"/><rect x=\"33\" y=\"74\" width=\"40\" height=\"6\" rx=\"2\" fill=\"var(--w-bg,#101830)\" opacity=\".5\"/><rect x=\"33\" y=\"86\" width=\"30\" height=\"6\" rx=\"2\" fill=\"var(--w-bg,#101830)\" opacity=\".5\"/></g><text x=\"120\" y=\"130\" font-family=\"ui-monospace,monospace\" font-size=\"9\" fill=\"var(--w-sub,#94a3c0)\" text-anchor=\"middle\">anchor() / anchor-name</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "has-selector-interact",
    "scroll-margin-padding",
    "details-summary-accordion",
    "text-orientation-upright"
   ]
  },
  {
   "id": "details-summary-accordion",
   "num": "W-093",
   "name": "Details/Summary Exclusive Accordion",
   "nameJa": "アコーディオン（details/summary）",
   "category": "interact",
   "description": "details要素とsummaryだけで開閉するアコーディオン。同じname属性を複数のdetailsに付けるとラジオボタンのように1つだけ開く排他制御になる。",
   "useCase": "FAQ・仕様一覧・LPの折りたたみセクションをJSを書かずに実装したい場面。",
   "code": "<details name=\"faq\"><summary>質問A</summary><p>回答A</p></details>\n<details name=\"faq\"><summary>質問B</summary><p>回答B</p></details>",
   "tags": [
    "HTML",
    "アコーディオン",
    "省コード",
    "さりげない",
    "普及中"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"アコーディオンdetails summaryのデモ\"><style>.dsa-pa{animation:dsa-a 5s ease-in-out infinite}.dsa-pb{animation:dsa-b 5s ease-in-out infinite}@keyframes dsa-a{0%,15%{height:0}30%,65%{height:32px}80%,100%{height:0}}@keyframes dsa-b{0%,65%{height:0}80%,95%{height:32px}100%{height:0}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"30\" y=\"20\" width=\"180\" height=\"22\" rx=\"5\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/><text x=\"40\" y=\"35\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-ink,#e8eef9)\">質問A</text><rect class=\"dsa-pa\" x=\"30\" y=\"42\" width=\"180\" height=\"32\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".15\"/><rect x=\"30\" y=\"84\" width=\"180\" height=\"22\" rx=\"5\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/><text x=\"40\" y=\"99\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-ink,#e8eef9)\">質問B</text><rect class=\"dsa-pb\" x=\"30\" y=\"106\" width=\"180\" height=\"32\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".15\"/></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "popover-api",
    "inert-attribute",
    "has-selector-interact",
    "anchor-positioning"
   ]
  },
  {
   "id": "tooltip",
   "num": "W-094",
   "name": "CSS Tooltip",
   "nameJa": "ツールチップ",
   "category": "interact",
   "description": "要素の::afterにcontent: attr(data-tip)で吹き出しを仕込み、:hoverや:focus時にopacityとtransformでふわっと表示するCSSツールチップ。",
   "useCase": "アイコンボタンの説明や専門用語の補足、フォーム入力欄のヒントなど、常時は隠しておきたい補足情報の表示。",
   "code": ".tip { position: relative; }\n.tip::after {\n  content: attr(data-tip);\n  position: absolute; bottom: 130%; left: 50%;\n  transform: translateX(-50%) translateY(4px);\n  opacity: 0; transition: .2s;\n}\n.tip:hover::after { opacity: 1; transform: translateX(-50%) translateY(0); }",
   "tags": [
    "CSS",
    "ホバー",
    "補足情報",
    "安定",
    "ふわっと",
    "さりげない"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ツールチップのデモ\"><style>.ttp-cur{animation:ttp-cur 4s ease-in-out infinite}@keyframes ttp-cur{0%,10%{transform:translateY(28px);opacity:0}25%,75%{transform:translateY(0);opacity:1}90%,100%{transform:translateY(28px);opacity:0}}.ttp-bub{animation:ttp-show 4s ease-in-out infinite}@keyframes ttp-show{0%,20%{opacity:0;transform:translateY(6px)}35%,75%{opacity:1;transform:translateY(0)}90%,100%{opacity:0;transform:translateY(6px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><circle cx=\"120\" cy=\"100\" r=\"14\" fill=\"var(--w-sub,#94a3c0)\"/><text x=\"120\" y=\"105\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"12\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\">?</text><g class=\"ttp-bub\"><rect x=\"70\" y=\"48\" width=\"100\" height=\"28\" rx=\"6\" fill=\"var(--w-ink,#e8eef9)\"/><polygon points=\"115,76 125,76 120,86\" fill=\"var(--w-ink,#e8eef9)\"/><text x=\"120\" y=\"66\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"9\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\">補足説明テキスト</text></g><circle class=\"ttp-cur\" cx=\"120\" cy=\"90\" r=\"4\" fill=\"var(--w-amber,#ffc857)\"/></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "hover-focus-states",
    "hover-pause",
    "hover-lift-card",
    "clip-path-shapes"
   ]
  },
  {
   "id": "custom-cursor",
   "num": "W-095",
   "name": "Custom Cursor",
   "nameJa": "カスタムカーソル",
   "category": "interact",
   "description": "cursor: noneでシステムカーソルを消し、fixed配置の要素をmousemoveの座標に合わせてtransformで追従させ、独自グラフィックのカーソルに差し替える演出。",
   "useCase": "ブランド世界観の強いLPやポートフォリオサイトで、カーソル自体を演出の一部にしたい場面。",
   "code": "body { cursor: none; }\n.cursor-dot {\n  position: fixed; width: 20px; height: 20px; border-radius: 50%;\n  background: var(--accent); pointer-events: none;\n  transform: translate(var(--x), var(--y));\n  transition: transform .08s linear;\n}",
   "tags": [
    "CSS",
    "JS",
    "カーソル",
    "演出",
    "目を引く",
    "高級感",
    "ダイナミック"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"カスタムカーソルのデモ\"><style>.ccu-ring{animation:ccu-path 5s ease-in-out infinite}@keyframes ccu-path{0%{transform:translate(30px,30px)}25%{transform:translate(180px,40px)}50%{transform:translate(160px,110px)}75%{transform:translate(50px,100px)}100%{transform:translate(30px,30px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"20\" y=\"20\" width=\"200\" height=\"110\" rx=\"8\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-width=\"1\" opacity=\".3\"/><g class=\"ccu-ring\"><circle r=\"14\" fill=\"none\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"2\"/><circle r=\"3\" fill=\"var(--w-amber,#ffc857)\"/></g></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "horizontal-scroll-section",
    "carousel-3d",
    "cursor-spotlight",
    "laser-pointer-cursor"
   ]
  },
  {
   "id": "magnetic-button",
   "num": "W-096",
   "name": "Magnetic Button",
   "nameJa": "磁石ボタン",
   "category": "interact",
   "description": "mousemoveでカーソルとボタン中心の距離を計算し、近づくとボタンをtransform: translateで引き寄せ、離れるとease-outで元位置へ戻す動き。",
   "useCase": "CTAボタンやSNSアイコンなど、操作の楽しさとクリック率を上げたい主要導線に使う。",
   "code": "btn.addEventListener('mousemove', e => {\n  const r = btn.getBoundingClientRect();\n  const x = e.clientX - r.left - r.width / 2;\n  const y = e.clientY - r.top - r.height / 2;\n  btn.style.transform = `translate(${x * .3}px, ${y * .3}px)`;\n});\nbtn.addEventListener('mouseleave', () => btn.style.transform = '');",
   "tags": [
    "JS",
    "ホバー",
    "CTA",
    "ダイナミック",
    "目を引く",
    "ぬるっと"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"磁石ボタンのデモ\"><style>.mgb-cur{animation:mgb-cur 4s ease-in-out infinite}@keyframes mgb-cur{0%,15%{transform:translate(60px,0)}45%,60%{transform:translate(0,0)}90%,100%{transform:translate(60px,0)}}.mgb-btn{animation:mgb-btn 4s ease-in-out infinite}@keyframes mgb-btn{0%,15%{transform:translate(0,0)}45%,60%{transform:translate(14px,0)}90%,100%{transform:translate(0,0)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g class=\"mgb-btn\"><rect x=\"90\" y=\"60\" width=\"70\" height=\"30\" rx=\"15\" fill=\"var(--w-accent,#4fe3c1)\"/><text x=\"125\" y=\"80\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\">CLICK</text></g><circle class=\"mgb-cur\" cx=\"190\" cy=\"75\" r=\"6\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".8\"/></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "text-scramble",
    "custom-cursor",
    "drag-and-drop",
    "flip-technique"
   ]
  },
  {
   "id": "ripple-effect",
   "num": "W-097",
   "name": "Ripple Effect",
   "nameJa": "リップルエフェクト",
   "category": "interact",
   "description": "クリック位置を起点に円をscale(0)からscale(4)へ広げながらopacityを0にするアニメーションで、水面の波紋のような押下フィードバックを出す表現。",
   "useCase": "Material Design風のボタン・カードタップで、押した瞬間のフィードバックを視覚的に強調したい場面。",
   "code": ".ripple {\n  position: absolute; border-radius: 50%;\n  background: rgba(255,255,255,.5);\n  transform: scale(0); animation: ripple .6s linear;\n}\n@keyframes ripple { to { transform: scale(4); opacity: 0; } }",
   "tags": [
    "CSS",
    "JS",
    "クリック",
    "フィードバック",
    "パッと切替",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"リップルエフェクトのデモ\">\n  <style>.rip-ring{transform-origin:120px 75px;animation:rip-wave 2.8s ease-out infinite}.rip-b{animation-delay:1.4s}@keyframes rip-wave{0%{transform:scale(.3);opacity:1}75%{opacity:.35}100%{transform:scale(6);opacity:0}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"58\" y=\"49\" width=\"124\" height=\"52\" rx=\"10\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".32\"/><circle class=\"rip-ring rip-a\" cx=\"120\" cy=\"75\" r=\"8\" fill=\"none\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"4\"/><circle class=\"rip-ring rip-b\" cx=\"120\" cy=\"75\" r=\"8\" fill=\"none\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"3\"/>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">click feedback</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "copy-button",
    "custom-cursor",
    "toast-notification",
    "scroll-reveal"
   ]
  },
  {
   "id": "copy-button",
   "num": "W-098",
   "name": "Copy Button",
   "nameJa": "コピー機能付きボタン",
   "category": "interact",
   "description": "navigator.clipboard.writeText()でテキストをコピーし、成功時だけボタンのラベルを一瞬「完了」に切り替える。",
   "useCase": "コードブロック・クーポンコード・共有用URLなど、ユーザーにワンクリックでコピーさせたい場面。",
   "code": "btn.addEventListener('click', async () => {\n  await navigator.clipboard.writeText(code);\n  btn.textContent = 'コピーしました';\n  setTimeout(() => btn.textContent = 'コピー', 1500);\n});",
   "tags": [
    "JS",
    "API",
    "クリック",
    "フィードバック",
    "パッと切替",
    "便利"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"コピーボタンのデモ\"><style>.cpb-a{animation:cpb-a 3s steps(1) infinite}.cpb-b{animation:cpb-b 3s steps(1) infinite}@keyframes cpb-a{0%,50%{opacity:1}50.01%,100%{opacity:0}}@keyframes cpb-b{0%,50%{opacity:0}50.01%,100%{opacity:1}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"60\" y=\"55\" width=\"120\" height=\"40\" rx=\"8\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/><g class=\"cpb-a\"><rect x=\"100\" y=\"65\" width=\"14\" height=\"18\" rx=\"2\" fill=\"none\" stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"2\"/><rect x=\"106\" y=\"70\" width=\"14\" height=\"18\" rx=\"2\" fill=\"var(--w-bg,#101830)\" stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"2\"/><text x=\"142\" y=\"80\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-ink,#e8eef9)\">コピー</text></g><g class=\"cpb-b\"><path d=\"M100 76 l8 8 l16 -18\" fill=\"none\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"3\" stroke-linecap=\"round\"/><text x=\"150\" y=\"80\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-accent,#4fe3c1)\">完了</text></g></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "ripple-effect",
    "web-share-api",
    "scroll-spy-nav",
    "popover-api"
   ]
  },
  {
   "id": "web-share-api",
   "num": "W-099",
   "name": "Web Share API",
   "nameJa": "Web Share API",
   "category": "interact",
   "description": "navigator.share()を呼ぶとOS標準の共有シートが開き、LINEやXなど端末にインストール済みのアプリへ直接共有できる。対応判定はnavigator.shareの有無で行う。",
   "useCase": "モバイル中心のLPや記事ページで、個別のSNSシェアボタンを並べずネイティブ共有UIを使いたい場面。",
   "code": "if (navigator.share) {\n  shareBtn.onclick = () => navigator.share({\n    title: document.title, url: location.href\n  });\n}",
   "tags": [
    "JS",
    "API",
    "シェア",
    "モバイル",
    "パッと切替",
    "便利"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"Web Share APIのデモ\"><style>.wsh-sheet{animation:wsh-up 4s ease-in-out infinite}@keyframes wsh-up{0%,20%{transform:translateY(70px)}40%,80%{transform:translateY(0)}100%{transform:translateY(70px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><circle cx=\"120\" cy=\"30\" r=\"12\" fill=\"var(--w-sub,#94a3c0)\"/><path d=\"M120 24v11M115 28l5-5 5 5\" fill=\"none\" stroke=\"var(--w-bg,#101830)\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><g class=\"wsh-sheet\"><rect x=\"30\" y=\"70\" width=\"180\" height=\"60\" rx=\"10\" fill=\"var(--w-ink,#e8eef9)\"/><circle cx=\"60\" cy=\"100\" r=\"12\" fill=\"var(--w-accent,#4fe3c1)\"/><circle cx=\"120\" cy=\"100\" r=\"12\" fill=\"var(--w-amber,#ffc857)\"/><circle cx=\"180\" cy=\"100\" r=\"12\" fill=\"var(--w-sub,#94a3c0)\"/></g></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "copy-button",
    "scroll-spy-nav",
    "popover-api",
    "dialog-modal"
   ]
  },
  {
   "id": "target-css-toggle",
   "num": "W-100",
   "name": "CSS-only Page with :target",
   "nameJa": ":targetでCSSだけのページ切替",
   "category": "interact",
   "description": "aタグのhrefでid付き要素へジャンプし、:target擬似クラスで表示中の要素だけdisplay:blockにする。JS無しでタブ切替や簡易モーダルを作れる。",
   "useCase": "静的サイトでタブUIやライトボックス、簡易モーダルをJS無しで実装したい場面。",
   "code": ".panel { display: none; }\n.panel:target { display: block; }\n\n<a href=\"#tab1\">Tab1</a>\n<div id=\"tab1\" class=\"panel\">内容</div>",
   "tags": [
    "CSS",
    "HTML",
    "ページ切替",
    "安定",
    "パッと切替",
    "軽量"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\":targetページ切替のデモ\"><style>.tgt-t1{animation:tgt-t1 4s steps(1) infinite}.tgt-t2{animation:tgt-t2 4s steps(1) infinite}.tgt-p1{animation:tgt-p1 4s steps(1) infinite}.tgt-p2{animation:tgt-p2 4s steps(1) infinite}@keyframes tgt-t1{0%,50%{fill:var(--w-accent,#4fe3c1)}50.01%,100%{fill:var(--w-sub,#94a3c0)}}@keyframes tgt-t2{0%,50%{fill:var(--w-sub,#94a3c0)}50.01%,100%{fill:var(--w-accent,#4fe3c1)}}@keyframes tgt-p1{0%,50%{opacity:1}50.01%,100%{opacity:0}}@keyframes tgt-p2{0%,50%{opacity:0}50.01%,100%{opacity:1}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect class=\"tgt-t1\" x=\"30\" y=\"25\" width=\"80\" height=\"24\" rx=\"5\"/><rect class=\"tgt-t2\" x=\"120\" y=\"25\" width=\"80\" height=\"24\" rx=\"5\"/><text x=\"70\" y=\"41\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\">#tab1</text><text x=\"160\" y=\"41\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\">#tab2</text><g class=\"tgt-p1\"><rect x=\"30\" y=\"60\" width=\"170\" height=\"60\" rx=\"8\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".15\"/><text x=\"115\" y=\"94\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"11\" fill=\"var(--w-ink,#e8eef9)\" text-anchor=\"middle\">内容 1</text></g><g class=\"tgt-p2\"><rect x=\"30\" y=\"60\" width=\"170\" height=\"60\" rx=\"8\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".15\"/><text x=\"115\" y=\"94\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"11\" fill=\"var(--w-ink,#e8eef9)\" text-anchor=\"middle\">内容 2</text></g></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "dialog-modal",
    "customizable-select",
    "popover-api",
    "tooltip"
   ]
  },
  {
   "id": "scroll-spy-nav",
   "num": "W-101",
   "name": "Scroll Spy Navigation",
   "nameJa": "スクロールスパイ付きナビ",
   "category": "interact",
   "description": "IntersectionObserverで表示中のセクションを検知し、対応するナビリンクにactiveクラスを付け替える。スクロール位置にナビのハイライトが自動追従する。",
   "useCase": "長いLPや資料サイトのサイドナビ・目次で、今どこを読んでいるかを常に示したい場面。",
   "code": "const io = new IntersectionObserver(entries => {\n  entries.forEach(e => {\n    nav.querySelector(`[href=\"#${e.target.id}\"]`)\n      .classList.toggle('active', e.isIntersecting);\n  });\n}, { rootMargin: '-40% 0px -40% 0px' });\nsections.forEach(s => io.observe(s));",
   "tags": [
    "JS",
    "API",
    "スクロール",
    "ナビゲーション",
    "さりげない",
    "便利"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"スクロールスパイ付きナビのデモ\"><style>.ssp-n1{animation:ssp-n1 6s steps(1) infinite}.ssp-n2{animation:ssp-n2 6s steps(1) infinite}.ssp-n3{animation:ssp-n3 6s steps(1) infinite}@keyframes ssp-n1{0%,33%{fill:var(--w-accent,#4fe3c1)}33.1%,100%{fill:var(--w-sub,#94a3c0)}}@keyframes ssp-n2{0%,33%{fill:var(--w-sub,#94a3c0)}33.1%,66%{fill:var(--w-accent,#4fe3c1)}66.1%,100%{fill:var(--w-sub,#94a3c0)}}@keyframes ssp-n3{0%,66%{fill:var(--w-sub,#94a3c0)}66.1%,100%{fill:var(--w-accent,#4fe3c1)}}.ssp-sc{animation:ssp-sc 6s ease-in-out infinite}@keyframes ssp-sc{0%,28%{transform:translateY(0)}38%,61%{transform:translateY(-60px)}71%,97%{transform:translateY(-120px)}100%{transform:translateY(0)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"16\" y=\"20\" width=\"8\" height=\"14\" rx=\"2\" class=\"ssp-n1\"/><rect x=\"16\" y=\"44\" width=\"8\" height=\"14\" rx=\"2\" class=\"ssp-n2\"/><rect x=\"16\" y=\"68\" width=\"8\" height=\"14\" rx=\"2\" class=\"ssp-n3\"/><text x=\"32\" y=\"31\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"9\" fill=\"var(--w-ink,#e8eef9)\">概要</text><text x=\"32\" y=\"55\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"9\" fill=\"var(--w-ink,#e8eef9)\">機能</text><text x=\"32\" y=\"79\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"9\" fill=\"var(--w-ink,#e8eef9)\">料金</text><clipPath id=\"ssp-clip1\"><rect x=\"110\" y=\"15\" width=\"110\" height=\"90\" rx=\"6\"/></clipPath><g clip-path=\"url(#ssp-clip1)\"><rect x=\"110\" y=\"15\" width=\"110\" height=\"90\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".08\"/><g class=\"ssp-sc\"><rect x=\"120\" y=\"20\" width=\"90\" height=\"50\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".4\"/><rect x=\"120\" y=\"80\" width=\"90\" height=\"50\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".4\"/><rect x=\"120\" y=\"140\" width=\"90\" height=\"50\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".4\"/></g></g></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "copy-button",
    "web-share-api",
    "keyboard-shortcuts",
    "sticky-position"
   ]
  },
  {
   "id": "command-palette",
   "num": "W-102",
   "name": "Command Palette",
   "nameJa": "コマンドパレット風検索",
   "category": "interact",
   "description": "Ctrl/Cmd+Kなどのショートカットで画面中央にオーバーレイ検索を呼び出し、入力に合わせてリストをインクリメンタルに絞り込む。",
   "useCase": "ドキュメントサイトやダッシュボードで、メニューを辿らず一発でページ・機能に飛びたいパワーユーザー向け導線。",
   "code": "document.addEventListener('keydown', e => {\n  if ((e.metaKey || e.ctrlKey) && e.key === 'k') {\n    e.preventDefault(); palette.showModal(); input.focus();\n  }\n});\ninput.addEventListener('input', () => filterItems(input.value));",
   "tags": [
    "JS",
    "HTML",
    "検索",
    "ショートカット",
    "パッと切替",
    "高級感",
    "没入感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"コマンドパレット風検索のデモ\"><style>.cmp-panel{animation:cmp-show 4s ease-in-out infinite}@keyframes cmp-show{0%,10%{opacity:0;transform:translateY(-8px)}25%,90%{opacity:1;transform:translateY(0)}100%{opacity:0;transform:translateY(-8px)}}.cmp-i2{animation:cmp-fade 4s ease-in-out infinite}.cmp-i3{animation:cmp-fade 4s ease-in-out infinite .2s}@keyframes cmp-fade{0%,40%{opacity:1}55%,100%{opacity:.15}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"20\" y=\"10\" width=\"200\" height=\"130\" rx=\"6\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".05\"/><g class=\"cmp-panel\"><rect x=\"45\" y=\"30\" width=\"150\" height=\"90\" rx=\"10\" fill=\"var(--w-ink,#e8eef9)\"/><rect x=\"58\" y=\"42\" width=\"124\" height=\"18\" rx=\"4\" fill=\"var(--w-bg,#101830)\" opacity=\".5\"/><text x=\"64\" y=\"55\" font-family=\"ui-monospace,monospace\" font-size=\"9\" fill=\"var(--w-ink,#e8eef9)\">検索...</text><rect class=\"cmp-i2\" x=\"58\" y=\"68\" width=\"124\" height=\"12\" rx=\"3\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".7\"/><rect class=\"cmp-i3\" x=\"58\" y=\"86\" width=\"124\" height=\"12\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/><rect x=\"58\" y=\"104\" width=\"124\" height=\"12\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".3\"/></g></svg>",
   "useFor": [
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "lightbox-gallery",
    "dialog-modal",
    "lightbox-dialog",
    "video-background"
   ]
  },
  {
   "id": "inert-attribute",
   "num": "W-103",
   "name": "inert Attribute",
   "nameJa": "inert属性",
   "category": "interact",
   "description": "要素にinert属性を付けるだけで、配下のクリック・フォーカス・スクリーンリーダー読み上げを丸ごと無効化するHTML標準機能。モーダル表示中の背景操作封じに使う。",
   "useCase": "モーダルやドロワー表示中に背景コンテンツを完全に触れなくしたい場面。アクセシビリティ対応の手数を減らす。",
   "code": "<main inert>...</main>\n<dialog open>モーダル内容</dialog>\n\nmain.toggleAttribute('inert', dialog.open);",
   "tags": [
    "HTML",
    "アクセシビリティ",
    "モーダル",
    "普及中",
    "さりげない",
    "安全"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"inert属性のデモ\"><style>.ine-bg{animation:ine-dim 4s ease-in-out infinite}@keyframes ine-dim{0%,20%{opacity:1}35%,75%{opacity:.3}90%,100%{opacity:1}}.ine-ban{animation:ine-ban 4s ease-in-out infinite}@keyframes ine-ban{0%,20%{opacity:0}35%,75%{opacity:1}90%,100%{opacity:0}}.ine-modal{animation:ine-modal 4s ease-in-out infinite}@keyframes ine-modal{0%,20%{opacity:0}35%,75%{opacity:1}90%,100%{opacity:0}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g class=\"ine-bg\"><rect x=\"15\" y=\"15\" width=\"90\" height=\"12\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\"/><rect x=\"15\" y=\"35\" width=\"120\" height=\"12\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\"/><rect x=\"15\" y=\"55\" width=\"70\" height=\"12\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\"/></g><g class=\"ine-ban\"><circle cx=\"50\" cy=\"35\" r=\"16\" fill=\"none\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"3\"/><line x1=\"39\" y1=\"24\" x2=\"61\" y2=\"46\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"3\"/></g><g class=\"ine-modal\"><rect x=\"100\" y=\"80\" width=\"120\" height=\"55\" rx=\"10\" fill=\"var(--w-ink,#e8eef9)\"/><text x=\"160\" y=\"112\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\">モーダル表示中</text></g></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "details-summary-accordion",
    "customizable-select",
    "dialog-closedby",
    "hover-focus-states"
   ]
  },
  {
   "id": "drag-and-drop",
   "num": "W-104",
   "name": "Drag and Drop",
   "nameJa": "ドラッグ&ドロップ",
   "category": "interact",
   "description": "draggable属性とdragstart/dragover/dropイベントで要素を掴んで別領域へ移動させる。dragoverでpreventDefaultしないとdropが発火しない点に注意。",
   "useCase": "カンバンボードのカード移動、ファイルアップロードの投げ込み領域、並べ替え可能なリスト作成など。",
   "code": "card.addEventListener('dragstart', e => e.dataTransfer.setData('id', card.id));\nzone.addEventListener('dragover', e => e.preventDefault());\nzone.addEventListener('drop', e =>\n  zone.append(document.getElementById(e.dataTransfer.getData('id'))));",
   "tags": [
    "JS",
    "API",
    "ドラッグ",
    "カンバン",
    "ダイナミック",
    "目を引く",
    "直感的"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ドラッグアンドドロップのデモ\"><style>.dad-card{animation:dad-move 4.5s ease-in-out infinite}@keyframes dad-move{0%,15%{transform:translate(0,0)}45%,60%{transform:translate(110px,10px)}100%{transform:translate(0,0)}}.dad-cur{animation:dad-move 4.5s ease-in-out infinite}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"20\" y=\"20\" width=\"90\" height=\"110\" rx=\"8\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-width=\"1\" stroke-dasharray=\"4 3\"/><rect x=\"130\" y=\"20\" width=\"90\" height=\"110\" rx=\"8\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-width=\"1\" stroke-dasharray=\"4 3\"/><g class=\"dad-card\"><rect x=\"32\" y=\"35\" width=\"66\" height=\"30\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\"/></g><g class=\"dad-cur\"><circle cx=\"90\" cy=\"55\" r=\"5\" fill=\"var(--w-ink,#e8eef9)\"/></g></svg>",
   "useFor": [
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "magnetic-button",
    "custom-cursor",
    "text-scramble",
    "horizontal-scroll-section"
   ]
  },
  {
   "id": "keyboard-shortcuts",
   "num": "W-105",
   "name": "Keyboard Shortcuts",
   "nameJa": "キーボードショートカット実装",
   "category": "interact",
   "description": "keydownイベントでkeyやmodifierキーの組み合わせを判定し、g→hのような連続キー入力も内部バッファで追跡してコマンドを実行する仕組み。",
   "useCase": "エディタ・ダッシュボード・スライド操作など、マウスに頼らず高速操作したいパワーユーザー向け機能。",
   "code": "let buffer = '';\ndocument.addEventListener('keydown', e => {\n  if (e.target.tagName === 'INPUT') return;\n  buffer = (buffer + e.key).slice(-2);\n  if (buffer === 'gh') location.hash = '#home';\n});",
   "tags": [
    "JS",
    "キーボード",
    "ショートカット",
    "パワーユーザー",
    "さりげない",
    "便利"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"キーボードショートカット実装のデモ\"><style>.kbs-g{animation:kbs-g 3.5s ease-in-out infinite}.kbs-h{animation:kbs-h 3.5s ease-in-out infinite}.kbs-act{animation:kbs-act 3.5s ease-in-out infinite}@keyframes kbs-g{0%,15%{fill:var(--w-sub,#94a3c0)}25%,45%{fill:var(--w-accent,#4fe3c1)}60%,100%{fill:var(--w-sub,#94a3c0)}}@keyframes kbs-h{0%,45%{fill:var(--w-sub,#94a3c0)}55%,75%{fill:var(--w-accent,#4fe3c1)}90%,100%{fill:var(--w-sub,#94a3c0)}}@keyframes kbs-act{0%,55%{opacity:0}70%,95%{opacity:1}100%{opacity:0}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect class=\"kbs-g\" x=\"60\" y=\"55\" width=\"34\" height=\"34\" rx=\"6\"/><text x=\"77\" y=\"77\" font-family=\"ui-monospace,monospace\" font-size=\"13\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\">g</text><rect class=\"kbs-h\" x=\"110\" y=\"55\" width=\"34\" height=\"34\" rx=\"6\"/><text x=\"127\" y=\"77\" font-family=\"ui-monospace,monospace\" font-size=\"13\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\">h</text><g class=\"kbs-act\"><path d=\"M165 72 h30\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"2\"/><polygon points=\"195,68 205,72 195,76\" fill=\"var(--w-amber,#ffc857)\"/></g><text x=\"120\" y=\"120\" font-family=\"ui-monospace,monospace\" font-size=\"9\" fill=\"var(--w-sub,#94a3c0)\" text-anchor=\"middle\">g → h でホームへ</text></svg>",
   "useFor": [
    "slide",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "scroll-spy-nav",
    "copy-button",
    "web-share-api",
    "command-palette"
   ]
  },
  {
   "id": "perspective-rotate3d",
   "num": "W-106",
   "name": "Perspective & rotate3d",
   "nameJa": "パースペクティブ回転",
   "category": "depth",
   "description": "親要素にperspectiveを設定し、子要素をrotateX/rotateYで傾けて奥行きのある回転を作る3D表現の基本形。transform-style: preserve-3dも併用する。",
   "useCase": "ホバーで傾くバナーや見出しカードなど、あらゆる3D表現の土台として最初に押さえておきたい技。",
   "code": ".p3d-stage{ perspective: 800px; }\n.p3d-card{ transform: rotateY(25deg) rotateX(10deg); transition: transform .4s; }\n.p3d-card:hover{ transform: rotateY(0) rotateX(0); }",
   "tags": [
    "CSS",
    "3D",
    "transform",
    "ホバー",
    "奥行き感",
    "ダイナミック"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"パースペクティブ回転のデモ\">\n  <style>\n    .p3d-card{animation:p3d-spin 4s ease-in-out infinite;transform-origin:120px 75px}\n    @keyframes p3d-spin{0%,100%{transform:scaleX(1)}50%{transform:scaleX(.15)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <line x1=\"20\" y1=\"20\" x2=\"120\" y2=\"75\" stroke=\"var(--w-sub,#94a3c0)\" opacity=\".3\"/>\n  <line x1=\"220\" y1=\"20\" x2=\"120\" y2=\"75\" stroke=\"var(--w-sub,#94a3c0)\" opacity=\".3\"/>\n  <line x1=\"20\" y1=\"130\" x2=\"120\" y2=\"75\" stroke=\"var(--w-sub,#94a3c0)\" opacity=\".3\"/>\n  <line x1=\"220\" y1=\"130\" x2=\"120\" y2=\"75\" stroke=\"var(--w-sub,#94a3c0)\" opacity=\".3\"/>\n  <rect class=\"p3d-card\" x=\"70\" y=\"35\" width=\"100\" height=\"80\" rx=\"8\" fill=\"var(--w-accent,#4fe3c1)\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "card-flip",
    "cube-3d",
    "ring-gallery",
    "scroll-3d-rotate"
   ]
  },
  {
   "id": "card-flip",
   "num": "W-107",
   "name": "Card Flip",
   "nameJa": "カードフリップ",
   "category": "depth",
   "description": "backface-visibility: hiddenで表裏2面を作り、rotateY(180deg)で切り替えてカードがくるっと裏返る定番の3D表現。preserve-3dと併用する。",
   "useCase": "料金プランの詳細開示、FAQのQ→A切り替え、名刺風の自己紹介カードなどに使う。",
   "code": ".cflip-inner{ transform-style: preserve-3d; transition: transform .6s; }\n.cflip:hover .cflip-inner{ transform: rotateY(180deg); }\n.cflip-front, .cflip-back{ backface-visibility: hidden; position: absolute; inset: 0; }\n.cflip-back{ transform: rotateY(180deg); }",
   "tags": [
    "CSS",
    "3D",
    "ホバー",
    "カード",
    "パッと切替",
    "高級感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"カードフリップのデモ\">\n  <style>\n    .cflp-card{animation:cflp-flip 4s ease-in-out infinite;transform-origin:120px 75px}\n    @keyframes cflp-flip{0%,20%{transform:scaleX(1)}30%{transform:scaleX(0)}40%,80%{transform:scaleX(1)}90%{transform:scaleX(0)}100%{transform:scaleX(1)}}\n    .cflp-back{animation:cflp-show 4s step-end infinite}\n    @keyframes cflp-show{0%,29%{opacity:0}30%,89%{opacity:1}90%,100%{opacity:0}}\n    .cflp-frontf{animation:cflp-hide 4s step-end infinite}\n    @keyframes cflp-hide{0%,29%{opacity:1}30%,89%{opacity:0}90%,100%{opacity:1}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"cflp-card\">\n    <rect class=\"cflp-frontf\" x=\"70\" y=\"30\" width=\"100\" height=\"90\" rx=\"10\" fill=\"var(--w-accent,#4fe3c1)\"/>\n    <rect class=\"cflp-back\" x=\"70\" y=\"30\" width=\"100\" height=\"90\" rx=\"10\" fill=\"var(--w-amber,#ffc857)\"/>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "pricing-card-hover-lift",
    "grayscale-hover",
    "perspective-rotate3d",
    "page-turn"
   ]
  },
  {
   "id": "mouse-tilt",
   "num": "W-108",
   "name": "Mouse Tilt",
   "nameJa": "マウス追従チルト",
   "category": "depth",
   "description": "マウス座標から傾き角を計算し、JSでrotateX/rotateYへ反映してカードがカーソルに追従して傾く立体的なインタラクション。",
   "useCase": "商品カードやプロフィールカードにマウスを乗せた瞬間の高級感を出したいときに使う。",
   "code": "el.addEventListener('mousemove', e => {\n  const r = el.getBoundingClientRect();\n  const rx = (e.clientY - r.top - r.height / 2) / 10;\n  const ry = (e.clientX - r.left - r.width / 2) / -10;\n  el.style.transform = `perspective(600px) rotateX(${rx}deg) rotateY(${ry}deg)`;\n});",
   "tags": [
    "JS",
    "3D",
    "マウス追従",
    "ホバー",
    "高級感",
    "ぬるっと",
    "インタラクティブ"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"マウス追従チルトのデモ\">\n  <style>\n    .mtlt-card{animation:mtlt-tilt 4s ease-in-out infinite;transform-origin:120px 75px}\n    @keyframes mtlt-tilt{0%,100%{transform:rotate(-6deg) scale(1)}25%{transform:rotate(4deg) scale(1.02)}50%{transform:rotate(-2deg) scale(1)}75%{transform:rotate(6deg) scale(1.02)}}\n    .mtlt-cursor{animation:mtlt-orbit 4s linear infinite}\n    @keyframes mtlt-orbit{0%{transform:translate(40px,-30px)}25%{transform:translate(40px,30px)}50%{transform:translate(-40px,30px)}75%{transform:translate(-40px,-30px)}100%{transform:translate(40px,-30px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"mtlt-card\" x=\"70\" y=\"35\" width=\"100\" height=\"80\" rx=\"8\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".9\"/>\n  <circle class=\"mtlt-cursor\" cx=\"120\" cy=\"75\" r=\"5\" fill=\"var(--w-amber,#ffc857)\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "page-turn",
    "card-flip",
    "variable-font-weight",
    "web-animations-api"
   ]
  },
  {
   "id": "cube-3d",
   "num": "W-109",
   "name": "3D Cube",
   "nameJa": "3Dキューブ",
   "category": "depth",
   "description": "6面をtransform-style: preserve-3dで箱状に組み立て、translateZで配置しrotateX/Yで回転させる純CSSの立方体表現。",
   "useCase": "サービス紹介のロゴキューブやローディング表示など、回転する立体オブジェクトが欲しいときに使う。",
   "code": ".cube-box{ transform-style: preserve-3d; animation: cube-spin 6s linear infinite; }\n.cube-face{ position: absolute; width: 100px; height: 100px; }\n.cube-front{ transform: translateZ(50px); }\n.cube-back{ transform: rotateY(180deg) translateZ(50px); }\n@keyframes cube-spin{ to{ transform: rotateX(360deg) rotateY(360deg); } }",
   "tags": [
    "CSS",
    "3D",
    "preserve-3d",
    "回転",
    "ダイナミック",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"3Dキューブのデモ\">\n  <style>\n    .cb3-grp{animation:cb3-rot 5s linear infinite;transform-origin:120px 78px}\n    @keyframes cb3-rot{0%{transform:scaleX(1)}50%{transform:scaleX(-1)}100%{transform:scaleX(1)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"cb3-grp\">\n    <polygon points=\"120,30 170,55 120,80 70,55\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".85\"/>\n    <polygon points=\"70,55 120,80 120,130 70,105\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".8\"/>\n    <polygon points=\"170,55 120,80 120,130 170,105\" fill=\"var(--w-amber,#ffc857)\" opacity=\".7\"/>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "ring-gallery",
    "scroll-3d-rotate",
    "carousel-3d",
    "perspective-rotate3d"
   ]
  },
  {
   "id": "carousel-3d",
   "num": "W-110",
   "name": "3D Carousel (Coverflow)",
   "nameJa": "3Dカルーセル",
   "category": "depth",
   "description": "複数カードをrotateYとtranslateZで円弧状に並べ、中央を正面・左右を傾けて奥に配置する3Dカルーセル。indexに応じ角度をJSで再計算する。",
   "useCase": "製品ギャラリーや実績スライダーで、次々にカードをめくる立体的な一覧演出に使う。",
   "code": ".carousel-track{ transform-style: preserve-3d; }\n.carousel-item{ position: absolute; transition: transform .5s; }\n.carousel-item[data-pos=\"0\"]{ transform: translateZ(0) rotateY(0); }\n.carousel-item[data-pos=\"-1\"]{ transform: translateX(-140px) translateZ(-120px) rotateY(35deg); }\n.carousel-item[data-pos=\"1\"]{ transform: translateX(140px) translateZ(-120px) rotateY(-35deg); }",
   "tags": [
    "CSS",
    "JS",
    "3D",
    "スライダー",
    "ギャラリー",
    "ダイナミック",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"3Dカルーセルのデモ\">\n  <style>\n    .crv-a{animation:crv-cyc 4.5s ease-in-out infinite;transform-origin:120px 75px}\n    .crv-b{animation:crv-cyc 4.5s ease-in-out infinite -1.5s;transform-origin:120px 75px}\n    .crv-c{animation:crv-cyc 4.5s ease-in-out infinite -3s;transform-origin:120px 75px}\n    @keyframes crv-cyc{0%{transform:translateX(-70px) scale(.75)}33%{transform:translateX(0) scale(1)}66%{transform:translateX(70px) scale(.75)}100%{transform:translateX(-70px) scale(.75)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"crv-a\" x=\"100\" y=\"35\" width=\"60\" height=\"80\" rx=\"6\" fill=\"var(--w-sub,#94a3c0)\"/>\n  <rect class=\"crv-b\" x=\"100\" y=\"35\" width=\"60\" height=\"80\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <rect class=\"crv-c\" x=\"100\" y=\"35\" width=\"60\" height=\"80\" rx=\"6\" fill=\"var(--w-amber,#ffc857)\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "cube-3d",
    "ring-gallery",
    "horizontal-scroll-section",
    "custom-cursor"
   ]
  },
  {
   "id": "preserve-3d-nesting",
   "num": "W-111",
   "name": "Nested preserve-3d",
   "nameJa": "入れ子の3D空間",
   "category": "depth",
   "description": "transform-style: preserve-3dを親子で入れ子にし、子要素の3D変形を親の3D空間に保ったまま組み合わせる高度な立体構築技法。",
   "useCase": "複数パーツからなる立体オブジェクト（本・箱・複合カード）を階層構造のまま回転させたいときに使う。",
   "code": ".nest-scene{ perspective: 900px; }\n.nest-parent{ transform-style: preserve-3d; transform: rotateY(20deg); }\n.nest-child{ transform-style: preserve-3d; transform: translateZ(40px) rotateX(15deg); }\n/* 子要素にもtransform-styleを明示しないと平面化されるので注意 */",
   "tags": [
    "CSS",
    "3D",
    "preserve-3d",
    "階層構造",
    "精密",
    "没入感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"入れ子の3D空間のデモ\">\n  <style>\n    .p3n-outer{animation:p3n-o 5s ease-in-out infinite;transform-origin:120px 75px}\n    @keyframes p3n-o{0%,100%{transform:rotate(-8deg)}50%{transform:rotate(8deg)}}\n    .p3n-inner{animation:p3n-i 5s ease-in-out infinite;transform-origin:120px 75px}\n    @keyframes p3n-i{0%,100%{transform:rotate(10deg) scale(.6)}50%{transform:rotate(-10deg) scale(.7)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"p3n-outer\" x=\"55\" y=\"30\" width=\"130\" height=\"90\" rx=\"10\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-width=\"3\"/>\n  <rect class=\"p3n-inner\" x=\"90\" y=\"52\" width=\"60\" height=\"46\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "cube-3d",
    "isometric",
    "ring-gallery",
    "perspective-grid-floor"
   ]
  },
  {
   "id": "parallax-layers",
   "num": "W-112",
   "name": "Multi-layer Parallax",
   "nameJa": "多層パララックス",
   "category": "depth",
   "description": "背景から前景まで複数レイヤーにtranslateZとscaleを与え、層ごとに移動量を変えることで視差による奥行きを錯覚させる多層パララックス。",
   "useCase": "ヒーローセクションの背景演出やスクロール連動のストーリーテリングページに使う。",
   "code": ".pxl-scene{ perspective: 1px; height: 100vh; overflow-y: scroll; transform-style: preserve-3d; }\n.pxl-back{ transform: translateZ(-2px) scale(3); }\n.pxl-mid{ transform: translateZ(-1px) scale(2); }\n.pxl-front{ transform: translateZ(0); }",
   "tags": [
    "CSS",
    "スクロール",
    "パララックス",
    "奥行き感",
    "没入感",
    "レイヤー"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"多層パララックスのデモ\">\n  <style>\n    .pxl-far{animation:pxl-mv 5.5s linear infinite}\n    .pxl-mid{animation:pxl-mv 4s linear infinite}\n    .pxl-near{animation:pxl-mv 2.8s linear infinite}\n    @keyframes pxl-mv{0%{transform:translateX(0)}100%{transform:translateX(-40px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"pxl-far\" opacity=\".4\">\n    <circle cx=\"40\" cy=\"40\" r=\"14\" fill=\"var(--w-sub,#94a3c0)\"/>\n    <circle cx=\"140\" cy=\"35\" r=\"10\" fill=\"var(--w-sub,#94a3c0)\"/>\n    <circle cx=\"230\" cy=\"45\" r=\"16\" fill=\"var(--w-sub,#94a3c0)\"/>\n  </g>\n  <g class=\"pxl-mid\" opacity=\".65\">\n    <rect x=\"20\" y=\"80\" width=\"30\" height=\"20\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\"/>\n    <rect x=\"120\" y=\"85\" width=\"30\" height=\"20\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\"/>\n    <rect x=\"210\" y=\"78\" width=\"30\" height=\"20\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  </g>\n  <g class=\"pxl-near\">\n    <rect x=\"10\" y=\"120\" width=\"40\" height=\"16\" rx=\"3\" fill=\"var(--w-amber,#ffc857)\"/>\n    <rect x=\"110\" y=\"120\" width=\"40\" height=\"16\" rx=\"3\" fill=\"var(--w-amber,#ffc857)\"/>\n    <rect x=\"200\" y=\"120\" width=\"40\" height=\"16\" rx=\"3\" fill=\"var(--w-amber,#ffc857)\"/>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "glass-depth",
    "vertical-scroll-snap",
    "scroll-snap",
    "parallax-scroll"
   ]
  },
  {
   "id": "floating-shadow",
   "num": "W-113",
   "name": "Floating Shadow",
   "nameJa": "浮遊影の連動",
   "category": "depth",
   "description": "要素をtranslateYで上下にふわふわ揺らしつつ、真下の影を要素の高さと連動して伸縮させ、宙に浮いている感覚を強調する表現。",
   "useCase": "アイコンやプロダクト画像を宙に浮かせて見せたいヒーロー演出やアイキャッチに使う。",
   "code": ".float-obj{ animation: float-move 3s ease-in-out infinite; }\n.float-shadow{ animation: float-shrink 3s ease-in-out infinite; }\n@keyframes float-move{ 0%, 100%{ transform: translateY(0); } 50%{ transform: translateY(-18px); } }\n@keyframes float-shrink{ 0%, 100%{ transform: scale(1); opacity: .5; } 50%{ transform: scale(.6); opacity: .25; } }",
   "tags": [
    "CSS",
    "アニメーション",
    "浮遊感",
    "ふわっと",
    "影",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"浮遊影の連動のデモ\">\n  <style>\n    .flts-obj{animation:flts-f 3s ease-in-out infinite}\n    @keyframes flts-f{0%,100%{transform:translateY(0)}50%{transform:translateY(-20px)}}\n    .flts-sh{animation:flts-s 3s ease-in-out infinite;transform-origin:120px 125px}\n    @keyframes flts-s{0%,100%{transform:scale(1);opacity:.55}50%{transform:scale(.55);opacity:.25}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <ellipse class=\"flts-sh\" cx=\"120\" cy=\"125\" rx=\"40\" ry=\"9\" fill=\"var(--w-ink,#e8eef9)\"/>\n  <circle class=\"flts-obj\" cx=\"120\" cy=\"65\" r=\"28\" fill=\"var(--w-accent,#4fe3c1)\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "starting-style",
    "animation-composition",
    "view-timeline-reveal",
    "scroll-reveal"
   ]
  },
  {
   "id": "isometric",
   "num": "W-114",
   "name": "Isometric Transform",
   "nameJa": "アイソメトリック変形",
   "category": "depth",
   "description": "rotateXとrotateZの組み合わせで等角投影に近い変形を作り、正面図をそのまま立体的な箱型に見せるアイソメトリック表現。",
   "useCase": "アプリの機能図やプロセス説明図をゲーム風の立体イラストで見せたいセクションに使う。",
   "code": ".iso-scene{ transform: rotateX(55deg) rotateZ(45deg); transform-style: preserve-3d; }\n.iso-block{ transform: translateZ(20px); box-shadow: 0 20px 20px rgba(0,0,0,.3); }\n/* matrix()による2.5D近似でも代用可 */",
   "tags": [
    "CSS",
    "3D",
    "アイソメトリック",
    "レイアウト",
    "精密",
    "落ち着いた"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"アイソメトリック変形のデモ\">\n  <style>\n    .iso-grp{animation:iso-tilt 4s ease-in-out infinite;transform-origin:120px 82px}\n    @keyframes iso-tilt{0%,100%{transform:scaleY(.35)}50%{transform:scaleY(1)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"iso-grp\">\n    <polygon points=\"120,30 175,60 120,90 65,60\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".9\"/>\n    <polygon points=\"65,60 120,90 120,135 65,105\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\"/>\n    <polygon points=\"175,60 120,90 120,135 175,105\" fill=\"var(--w-amber,#ffc857)\" opacity=\".75\"/>\n    <polyline points=\"120,30 175,60 120,90 65,60 120,30\" fill=\"none\" stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"1.5\"/>\n  </g>\n</svg>",
   "useFor": [
    "slide",
    "lp"
   ],
   "weight": "主役",
   "relatedIds": [
    "preserve-3d-nesting",
    "text-orientation-upright",
    "vertical-embed-override",
    "logical-properties-vertical"
   ]
  },
  {
   "id": "page-turn",
   "num": "W-115",
   "name": "Page Turn",
   "nameJa": "ページめくり",
   "category": "depth",
   "description": "要素を左右2分割しrotateY(-160deg)前後で右端を軸にめくり、裏面にグラデーション影を重ねて本のページのような質感を出す。",
   "useCase": "電子カタログや長文コンテンツのページ送り、写真集風ギャラリーの演出に使う。",
   "code": ".page-leaf{ transform-origin: left center; transform-style: preserve-3d; transition: transform .8s ease; }\n.page-leaf.turning{ transform: rotateY(-160deg); }\n.page-leaf::after{ content: \"\"; position: absolute; inset: 0; background: linear-gradient(90deg, transparent, rgba(0,0,0,.25)); opacity: 0; }\n.page-leaf.turning::after{ opacity: 1; }",
   "tags": [
    "CSS",
    "JS",
    "3D",
    "ページ送り",
    "高級感",
    "ぬるっと"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ページめくりのデモ\">\n  <style>\n    .pgtn-leaf{animation:pgtn-turn 4s ease-in-out infinite;transform-origin:70px 75px}\n    @keyframes pgtn-turn{0%,20%{transform:scaleX(1)}55%{transform:scaleX(.05)}90%,100%{transform:scaleX(1)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"20\" y=\"25\" width=\"100\" height=\"100\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/>\n  <rect class=\"pgtn-leaf\" x=\"70\" y=\"25\" width=\"100\" height=\"100\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\"/>\n</svg>",
   "useFor": [
    "slide",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "mouse-tilt",
    "card-flip",
    "carousel-3d",
    "variable-font-weight"
   ]
  },
  {
   "id": "text-extrude",
   "num": "W-116",
   "name": "3D Text Extrude",
   "nameJa": "文字の押し出し",
   "category": "depth",
   "description": "同じ文字にtext-shadowで色と濃度を変えた層を斜め方向へ重ね、厚みのある立体文字を作る押し出し表現。層数が多いほど厚みが増す。",
   "useCase": "インパクトが欲しい見出しやロゴタイプ、レトロ・ゲーム風のタイトル演出に使う。",
   "code": ".text-3d{ color: #fff; text-shadow:\n  1px 1px 0 #0008, 2px 2px 0 #0008, 3px 3px 0 #0008,\n  4px 4px 0 #0008, 5px 5px 6px rgba(0,0,0,.4);\n}\n/* 層を増やすほど厚みが増す。JS/Sassでループ生成すると保守しやすい */",
   "tags": [
    "CSS",
    "タイポグラフィ",
    "立体文字",
    "高級感",
    "レトロ",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"文字の押し出しのデモ\">\n  <style>\n    .txex-shadow{animation:txex-d 3.5s ease-in-out infinite}\n    @keyframes txex-d{0%,100%{transform:translate(1px,1px)}50%{transform:translate(6px,6px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g transform=\"translate(20,85) scale(2.4)\">\n    <text class=\"txex-shadow\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"14\" font-weight=\"700\" fill=\"var(--w-sub,#94a3c0)\">DEPTH</text>\n    <text font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"14\" font-weight=\"700\" fill=\"var(--w-accent,#4fe3c1)\">DEPTH</text>\n  </g>\n</svg>",
   "useFor": [
    "slide",
    "lp"
   ],
   "weight": "主役",
   "relatedIds": [
    "outline-text-bg",
    "text-image-mask",
    "gradient-text",
    "marker-highlight"
   ]
  },
  {
   "id": "ring-gallery",
   "num": "W-117",
   "name": "Ring Gallery",
   "nameJa": "リング状回転ギャラリー",
   "category": "depth",
   "description": "複数要素をrotateY(360deg/n×i)とtranslateZで円周上に等間隔配置し、親をrotateYで回転させ画像がリング状に周回する演出。",
   "useCase": "実績ロゴやメンバー紹介をぐるぐる回る立体ギャラリーとして見せたいセクションに使う。",
   "code": ".ring-stage{ transform-style: preserve-3d; animation: ring-spin 10s linear infinite; }\n.ring-item{\n  position: absolute;\n  transform: rotateY(calc(360deg / var(--n) * var(--i))) translateZ(140px);\n}\n@keyframes ring-spin{ to{ transform: rotateY(360deg); } }",
   "tags": [
    "CSS",
    "3D",
    "回転",
    "ギャラリー",
    "ダイナミック",
    "没入感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"リング状回転ギャラリーのデモ\">\n  <style>\n    .rg-dot{transform-box:fill-box;transform-origin:center;animation:rg-pulse 4.5s ease-in-out infinite}\n    @keyframes rg-pulse{0%,100%{transform:scale(1);opacity:1}25%{transform:scale(.55);opacity:.4}50%{transform:scale(.4);opacity:.25}75%{transform:scale(.55);opacity:.4}}\n    .rg-d1{animation-delay:-.75s}\n    .rg-d2{animation-delay:-1.5s}\n    .rg-d3{animation-delay:-2.25s}\n    .rg-d4{animation-delay:-3s}\n    .rg-d5{animation-delay:-3.75s}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <ellipse cx=\"120\" cy=\"75\" rx=\"90\" ry=\"30\" fill=\"none\" stroke=\"var(--w-sub,#94a3c2)\" stroke-width=\"1\" opacity=\".3\"/>\n  <circle class=\"rg-dot\" cx=\"210\" cy=\"75\" r=\"10\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <circle class=\"rg-dot rg-d1\" cx=\"165\" cy=\"101\" r=\"9\" fill=\"var(--w-amber,#ffc857)\"/>\n  <circle class=\"rg-dot rg-d2\" cx=\"75\" cy=\"101\" r=\"8\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <circle class=\"rg-dot rg-d3\" cx=\"30\" cy=\"75\" r=\"7\" fill=\"var(--w-amber,#ffc857)\"/>\n  <circle class=\"rg-dot rg-d4\" cx=\"75\" cy=\"49\" r=\"8\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <circle class=\"rg-dot rg-d5\" cx=\"165\" cy=\"49\" r=\"9\" fill=\"var(--w-amber,#ffc857)\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "cube-3d",
    "scroll-3d-rotate",
    "perspective-grid-floor",
    "carousel-3d"
   ]
  },
  {
   "id": "glass-depth",
   "num": "W-118",
   "name": "Layered Glass Depth",
   "nameJa": "ガラスの奥行き",
   "category": "depth",
   "description": "backdrop-filter: blurと半透明背景を持つ層を複数重ね、層ごとに濃度とぼかし量を変えて奥に向かうガラスの厚みを表現する。",
   "useCase": "モーダルやカード背景にすりガラスの重なりを出し、奥行きのある高級感を演出したいときに使う。",
   "code": ".glass-l1{ backdrop-filter: blur(4px); background: rgba(255,255,255,.08); }\n.glass-l2{ backdrop-filter: blur(10px); background: rgba(255,255,255,.05); transform: translateZ(-20px) scale(1.05); }\n.glass-l3{ backdrop-filter: blur(18px); background: rgba(255,255,255,.03); transform: translateZ(-40px) scale(1.1); }",
   "tags": [
    "CSS",
    "すりガラス",
    "奥行き感",
    "高級感",
    "レイヤー",
    "落ち着いた"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ガラスの奥行きのデモ\">\n  <style>\n    .gld-l{animation:gld-f 5s ease-in-out infinite}\n    @keyframes gld-f{0%,100%{transform:translateY(0)}50%{transform:translateY(-6px)}}\n    .gld-l2{animation-delay:-1.5s}\n    .gld-l3{animation-delay:-3s}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"gld-l gld-l3\" x=\"40\" y=\"55\" width=\"160\" height=\"70\" rx=\"14\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".08\"/>\n  <rect class=\"gld-l gld-l2\" x=\"55\" y=\"42\" width=\"150\" height=\"70\" rx=\"14\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".14\"/>\n  <rect class=\"gld-l\" x=\"70\" y=\"30\" width=\"140\" height=\"70\" rx=\"14\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".22\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "parallax-layers",
    "glassmorphism",
    "perspective-rotate3d",
    "card-flip"
   ]
  },
  {
   "id": "hover-lift-card",
   "num": "W-119",
   "name": "Hover Lift Card",
   "nameJa": "浮き上がるカード",
   "category": "depth",
   "description": "ホバー時にtranslateYで要素を持ち上げつつbox-shadowを大きく拡散させ、影の距離感で浮き上がったように見せるシンプルな立体演出。",
   "useCase": "料金表カードや記事一覧のサムネイルに、触れた瞬間の反応として使う定番テク。",
   "code": ".lift-card{ transition: transform .25s ease, box-shadow .25s ease; }\n.lift-card:hover{\n  transform: translateY(-10px);\n  box-shadow: 0 20px 30px rgba(0,0,0,.35);\n}",
   "tags": [
    "CSS",
    "ホバー",
    "カード",
    "浮遊感",
    "さりげない",
    "定番"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"浮き上がるカードのデモ\">\n  <style>\n    .hlc-card{animation:hlc-up 3s ease-in-out infinite}\n    @keyframes hlc-up{0%,100%{transform:translateY(0)}50%{transform:translateY(-14px)}}\n    .hlc-sh{animation:hlc-shr 3s ease-in-out infinite;transform-origin:120px 128px}\n    @keyframes hlc-shr{0%,100%{transform:scaleX(1);opacity:.5}50%{transform:scaleX(.7);opacity:.25}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <ellipse class=\"hlc-sh\" cx=\"120\" cy=\"128\" rx=\"50\" ry=\"8\" fill=\"var(--w-ink,#e8eef9)\"/>\n  <rect class=\"hlc-card\" x=\"70\" y=\"35\" width=\"100\" height=\"80\" rx=\"10\" fill=\"var(--w-accent,#4fe3c1)\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "pricing-card-hover-lift",
    "card-flip",
    "hover-pause",
    "hover-focus-states"
   ]
  },
  {
   "id": "scroll-3d-rotate",
   "num": "W-120",
   "name": "Scroll-driven 3D Rotate",
   "nameJa": "スクロール連動3D回転",
   "category": "depth",
   "description": "animation-timeline: scroll()やIntersectionObserverでスクロール量を角度に変換し、要素をrotateX/Yで連続的に回転させる表現。",
   "useCase": "製品紹介ページでスクロールに合わせてオブジェクトが立体的に回転していく演出に使う。",
   "code": ".scroll3d-obj{\n  animation: scroll3d-turn linear;\n  animation-timeline: scroll();\n}\n@keyframes scroll3d-turn{ from{ transform: rotateY(0); } to{ transform: rotateY(360deg); } }",
   "tags": [
    "CSS",
    "スクロール",
    "3D",
    "回転",
    "ダイナミック",
    "限定対応"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"スクロール連動3D回転のデモ\">\n  <style>\n    .sc3d-bar{animation:sc3d-fill 5s linear infinite}\n    @keyframes sc3d-fill{0%{width:0}100%{width:200px}}\n    .sc3d-obj{animation:sc3d-rot 5s linear infinite;transform-origin:120px 55px}\n    @keyframes sc3d-rot{0%{transform:scaleX(1)}50%{transform:scaleX(-1)}100%{transform:scaleX(1)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"sc3d-obj\" x=\"90\" y=\"25\" width=\"60\" height=\"60\" rx=\"8\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <rect x=\"20\" y=\"120\" width=\"200\" height=\"6\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".3\"/>\n  <rect class=\"sc3d-bar\" x=\"20\" y=\"120\" height=\"6\" rx=\"3\" fill=\"var(--w-amber,#ffc857)\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "cube-3d",
    "ring-gallery",
    "perspective-rotate3d",
    "perspective-grid-floor"
   ]
  },
  {
   "id": "perspective-grid-floor",
   "num": "W-121",
   "name": "Perspective Grid Floor",
   "nameJa": "パースグリッド床",
   "category": "depth",
   "description": "巨大なグリッド背景をrotateX(70〜80deg)前後で寝かせ、perspectiveで奥へ収束させることでシンセウェーブ風の無限グリッド床を作る。",
   "useCase": "SF・レトロフューチャー系のヒーロー背景やイベントLPの世界観演出に使う。",
   "code": ".grid-floor{ perspective: 400px; overflow: hidden; }\n.grid-plane{\n  background:\n    linear-gradient(#4fe3c1 1px, transparent 1px) 0 0/40px 40px,\n    linear-gradient(90deg, #4fe3c1 1px, transparent 1px) 0 0/40px 40px;\n  transform: rotateX(75deg);\n  animation: grid-scroll 2s linear infinite;\n}\n@keyframes grid-scroll{ to{ background-position: 0 40px; } }",
   "tags": [
    "CSS",
    "3D",
    "グリッド",
    "レトロ",
    "没入感",
    "ダイナミック"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"パースグリッド床のデモ\">\n  <style>\n    .pgf-h{animation:pgf-mv 3s linear infinite}\n    @keyframes pgf-mv{0%{transform:translateY(0)}100%{transform:translateY(20px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <line x1=\"120\" y1=\"30\" x2=\"10\" y2=\"140\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"1.5\" opacity=\".6\"/>\n  <line x1=\"120\" y1=\"30\" x2=\"70\" y2=\"140\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"1.5\" opacity=\".6\"/>\n  <line x1=\"120\" y1=\"30\" x2=\"120\" y2=\"140\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"1.5\" opacity=\".6\"/>\n  <line x1=\"120\" y1=\"30\" x2=\"170\" y2=\"140\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"1.5\" opacity=\".6\"/>\n  <line x1=\"120\" y1=\"30\" x2=\"230\" y2=\"140\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"1.5\" opacity=\".6\"/>\n  <g class=\"pgf-h\">\n    <line x1=\"30\" y1=\"70\" x2=\"210\" y2=\"70\" stroke=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/>\n    <line x1=\"15\" y1=\"100\" x2=\"225\" y2=\"100\" stroke=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/>\n    <line x1=\"0\" y1=\"130\" x2=\"240\" y2=\"130\" stroke=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/>\n  </g>\n</svg>",
   "useFor": [
    "lp"
   ],
   "weight": "主役",
   "relatedIds": [
    "ring-gallery",
    "perspective-rotate3d",
    "cube-3d",
    "preserve-3d-nesting"
   ]
  },
  {
   "id": "tilt-shift",
   "num": "W-122",
   "name": "Tilt-Shift Blur",
   "nameJa": "チルトシフト風ぼかし",
   "category": "depth",
   "description": "画面の上下をbackdrop-filter: blurで強くぼかし、中央だけをシャープに残すことでミニチュアジオラマのような被写界深度の浅さを演出する。",
   "useCase": "実写写真や俯瞰イラストを「ジオラマ風」に見せて可愛らしさや特別感を出したいときに使う。",
   "code": ".tshift-wrap{ position: relative; }\n.tshift-wrap::before, .tshift-wrap::after{\n  content: \"\"; position: absolute; left: 0; right: 0; height: 35%;\n  backdrop-filter: blur(6px);\n}\n.tshift-wrap::before{ top: 0; }\n.tshift-wrap::after{ bottom: 0; }",
   "tags": [
    "CSS",
    "ぼかし",
    "ミニチュア風",
    "被写界深度",
    "さりげない",
    "演出"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"チルトシフト風ぼかしのデモ\">\n  <defs>\n    <filter id=\"tsft-blur\" x=\"-30%\" y=\"-30%\" width=\"160%\" height=\"160%\">\n      <feGaussianBlur stdDeviation=\"1.2\">\n        <animate attributeName=\"stdDeviation\" values=\"1.2;3.6;1.2\" dur=\"4s\" repeatCount=\"indefinite\"/>\n      </feGaussianBlur>\n    </filter>\n  </defs>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g filter=\"url(#tsft-blur)\">\n    <rect x=\"15\" y=\"20\" width=\"60\" height=\"18\" rx=\"3\" fill=\"var(--w-sub,#94a3c2)\" opacity=\".6\"/>\n    <rect x=\"90\" y=\"15\" width=\"60\" height=\"24\" rx=\"3\" fill=\"var(--w-sub,#94a3c2)\" opacity=\".6\"/>\n    <rect x=\"165\" y=\"22\" width=\"60\" height=\"16\" rx=\"3\" fill=\"var(--w-sub,#94a3c2)\" opacity=\".6\"/>\n  </g>\n  <rect x=\"15\" y=\"60\" width=\"70\" height=\"30\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <rect x=\"100\" y=\"55\" width=\"70\" height=\"35\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <rect x=\"180\" y=\"62\" width=\"45\" height=\"28\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <g filter=\"url(#tsft-blur)\">\n    <rect x=\"15\" y=\"110\" width=\"60\" height=\"22\" rx=\"3\" fill=\"var(--w-sub,#94a3c2)\" opacity=\".6\"/>\n    <rect x=\"90\" y=\"105\" width=\"60\" height=\"28\" rx=\"3\" fill=\"var(--w-sub,#94a3c2)\" opacity=\".6\"/>\n    <rect x=\"165\" y=\"112\" width=\"60\" height=\"20\" rx=\"3\" fill=\"var(--w-sub,#94a3c2)\" opacity=\".6\"/>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "mask-gradient-fade",
    "hover-lift-card",
    "text-emphasis-dots",
    "vertical-writing"
   ]
  },
  {
   "id": "gradient-animation",
   "num": "W-123",
   "name": "Animated Gradient",
   "nameJa": "動くグラデーション",
   "category": "background",
   "description": "background-sizeを200%以上に拡大したグラデーションをbackground-positionでずらし続け、色が滑らかに流れる背景を作る。@keyframesでpositionを往復させるだけで実装できる。",
   "useCase": "LPのヒーローセクションやCTAボタン背景で、単色より動きと高級感を出したいときに使う。",
   "code": ".grad-anim {\n  background: linear-gradient(120deg, #4f46e5, #06b6d4, #4f46e5);\n  background-size: 300% 300%;\n  animation: gradMove 8s ease infinite;\n}\n@keyframes gradMove {\n  0% { background-position: 0% 50%; }\n  50% { background-position: 100% 50%; }\n  100% { background-position: 0% 50%; }\n}",
   "tags": [
    "CSS",
    "グラデーション",
    "背景",
    "ふわっと",
    "高級感",
    "ヒーロー",
    "アニメーション"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"動くグラデーションのデモ\">\n  <defs>\n    <linearGradient id=\"gani-g\" gradientUnits=\"userSpaceOnUse\" x1=\"0\" y1=\"0\" x2=\"240\" y2=\"0\">\n      <stop offset=\"0%\" stop-color=\"var(--w-accent,#4fe3c1)\"/>\n      <stop offset=\"50%\" stop-color=\"var(--w-amber,#ffc857)\"/>\n      <stop offset=\"100%\" stop-color=\"var(--w-accent,#4fe3c1)\"/>\n      <animateTransform attributeName=\"gradientTransform\" type=\"translate\" values=\"-240 0;240 0;-240 0\" dur=\"5s\" repeatCount=\"indefinite\"/>\n    </linearGradient>\n  </defs>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"12\" y=\"12\" width=\"216\" height=\"126\" rx=\"8\" fill=\"url(#gani-g)\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "mesh-gradient",
    "aurora-background",
    "outline-text-bg",
    "scrim-overlay"
   ]
  },
  {
   "id": "aurora-background",
   "num": "W-124",
   "name": "Aurora Background",
   "nameJa": "オーロラ背景",
   "category": "background",
   "description": "複数のradial-gradientを重ねてfilter: blur()で滲ませ、ゆるやかに位置を動かして光の帯が揺らめくオーロラのような背景を作る。",
   "useCase": "プレミアム感を出したいLPのヒーローやアプリのログイン画面の背景に使う。",
   "code": ".aurora { position: relative; background: #101830; overflow: hidden; }\n.aurora::before {\n  content: \"\";\n  position: absolute; inset: -20%;\n  background:\n    radial-gradient(40% 30% at 30% 30%, #4fe3c1aa, transparent 70%),\n    radial-gradient(35% 25% at 70% 60%, #ffc857aa, transparent 70%);\n  filter: blur(40px);\n  animation: auroraDrift 12s ease-in-out infinite alternate;\n}\n@keyframes auroraDrift {\n  from { transform: translate(-5%, -5%) rotate(0deg); }\n  to   { transform: translate(5%, 5%) rotate(6deg); }\n}",
   "tags": [
    "CSS",
    "radial-gradient",
    "blur",
    "背景",
    "幻想的",
    "高級感",
    "没入感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"オーロラ背景のデモ\">\n  <defs>\n    <radialGradient id=\"aurb-g1\" cx=\"30%\" cy=\"30%\" r=\"60%\">\n      <stop offset=\"0%\" stop-color=\"var(--w-accent,#4fe3c1)\" stop-opacity=\".8\"/>\n      <stop offset=\"100%\" stop-color=\"var(--w-accent,#4fe3c1)\" stop-opacity=\"0\"/>\n    </radialGradient>\n    <radialGradient id=\"aurb-g2\" cx=\"70%\" cy=\"65%\" r=\"55%\">\n      <stop offset=\"0%\" stop-color=\"var(--w-amber,#ffc857)\" stop-opacity=\".75\"/>\n      <stop offset=\"100%\" stop-color=\"var(--w-amber,#ffc857)\" stop-opacity=\"0\"/>\n    </radialGradient>\n  </defs>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <ellipse cx=\"70\" cy=\"60\" rx=\"90\" ry=\"60\" fill=\"url(#aurb-g1)\">\n    <animate attributeName=\"cx\" values=\"70;140;70\" dur=\"6s\" repeatCount=\"indefinite\"/>\n  </ellipse>\n  <ellipse cx=\"160\" cy=\"95\" rx=\"90\" ry=\"60\" fill=\"url(#aurb-g2)\">\n    <animate attributeName=\"cy\" values=\"95;55;95\" dur=\"7s\" repeatCount=\"indefinite\"/>\n  </ellipse>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "lava-blob",
    "starfield",
    "gradient-animation",
    "mesh-gradient"
   ]
  },
  {
   "id": "mesh-gradient",
   "num": "W-125",
   "name": "Mesh Gradient",
   "nameJa": "メッシュグラデーション",
   "category": "background",
   "description": "複数の色をぼかした点として異なる位置に配置したradial-gradientを重ね、面同士を滑らかに混ぜる多色グラデーション背景。単純な2色グラデより奥行きが出る。",
   "useCase": "SaaSのトップページやカード背景で、単調にならない彩り豊かな余白を作りたいときに使う。",
   "code": ".mesh {\n  background:\n    radial-gradient(at 20% 20%, #4fe3c1 0px, transparent 50%),\n    radial-gradient(at 80% 10%, #ffc857 0px, transparent 50%),\n    radial-gradient(at 60% 80%, #6366f1 0px, transparent 50%),\n    radial-gradient(at 10% 90%, #ec4899 0px, transparent 50%),\n    #101830;\n}",
   "tags": [
    "CSS",
    "グラデーション",
    "背景",
    "多色",
    "高級感",
    "目を引く",
    "おしゃれ"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"メッシュグラデーションのデモ\">\n  <defs>\n    <radialGradient id=\"mshg-a\" cx=\"20%\" cy=\"25%\" r=\"55%\"><stop offset=\"0%\" stop-color=\"var(--w-accent,#4fe3c1)\" stop-opacity=\".85\"/><stop offset=\"100%\" stop-color=\"var(--w-accent,#4fe3c1)\" stop-opacity=\"0\"/></radialGradient>\n    <radialGradient id=\"mshg-b\" cx=\"80%\" cy=\"20%\" r=\"55%\"><stop offset=\"0%\" stop-color=\"var(--w-amber,#ffc857)\" stop-opacity=\".85\"/><stop offset=\"100%\" stop-color=\"var(--w-amber,#ffc857)\" stop-opacity=\"0\"/></radialGradient>\n    <radialGradient id=\"mshg-c\" cx=\"55%\" cy=\"85%\" r=\"55%\"><stop offset=\"0%\" stop-color=\"var(--w-sub,#94a3c0)\" stop-opacity=\".8\"/><stop offset=\"100%\" stop-color=\"var(--w-sub,#94a3c0)\" stop-opacity=\"0\"/></radialGradient>\n  </defs>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"url(#mshg-a)\"><animate attributeName=\"opacity\" values=\".7;1;.7\" dur=\"4s\" repeatCount=\"indefinite\"/></rect>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"url(#mshg-b)\"><animate attributeName=\"opacity\" values=\"1;.6;1\" dur=\"5s\" repeatCount=\"indefinite\"/></rect>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"url(#mshg-c)\"><animate attributeName=\"opacity\" values=\".6;1;.6\" dur=\"6s\" repeatCount=\"indefinite\"/></rect>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "gradient-animation",
    "outline-text-bg",
    "gradient-text",
    "gradient-border"
   ]
  },
  {
   "id": "grain-noise",
   "num": "W-126",
   "name": "Grain / Noise Texture",
   "nameJa": "ノイズ・グレイン",
   "category": "background",
   "description": "SVGのfeTurbulenceとfeColorMatrixで生成したざらつきをoverlayとして敷き、単調な面にフィルム調の質感を足す。data URI不使用でインラインSVGフィルタとして実装できる。",
   "useCase": "写真感のあるヒーロー背景や暗色LPで、のっぺり感を消して高級感を出したいときに使う。",
   "code": "<svg style=\"position:absolute;inset:0;width:100%;height:100%\">\n  <filter id=\"grain\">\n    <feTurbulence type=\"fractalNoise\" baseFrequency=\"0.8\" numOctaves=\"2\" result=\"n\"/>\n    <feColorMatrix in=\"n\" type=\"matrix\"\n      values=\"0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.05 0\"/>\n  </filter>\n  <rect width=\"100%\" height=\"100%\" filter=\"url(#grain)\"/>\n</svg>",
   "tags": [
    "SVG",
    "フィルター",
    "質感",
    "背景",
    "ざらっと",
    "フィルム調",
    "高級感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ノイズ・グレインのデモ\">\n  <filter id=\"grn-f\" x=\"0\" y=\"0\" width=\"100%\" height=\"100%\">\n    <feTurbulence type=\"fractalNoise\" baseFrequency=\"0.9\" numOctaves=\"2\" seed=\"2\" result=\"n\">\n      <animate attributeName=\"seed\" values=\"1;8;3;1\" dur=\"1s\" repeatCount=\"indefinite\"/>\n    </feTurbulence>\n    <feColorMatrix in=\"n\" type=\"matrix\" values=\"0 0 0 0 0.9  0 0 0 0 0.93  0 0 0 0 0.97  0 0 0 0.4 0\"/>\n  </filter>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".15\"/>\n  <rect width=\"240\" height=\"150\" rx=\"10\" filter=\"url(#grn-f)\" opacity=\".5\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "fe-diffuselighting-emboss",
    "sketchy-outline-filter",
    "gradient-animate",
    "drop-shadow-filter"
   ]
  },
  {
   "id": "dot-grid-pattern",
   "num": "W-127",
   "name": "Dot / Grid Pattern",
   "nameJa": "ドット・グリッドパターン",
   "category": "background",
   "description": "radial-gradientやlinear-gradientをbackground-sizeで繰り返し、等間隔のドットや格子線を敷き詰めて設計図のような整然とした背景を作る。",
   "useCase": "SaaS管理画面やテック系LPの背景で、余白に情報感・秩序感を持たせたいときに使う。",
   "code": ".dot-grid {\n  background-color: #101830;\n  background-image: radial-gradient(#4fe3c1 1px, transparent 1px);\n  background-size: 20px 20px;\n}",
   "tags": [
    "CSS",
    "パターン",
    "背景",
    "グリッド",
    "整然",
    "テック感",
    "さりげない"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ドット・グリッドパターンのデモ\">\n  <defs>\n    <pattern id=\"dgp-p\" width=\"20\" height=\"20\" patternUnits=\"userSpaceOnUse\">\n      <circle cx=\"2\" cy=\"2\" r=\"1.6\" fill=\"var(--w-accent,#4fe3c1)\"/>\n      <animateTransform attributeName=\"patternTransform\" type=\"translate\" values=\"0 0;20 20;0 0\" dur=\"5s\" repeatCount=\"indefinite\"/>\n    </pattern>\n  </defs>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"url(#dgp-p)\" opacity=\".8\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "outline-text-bg",
    "scrim-overlay",
    "text-emphasis-dots",
    "gradient-animation"
   ]
  },
  {
   "id": "flowing-stripes",
   "num": "W-128",
   "name": "Flowing Stripes",
   "nameJa": "流れるストライプ",
   "category": "background",
   "description": "repeating-linear-gradientで斜めの縞模様を作り、background-positionをアニメーションさせて縞が流れ続けるように見せる背景演出。",
   "useCase": "セール告知バナーやCTA周りの背景で、勢いやスピード感を演出したいときに使う。",
   "code": ".stripes {\n  background: repeating-linear-gradient(\n    45deg,\n    #4fe3c1 0 10px,\n    #101830 10px 20px\n  );\n  background-size: 200% 200%;\n  animation: stripeFlow 3s linear infinite;\n}\n@keyframes stripeFlow {\n  from { background-position: 0 0; }\n  to   { background-position: 40px 40px; }\n}",
   "tags": [
    "CSS",
    "ストライプ",
    "背景",
    "動的",
    "スピード感",
    "ダイナミック",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"流れるストライプのデモ\">\n  <defs>\n    <pattern id=\"fst-p\" width=\"16\" height=\"16\" patternUnits=\"userSpaceOnUse\" patternTransform=\"rotate(45)\">\n      <rect width=\"16\" height=\"16\" fill=\"var(--w-bg,#101830)\"/>\n      <rect width=\"8\" height=\"16\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".75\"/>\n      <animate attributeName=\"x\" values=\"0;16;0\" dur=\"2.5s\" repeatCount=\"indefinite\"/>\n    </pattern>\n  </defs>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"url(#fst-p)\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "mesh-gradient",
    "cursor-spotlight",
    "outline-text-bg",
    "crt-scanlines"
   ]
  },
  {
   "id": "lava-blob",
   "num": "W-129",
   "name": "Lava Lamp Blob",
   "nameJa": "ラバランプ風ブロブ",
   "category": "background",
   "description": "filter: blur()をかけた複数の円をゆっくり移動・変形させ、mix-blend-modeで融合させることでラバランプのような有機的な滲みの背景を作る。",
   "useCase": "クリエイティブ系ポートフォリオやブランドLPのヒーロー背景で、柔らかく有機的な雰囲気を出したいときに使う。",
   "code": ".lava { position:relative; overflow:hidden; background:#101830; filter: blur(30px) contrast(20); }\n.lava span {\n  position:absolute; width:120px; height:120px; border-radius:50%;\n  background:#4fe3c1; mix-blend-mode:screen;\n  animation: lavaMove 8s ease-in-out infinite alternate;\n}\n@keyframes lavaMove {\n  from { transform: translate(0,0) scale(1); }\n  to   { transform: translate(60px,-40px) scale(1.4); }\n}",
   "tags": [
    "CSS",
    "blur",
    "ブロブ",
    "背景",
    "有機的",
    "ぬるっと",
    "没入感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ラバランプ風ブロブのデモ\">\n  <filter id=\"lvb-f\"><feGaussianBlur stdDeviation=\"6\"/></filter>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g filter=\"url(#lvb-f)\">\n    <circle r=\"30\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\">\n      <animate attributeName=\"cx\" values=\"70;150;90;70\" dur=\"6s\" repeatCount=\"indefinite\"/>\n      <animate attributeName=\"cy\" values=\"50;90;110;50\" dur=\"6s\" repeatCount=\"indefinite\"/>\n    </circle>\n    <circle r=\"24\" fill=\"var(--w-amber,#ffc857)\" opacity=\".8\">\n      <animate attributeName=\"cx\" values=\"160;90;140;160\" dur=\"7s\" repeatCount=\"indefinite\"/>\n      <animate attributeName=\"cy\" values=\"100;60;40;100\" dur=\"7s\" repeatCount=\"indefinite\"/>\n    </circle>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "aurora-background",
    "starfield",
    "cursor-spotlight",
    "ken-burns"
   ]
  },
  {
   "id": "particle-background",
   "num": "W-130",
   "name": "Particle Background",
   "nameJa": "パーティクル背景",
   "category": "background",
   "description": "canvasに小さな点を大量に配置し、requestAnimationFrameで座標を更新して漂わせたり線で結んだりする軽量なアニメーション背景。",
   "useCase": "テック系プロダクトサイトやイベントLPのヒーローで、先進的で動きのある印象を出したいときに使う。",
   "code": "const c = document.querySelector('canvas'), ctx = c.getContext('2d');\nconst pts = Array.from({length:60}, () => ({\n  x: Math.random()*c.width, y: Math.random()*c.height,\n  vx: (Math.random()-.5)*.5, vy: (Math.random()-.5)*.5 }));\n(function tick(){\n  ctx.clearRect(0,0,c.width,c.height); ctx.fillStyle = '#4fe3c1';\n  for (const p of pts){\n    p.x += p.vx; p.y += p.vy;\n    ctx.beginPath(); ctx.arc(p.x, p.y, 1.5, 0, Math.PI*2); ctx.fill();\n  }\n  requestAnimationFrame(tick);\n})();",
   "tags": [
    "Canvas",
    "JavaScript",
    "背景",
    "パーティクル",
    "先進的",
    "漂う",
    "没入感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"パーティクル背景のデモ\">\n  <style>.ptc-a,.ptc-c,.ptc-e{animation:ptc-up 6s ease-in-out infinite}.ptc-b,.ptc-d,.ptc-f{animation:ptc-down 7s ease-in-out infinite}@keyframes ptc-up{0%,100%{transform:translate(-3px,5px)}50%{transform:translate(5px,-6px)}}@keyframes ptc-down{0%,100%{transform:translate(4px,-4px)}50%{transform:translate(-5px,6px)}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"1\" opacity=\".22\"><path d=\"M42 48L92 72l48-31 57 42\"/><path d=\"M55 101l37-29 62 31 43-20\"/></g><g fill=\"var(--w-accent,#4fe3c1)\"><circle class=\"ptc-a\" cx=\"42\" cy=\"48\" r=\"3.5\"/><circle class=\"ptc-b\" cx=\"92\" cy=\"72\" r=\"3\"/><circle class=\"ptc-c\" cx=\"140\" cy=\"41\" r=\"4\"/><circle class=\"ptc-d\" cx=\"197\" cy=\"83\" r=\"3\"/><circle class=\"ptc-e\" cx=\"55\" cy=\"101\" r=\"2.8\"/><circle class=\"ptc-f\" cx=\"154\" cy=\"103\" r=\"3.4\"/></g>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">slow drift  ·  low density</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "canvas-raf-loop",
    "cursor-spotlight",
    "parallax-background",
    "canvas-ctx-filter"
   ]
  },
  {
   "id": "starfield",
   "num": "W-131",
   "name": "Starfield",
   "nameJa": "星空背景",
   "category": "background",
   "description": "小さな円やbox-shadowの点を多数散らし、opacityをランダムに明滅させて瞬く星空を表現する背景。box-shadowの多重指定だけで軽量に実装できる。",
   "useCase": "ダークテーマのLPや夜・宇宙をテーマにしたセクションの背景で、静かで幻想的な雰囲気を出したいときに使う。",
   "code": ".stars-bg { position: relative; background: #101830; overflow: hidden; }\n.stars-bg::before {\n  content: \"\";\n  position: absolute; top: 0; left: 0;\n  width: 2px; height: 2px; border-radius: 50%;\n  background: transparent;\n  box-shadow:\n    20px 30px #e8eef9, 80px 10px #e8eef9, 140px 60px #e8eef9,\n    200px 20px #e8eef9, 40px 100px #e8eef9, 180px 110px #e8eef9;\n  animation: twinkle 2.5s ease-in-out infinite alternate;\n}\n@keyframes twinkle { from { opacity:.4 } to { opacity:1 } }",
   "tags": [
    "CSS",
    "box-shadow",
    "背景",
    "星空",
    "幻想的",
    "静か",
    "没入感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"星空背景のデモ\">\n  <style>\n    .strf-s{fill:var(--w-ink,#e8eef9)}\n    .strf-a{animation:strf-tw 2.4s ease-in-out infinite}\n    .strf-b{animation:strf-tw 3.1s ease-in-out infinite .6s}\n    .strf-c{animation:strf-tw 2.8s ease-in-out infinite 1.2s}\n    @keyframes strf-tw{0%,100%{opacity:.25}50%{opacity:1}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <circle class=\"strf-s strf-a\" cx=\"30\" cy=\"30\" r=\"1.6\"/>\n  <circle class=\"strf-s strf-b\" cx=\"80\" cy=\"60\" r=\"1.2\"/>\n  <circle class=\"strf-s strf-c\" cx=\"130\" cy=\"20\" r=\"1.8\"/>\n  <circle class=\"strf-s strf-a\" cx=\"180\" cy=\"80\" r=\"1.4\"/>\n  <circle class=\"strf-s strf-b\" cx=\"210\" cy=\"40\" r=\"1.6\"/>\n  <circle class=\"strf-s strf-c\" cx=\"60\" cy=\"110\" r=\"1.3\"/>\n  <circle class=\"strf-s strf-a\" cx=\"150\" cy=\"120\" r=\"1.7\"/>\n  <circle class=\"strf-s strf-b\" cx=\"200\" cy=\"115\" r=\"1.2\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "aurora-background",
    "lava-blob",
    "cursor-spotlight",
    "ken-burns"
   ]
  },
  {
   "id": "cursor-spotlight",
   "num": "W-132",
   "name": "Cursor Spotlight",
   "nameJa": "カーソル追従スポットライト",
   "category": "background",
   "description": "mousemoveでカーソル座標を取得しCSS変数に反映、radial-gradientの中心をその変数に紐づけてカーソル周りだけ明るく照らす背景演出。",
   "useCase": "プロダクト紹介LPのカード群やダークUIで、操作している場所に視線を誘導したいときに使う。",
   "code": "el.addEventListener('mousemove', e => {\n  el.style.setProperty('--x', e.offsetX + 'px');\n  el.style.setProperty('--y', e.offsetY + 'px');\n});\n/* CSS */\n.spotlight {\n  background: radial-gradient(240px circle at var(--x,50%) var(--y,50%),\n    rgba(79,227,193,.25), transparent 70%), #101830;\n}",
   "tags": [
    "CSS",
    "JavaScript",
    "カーソル",
    "背景",
    "インタラクティブ",
    "目を引く",
    "没入感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"カーソル追従スポットライトのデモ\">\n  <defs>\n    <radialGradient id=\"csl-g\" r=\"45%\">\n      <stop offset=\"0%\" stop-color=\"var(--w-accent,#4fe3c1)\" stop-opacity=\".55\"/>\n      <stop offset=\"100%\" stop-color=\"var(--w-accent,#4fe3c1)\" stop-opacity=\"0\"/>\n    </radialGradient>\n  </defs>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <circle r=\"55\" fill=\"url(#csl-g)\">\n    <animate attributeName=\"cx\" values=\"60;180;60\" dur=\"4s\" repeatCount=\"indefinite\"/>\n    <animate attributeName=\"cy\" values=\"50;100;50\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </circle>\n  <circle r=\"4\" fill=\"var(--w-ink,#e8eef9)\">\n    <animate attributeName=\"cx\" values=\"60;180;60\" dur=\"4s\" repeatCount=\"indefinite\"/>\n    <animate attributeName=\"cy\" values=\"50;100;50\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </circle>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "parallax-background",
    "horizontal-scroll-section",
    "custom-cursor",
    "laser-pointer-cursor"
   ]
  },
  {
   "id": "video-background",
   "num": "W-133",
   "name": "Video Background",
   "nameJa": "動画背景",
   "category": "background",
   "description": "video要素にautoplay muted loop playsinlineを指定し、object-fit: coverでセクション全面に敷き詰めて実写やCGの動きをそのまま背景にする手法。",
   "useCase": "ブランドムービーの世界観をそのまま伝えたいファーストビューや、採用LPの雰囲気づくりに使う。",
   "code": "<video class=\"bg-video\" autoplay muted loop playsinline>\n  <source src=\"hero.mp4\" type=\"video/mp4\">\n</video>\n<style>\n.bg-video {\n  position: absolute; inset: 0;\n  width: 100%; height: 100%;\n  object-fit: cover; z-index: -1;\n}\n</style>",
   "tags": [
    "HTML",
    "video",
    "背景",
    "実写",
    "没入感",
    "ダイナミック",
    "高級感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"動画背景のデモ\">\n  <defs>\n    <clipPath id=\"vbg-c\"><rect x=\"10\" y=\"10\" width=\"220\" height=\"130\" rx=\"8\"/></clipPath>\n  </defs>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g clip-path=\"url(#vbg-c)\">\n    <rect x=\"10\" y=\"10\" width=\"220\" height=\"130\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".2\"/>\n    <circle r=\"70\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".5\">\n      <animate attributeName=\"cx\" values=\"0;240;0\" dur=\"5s\" repeatCount=\"indefinite\"/>\n      <animate attributeName=\"cy\" values=\"20;130;20\" dur=\"5s\" repeatCount=\"indefinite\"/>\n    </circle>\n  </g>\n  <polygon points=\"108,62 108,88 134,75\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".9\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "aurora-background",
    "parallax-background",
    "parallax-scroll",
    "command-palette"
   ]
  },
  {
   "id": "outline-text-bg",
   "num": "W-134",
   "name": "Giant Outline Text Background",
   "nameJa": "巨大アウトライン文字の背景",
   "category": "background",
   "description": "fill: transparentと-webkit-text-strokeで縁取りだけの超大型文字を背面に配置し、装飾として薄く見せるレイアウト手法。",
   "useCase": "スライドやLPのセクション見出し背後に、ブランドワードを大きく薄く敷いて世界観を強調したいときに使う。",
   "code": ".outline-bg {\n  position: absolute; inset: 0;\n  display: flex; align-items: center; justify-content: center;\n  font-size: 12rem; font-weight: 800;\n  color: transparent;\n  -webkit-text-stroke: 2px rgba(232,238,249,.15);\n  pointer-events: none; z-index: 0;\n}",
   "tags": [
    "CSS",
    "タイポグラフィ",
    "背景",
    "装飾",
    "さりげない",
    "高級感",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"巨大アウトライン文字の背景のデモ\">\n  <style>\n    .otb-t{animation:otb-fade 4s ease-in-out infinite}\n    @keyframes otb-fade{0%,100%{opacity:.15}50%{opacity:.4}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <text class=\"otb-t\" x=\"120\" y=\"100\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"72\" font-weight=\"800\" fill=\"none\" stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"1.5\">AI</text>\n  <text x=\"120\" y=\"60\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"14\" fill=\"var(--w-accent,#4fe3c1)\">Section Title</text>\n</svg>",
   "useFor": [
    "slide",
    "lp"
   ],
   "weight": "主役",
   "relatedIds": [
    "mesh-gradient",
    "text-extrude",
    "custom-scrollbar",
    "text-image-mask"
   ]
  },
  {
   "id": "ken-burns",
   "num": "W-135",
   "name": "Ken Burns Effect",
   "nameJa": "ケンバーンズ効果",
   "category": "background",
   "description": "静止画をtransform: scale()で数秒から数十秒かけてゆっくり拡大・移動させ、動画のような臨場感を静止画だけで生み出す演出。",
   "useCase": "写真1枚しかないヒーロー背景やスライドショーの各カットで、静止感をなくしたいときに使う。",
   "code": ".ken-burns { position: relative; overflow: hidden; }\n.ken-burns::before {\n  content: \"\";\n  position: absolute; inset: -8%;\n  background-image: url(photo.jpg);\n  background-size: cover;\n  animation: kb 20s ease-in-out infinite alternate;\n}\n@keyframes kb {\n  from { transform: scale(1) translate(0,0); }\n  to   { transform: scale(1.15) translate(-2%,-2%); }\n}",
   "tags": [
    "CSS",
    "写真",
    "背景",
    "ズーム",
    "臨場感",
    "ゆったり",
    "没入感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ケンバーンズ効果のデモ\">\n  <style>\n    .kbn-img{animation:kbn-zoom 6s ease-in-out infinite alternate;transform-origin:60% 40%}\n    @keyframes kbn-zoom{from{transform:scale(1)}to{transform:scale(1.25)}}\n  </style>\n  <defs>\n    <clipPath id=\"kbn-c\"><rect x=\"14\" y=\"14\" width=\"212\" height=\"122\" rx=\"6\"/></clipPath>\n  </defs>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g clip-path=\"url(#kbn-c)\">\n    <g class=\"kbn-img\">\n      <rect x=\"14\" y=\"14\" width=\"212\" height=\"122\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".25\"/>\n      <circle cx=\"90\" cy=\"60\" r=\"34\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".7\"/>\n      <circle cx=\"170\" cy=\"100\" r=\"26\" fill=\"var(--w-amber,#ffc857)\" opacity=\".6\"/>\n    </g>\n  </g>\n</svg>",
   "useFor": [
    "slide",
    "lp"
   ],
   "weight": "脇役",
   "relatedIds": [
    "aurora-background",
    "lava-blob",
    "starfield",
    "cursor-spotlight"
   ]
  },
  {
   "id": "scrim-overlay",
   "num": "W-136",
   "name": "Scrim Overlay",
   "nameJa": "暗幕スクリム",
   "category": "background",
   "description": "画像や動画の上に黒から透明へのlinear-gradientを重ねて下部や全体を暗くし、白文字の可読性を確保するオーバーレイ手法。",
   "useCase": "写真・動画背景の上にテキストを乗せるヒーローセクションで、コントラストを確保して読みやすくしたいときに使う。",
   "code": ".scrim { position: relative; }\n.scrim::after {\n  content: \"\";\n  position: absolute; inset: 0;\n  background: linear-gradient(to top, rgba(0,0,0,.75), transparent 60%);\n}",
   "tags": [
    "CSS",
    "グラデーション",
    "背景",
    "可読性",
    "オーバーレイ",
    "落ち着き",
    "さりげない"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"暗幕スクリムのデモ\">\n  <defs>\n    <linearGradient id=\"scr-g\" x1=\"0\" y1=\"1\" x2=\"0\" y2=\"0\">\n      <stop offset=\"0%\" stop-color=\"var(--w-bg,#101830)\" stop-opacity=\".9\"/>\n      <stop offset=\"60%\" stop-color=\"var(--w-bg,#101830)\" stop-opacity=\"0\"/>\n    </linearGradient>\n  </defs>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".4\"/>\n  <circle cx=\"90\" cy=\"55\" r=\"28\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".6\"/>\n  <circle cx=\"160\" cy=\"90\" r=\"22\" fill=\"var(--w-amber,#ffc857)\" opacity=\".5\"/>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"url(#scr-g)\">\n    <animate attributeName=\"opacity\" values=\".5;1;.5\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </rect>\n  <text x=\"20\" y=\"128\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"14\" fill=\"var(--w-ink,#e8eef9)\">Headline</text>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "gradient-animation",
    "mesh-gradient",
    "dot-grid-pattern",
    "outline-text-bg"
   ]
  },
  {
   "id": "floating-shapes",
   "num": "W-137",
   "name": "Floating Geometric Shapes",
   "nameJa": "浮遊する幾何学図形",
   "category": "background",
   "description": "円・三角形・多角形などをposition: absoluteで散らし、それぞれ異なる周期のtransform: translateYアニメーションでゆっくり上下浮遊させる背景装飾。",
   "useCase": "SaaSやスタートアップ系LPの余白で、単色背景に軽やかな動きと現代感を足したいときに使う。",
   "code": ".shape {\n  position: absolute;\n  animation: floaty 6s ease-in-out infinite;\n}\n.shape:nth-child(2) { animation-duration: 8s; animation-delay: -2s; }\n@keyframes floaty {\n  0%, 100% { transform: translateY(0) rotate(0deg); }\n  50% { transform: translateY(-20px) rotate(8deg); }\n}",
   "tags": [
    "CSS",
    "図形",
    "背景",
    "浮遊",
    "ふわふわ",
    "軽やか",
    "装飾"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"浮遊する幾何学図形のデモ\">\n  <style>\n    .fls-a{animation:fls-f1 4s ease-in-out infinite}\n    .fls-b{animation:fls-f2 5s ease-in-out infinite}\n    .fls-c{animation:fls-f1 6s ease-in-out infinite 1s}\n    @keyframes fls-f1{0%,100%{transform:translateY(0)}50%{transform:translateY(-14px)}}\n    @keyframes fls-f2{0%,100%{transform:translateY(0) rotate(0deg)}50%{transform:translateY(12px) rotate(20deg)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <circle class=\"fls-a\" cx=\"50\" cy=\"40\" r=\"14\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".8\"/>\n  <rect class=\"fls-b\" x=\"160\" y=\"30\" width=\"26\" height=\"26\" rx=\"6\" fill=\"var(--w-amber,#ffc857)\" opacity=\".75\"/>\n  <polygon class=\"fls-c\" points=\"110,90 130,120 90,120\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".7\"/>\n  <circle class=\"fls-b\" cx=\"190\" cy=\"110\" r=\"10\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".6\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "outline-text-bg",
    "css-shape-function",
    "gradient-animation",
    "aurora-background"
   ]
  },
  {
   "id": "crt-scanlines",
   "num": "W-138",
   "name": "CRT Scanlines",
   "nameJa": "走査線・レトロCRT風",
   "category": "background",
   "description": "repeating-linear-gradientで水平の走査線を重ね、上から下へ流れる光の帯やわずかな歪みを添えてブラウン管モニターの質感を再現する背景。",
   "useCase": "レトロゲーム風・8bit風の演出やノスタルジックなブランド表現をしたいセクションの背景に使う。",
   "code": ".crt { position: relative; background: #101830; }\n.crt::before {\n  content: \"\";\n  position: absolute; inset: 0;\n  background: repeating-linear-gradient(\n    to bottom, rgba(0,0,0,.35) 0 1px, transparent 1px 3px\n  );\n  animation: scan 6s linear infinite;\n}\n@keyframes scan { from { background-position: 0 0 } to { background-position: 0 12px } }",
   "tags": [
    "CSS",
    "走査線",
    "背景",
    "レトロ",
    "ノスタルジック",
    "チープ感",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"走査線・レトロCRT風のデモ\">\n  <defs>\n    <pattern id=\"crt-p\" width=\"4\" height=\"4\" patternUnits=\"userSpaceOnUse\">\n      <rect width=\"4\" height=\"1.4\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".18\"/>\n    </pattern>\n  </defs>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <circle cx=\"120\" cy=\"75\" r=\"40\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".5\"/>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"url(#crt-p)\"/>\n  <rect x=\"0\" y=\"0\" width=\"240\" height=\"18\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".12\">\n    <animate attributeName=\"y\" values=\"-18;150\" dur=\"2.5s\" repeatCount=\"indefinite\"/>\n  </rect>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "mesh-gradient",
    "flowing-stripes",
    "cursor-spotlight",
    "outline-text-bg"
   ]
  },
  {
   "id": "parallax-background",
   "num": "W-139",
   "name": "Parallax Scrolling Background",
   "nameJa": "パララックス背景",
   "category": "background",
   "description": "background-attachment: fixedや複数レイヤーのtransform: translateYをスクロール量に応じて異なる速度で動かし、奥行きのある立体的なスクロール演出を作る。",
   "useCase": "ストーリー性のあるLPや長尺スクロールページで、奥の背景と手前のコンテンツに視差をつけて没入感を出したいときに使う。",
   "code": ".parallax-bg {\n  background-image: url(bg.jpg);\n  background-attachment: fixed;\n  background-position: center;\n  background-size: cover;\n}\n/* JS: 手前のレイヤーだけ速く動かす */\nwindow.addEventListener('scroll', () => {\n  layer.style.transform = `translateY(${scrollY * 0.3}px)`;\n});",
   "tags": [
    "CSS",
    "JavaScript",
    "スクロール",
    "背景",
    "奥行き",
    "没入感",
    "ダイナミック"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"パララックス背景のデモ\">\n  <style>\n    .plx-back{animation:plx-slow 5s ease-in-out infinite alternate}\n    .plx-mid{animation:plx-mid 5s ease-in-out infinite alternate}\n    .plx-front{animation:plx-fast 5s ease-in-out infinite alternate}\n    @keyframes plx-slow{from{transform:translateY(0)}to{transform:translateY(6px)}}\n    @keyframes plx-mid{from{transform:translateY(0)}to{transform:translateY(14px)}}\n    @keyframes plx-fast{from{transform:translateY(0)}to{transform:translateY(26px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"plx-back\">\n    <circle cx=\"60\" cy=\"40\" r=\"30\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".3\"/>\n    <circle cx=\"190\" cy=\"30\" r=\"20\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".3\"/>\n  </g>\n  <g class=\"plx-mid\"><rect x=\"30\" y=\"80\" width=\"50\" height=\"50\" rx=\"8\" fill=\"var(--w-amber,#ffc857)\" opacity=\".55\"/></g>\n  <g class=\"plx-front\"><rect x=\"140\" y=\"70\" width=\"70\" height=\"60\" rx=\"8\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".8\"/></g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "parallax-scroll",
    "horizontal-scroll-section",
    "cursor-spotlight",
    "scrollytelling"
   ]
  },
  {
   "id": "wave-divider-bg",
   "num": "W-140",
   "name": "Wave Divider",
   "nameJa": "波形ディバイダー",
   "category": "background",
   "description": "SVGの波形pathをセクション境界に敷き、CSSのd属性アニメーションやSMILでtranslateXやdをゆらすことで水面のように揺らぐ区切りを作る。",
   "useCase": "LPのセクション間の直線的な境目をなくし、柔らかく自然な区切りにしたいときに使う。",
   "code": "<svg viewBox=\"0 0 400 60\" preserveAspectRatio=\"none\" class=\"wave\">\n  <path d=\"M0,30 C100,60 300,0 400,30 L400,60 L0,60 Z\" fill=\"#101830\"/>\n</svg>\n<style>\n.wave path { animation: waveMove 6s ease-in-out infinite alternate; }\n@keyframes waveMove {\n  from { d: path(\"M0,30 C100,60 300,0 400,30 L400,60 L0,60 Z\"); }\n  to   { d: path(\"M0,20 C100,0 300,60 400,20 L400,60 L0,60 Z\"); }\n}\n</style>",
   "tags": [
    "SVG",
    "CSS",
    "波形",
    "背景",
    "区切り",
    "やわらか",
    "ぬるっと"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"波形ディバイダーのデモ\">\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".25\"/>\n  <path fill=\"var(--w-bg,#101830)\">\n    <animate attributeName=\"d\" dur=\"4s\" repeatCount=\"indefinite\"\n      values=\"M0,90 C60,60 180,120 240,90 L240,150 L0,150 Z;\n              M0,100 C60,130 180,70 240,100 L240,150 L0,150 Z;\n              M0,90 C60,60 180,120 240,90 L240,150 L0,150 Z\"/>\n  </path>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "lava-blob",
    "gradient-animation",
    "aurora-background",
    "mesh-gradient"
   ]
  },
  {
   "id": "number-count-up",
   "num": "W-141",
   "name": "Count-Up Number",
   "nameJa": "数字カウントアップ",
   "category": "component",
   "description": "0や小さい値から目標値へ数字が滑らかに増えていく演出。requestAnimationFrameで毎フレーム計算するか、CSSの@propertyで数値型カスタムプロパティを定義しtransitionさせて実装する。",
   "useCase": "LPの導入社数・売上・満足度などの実績数値や、ダッシュボードのKPIカードを表示時に印象づけたい場面で使う。",
   "code": "@property --num{syntax:'<integer>';initial-value:0;inherits:false}\n.count{transition:--num 1.6s ease-out;counter-reset:num var(--num)}\n.count::after{content:counter(num)}\n.count.in-view{--num:1280}",
   "tags": [
    "CSS",
    "@property",
    "カウンター",
    "数値",
    "説得力",
    "ワクワク",
    "LP",
    "ダッシュボード"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"数字カウントアップのデモ\">\n  <style>\n    .ncup-n1{animation:ncup-fade 3s linear infinite}\n    .ncup-n2{opacity:0;animation:ncup-fade 3s linear infinite;animation-delay:1s}\n    .ncup-n3{opacity:0;animation:ncup-fade 3s linear infinite;animation-delay:2s}\n    @keyframes ncup-fade{0%,30%{opacity:1}34%,100%{opacity:0}}\n    .ncup-bar{animation:ncup-grow 3s ease-in-out infinite;transform-origin:150px 120px}\n    @keyframes ncup-grow{0%{transform:scaleY(.15)}100%{transform:scaleY(1)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"ncup-bar\" x=\"150\" y=\"80\" width=\"16\" height=\"40\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".5\"/>\n  <text class=\"ncup-n1\" x=\"110\" y=\"80\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"32\" fill=\"var(--w-ink,#e8eef9)\">128</text>\n  <text class=\"ncup-n2\" x=\"110\" y=\"80\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"32\" fill=\"var(--w-ink,#e8eef9)\">512</text>\n  <text class=\"ncup-n3\" x=\"110\" y=\"80\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"32\" fill=\"var(--w-ink,#e8eef9)\">1,280</text>\n  <text x=\"110\" y=\"112\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#94a3c0)\">導入社数</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "before-after-slider",
    "logo-marquee",
    "pricing-card-hover-lift",
    "property-custom-animate"
   ]
  },
  {
   "id": "circular-progress",
   "num": "W-142",
   "name": "Circular Progress",
   "nameJa": "円形プログレス",
   "category": "component",
   "description": "円環が進捗率に応じてぐるっと塗り進むインジケーター。SVGの<circle>にstroke-dasharrayを設定し、stroke-dashoffsetの値をJSやCSSアニメーションで動かして表現する。",
   "useCase": "スキル達成率、アップロード進捗、ダッシュボードの完了率カードなど、割合をひと目で伝えたいときに使う。",
   "code": "<svg viewBox=\"0 0 36 36\">\n  <circle cx=\"18\" cy=\"18\" r=\"16\" fill=\"none\" stroke=\"#e5e7eb\" stroke-width=\"3\"/>\n  <circle cx=\"18\" cy=\"18\" r=\"16\" fill=\"none\" stroke=\"#4fe3c1\" stroke-width=\"3\"\n    stroke-dasharray=\"100\" stroke-dashoffset=\"28\" stroke-linecap=\"round\"\n    transform=\"rotate(-90 18 18)\"/>\n</svg>",
   "tags": [
    "SVG",
    "プログレス",
    "進捗",
    "ぐるっと",
    "達成感",
    "ダッシュボード"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"円形プログレスのデモ\">\n  <style>\n    .cprg-ring{stroke-dasharray:251;animation:cprg-fill 3s ease-in-out infinite}\n    @keyframes cprg-fill{0%{stroke-dashoffset:251}70%{stroke-dashoffset:45}100%{stroke-dashoffset:251}}\n    .cprg-txt{animation:cprg-fade 3s ease-in-out infinite}\n    @keyframes cprg-fade{0%{opacity:.3}70%{opacity:1}100%{opacity:.3}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <circle cx=\"120\" cy=\"75\" r=\"40\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-width=\"10\" opacity=\".3\"/>\n  <circle class=\"cprg-ring\" cx=\"120\" cy=\"75\" r=\"40\" fill=\"none\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"10\" stroke-linecap=\"round\" transform=\"rotate(-90 120 75)\"/>\n  <text class=\"cprg-txt\" x=\"120\" y=\"80\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"18\" fill=\"var(--w-ink,#e8eef9)\">82%</text>\n</svg>",
   "useFor": [
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "svg-sparkline",
    "checkmark-draw",
    "progress-ring",
    "svg-line-area-chart"
   ]
  },
  {
   "id": "skeleton-shimmer",
   "num": "W-143",
   "name": "Skeleton Shimmer",
   "nameJa": "スケルトンスクリーンのシマー",
   "category": "component",
   "description": "コンテンツ読み込み中に灰色のブロックへ光の帯が斜めに流れる演出。linear-gradientの背景をbackground-position移動でアニメーションさせて実装する。",
   "useCase": "画像やカード情報のfetch待ちの間、読み込み中の体感時間をさりげなく短く見せたいリストやカードUIで使う。",
   "code": ".skel{background:linear-gradient(100deg,#e2e8f0 30%,#f8fafc 50%,#e2e8f0 70%);\n  background-size:200% 100%;animation:shimmer 1.4s linear infinite}\n@keyframes shimmer{to{background-position:-200% 0}}",
   "tags": [
    "CSS",
    "ローディング",
    "グラデーション",
    "さりげない",
    "待機体感",
    "カード"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"スケルトンスクリーンのシマーのデモ\">\n  <defs>\n    <linearGradient id=\"sksh-grad\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"0\">\n      <stop offset=\"0%\" stop-color=\"var(--w-ink,#e8eef9)\" stop-opacity=\"0\"/>\n      <stop offset=\"50%\" stop-color=\"var(--w-ink,#e8eef9)\" stop-opacity=\".55\"/>\n      <stop offset=\"100%\" stop-color=\"var(--w-ink,#e8eef9)\" stop-opacity=\"0\"/>\n    </linearGradient>\n    <clipPath id=\"sksh-clip\">\n      <rect x=\"20\" y=\"30\" width=\"200\" height=\"18\" rx=\"4\"/>\n      <rect x=\"20\" y=\"58\" width=\"160\" height=\"18\" rx=\"4\"/>\n      <rect x=\"20\" y=\"86\" width=\"180\" height=\"18\" rx=\"4\"/>\n    </clipPath>\n  </defs>\n  <style>\n    .sksh-sweep{animation:sksh-move 4s linear infinite}\n    @keyframes sksh-move{from{transform:translateX(-80px)}to{transform:translateX(300px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"20\" y=\"30\" width=\"200\" height=\"18\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".25\"/>\n  <rect x=\"20\" y=\"58\" width=\"160\" height=\"18\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".25\"/>\n  <rect x=\"20\" y=\"86\" width=\"180\" height=\"18\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".25\"/>\n  <g clip-path=\"url(#sksh-clip)\">\n    <rect class=\"sksh-sweep\" x=\"0\" y=\"20\" width=\"80\" height=\"100\" fill=\"url(#sksh-grad)\"/>\n  </g>\n</svg>",
   "useFor": [
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "loading-spinner",
    "hover-lift-card",
    "line-clamp",
    "mask-gradient-fade"
   ]
  },
  {
   "id": "toast-notification",
   "num": "W-144",
   "name": "Toast Notification",
   "nameJa": "トースト通知",
   "category": "component",
   "description": "画面端にパッと現れて数秒だけ静止し、すっと消える短い通知バー。position:fixedで配置し、@keyframesでtranslateYとopacityを操作して出現から消失までを一続きに演出する。",
   "useCase": "保存完了・エラー・カート追加などの結果を、ユーザーの操作を止めずに一瞬で伝えたいときに使う。",
   "code": ".toast{position:fixed;right:16px;bottom:16px;animation:toast-in .3s ease-out,\n  toast-out .3s ease-in 2.7s forwards}\n@keyframes toast-in{from{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}\n@keyframes toast-out{to{transform:translateY(20px);opacity:0}}",
   "tags": [
    "CSS",
    "通知",
    "アニメーション",
    "パッと切替",
    "フィードバック",
    "さりげない"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"トースト通知のデモ\">\n  <style>\n    .tstn-card{animation:tstn-cycle 3.5s ease-in-out infinite}\n    @keyframes tstn-cycle{\n      0%{transform:translateY(30px);opacity:0}\n      14%{transform:translateY(0);opacity:1}\n      78%{transform:translateY(0);opacity:1}\n      100%{transform:translateY(30px);opacity:0}\n    }\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"16\" y=\"16\" width=\"208\" height=\"110\" rx=\"8\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-opacity=\".3\"/>\n  <g class=\"tstn-card\">\n    <rect x=\"96\" y=\"94\" width=\"128\" height=\"34\" rx=\"8\" fill=\"var(--w-ink,#e8eef9)\"/>\n    <circle cx=\"114\" cy=\"111\" r=\"6\" fill=\"var(--w-accent,#4fe3c1)\"/>\n    <text x=\"128\" y=\"115\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-bg,#101830)\">保存しました</text>\n  </g>\n</svg>",
   "useFor": [
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "ripple-effect",
    "skeleton-shimmer",
    "back-to-top",
    "text-emphasis-dots"
   ]
  },
  {
   "id": "logo-marquee",
   "num": "W-145",
   "name": "Logo Marquee",
   "nameJa": "ロゴが流れるマーキー",
   "category": "component",
   "description": "導入企業ロゴなどが途切れず横に流れ続ける帯。同じロゴ列を複製して並べ、translateXを列の幅ぶんだけループさせることで継ぎ目を隠す。",
   "useCase": "LPの「導入実績」「提携企業」セクションで、ロゴを並べるだけより信頼感を強く演出したいときに使う。",
   "code": ".marquee{display:flex;width:max-content;animation:marquee 18s linear infinite}\n.marquee-track{display:flex;gap:48px}\n@keyframes marquee{to{transform:translateX(-50%)}}\n/* .marquee-track を2セット複製して並べる */",
   "tags": [
    "CSS",
    "マーキー",
    "ロゴ",
    "無限ループ",
    "信頼感",
    "流れる",
    "LP"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ロゴが流れるマーキーのデモ\">\n  <defs>\n    <clipPath id=\"lmqe-clip\"><rect x=\"20\" y=\"55\" width=\"200\" height=\"30\"/></clipPath>\n  </defs>\n  <style>\n    .lmqe-track{animation:lmqe-scroll 4s linear infinite}\n    @keyframes lmqe-scroll{to{transform:translateX(-150px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g clip-path=\"url(#lmqe-clip)\">\n    <g class=\"lmqe-track\">\n      <rect x=\"20\" y=\"60\" width=\"34\" height=\"20\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".6\"/>\n      <rect x=\"70\" y=\"60\" width=\"34\" height=\"20\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".6\"/>\n      <rect x=\"120\" y=\"60\" width=\"34\" height=\"20\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".6\"/>\n      <rect x=\"170\" y=\"60\" width=\"34\" height=\"20\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".6\"/>\n      <rect x=\"220\" y=\"60\" width=\"34\" height=\"20\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".6\"/>\n      <rect x=\"270\" y=\"60\" width=\"34\" height=\"20\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".6\"/>\n      <rect x=\"320\" y=\"60\" width=\"34\" height=\"20\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".6\"/>\n      <rect x=\"370\" y=\"60\" width=\"34\" height=\"20\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".6\"/>\n    </g>\n  </g>\n</svg>",
   "useFor": [
    "lp"
   ],
   "weight": "脇役",
   "relatedIds": [
    "timeline",
    "pricing-card-hover-lift",
    "hover-pause",
    "number-count-up"
   ]
  },
  {
   "id": "tab-switch",
   "num": "W-146",
   "name": "Tabs",
   "nameJa": "タブ切替",
   "category": "component",
   "description": "複数のパネルを1つの表示領域でパッと切り替えるUI。タブのaria-selectedとパネルのhidden属性を同期し、下線インジケーターをtransformで滑らせる。",
   "useCase": "料金プランの月額/年額切替や、製品仕様・レビューなど複数情報を同じ枠内で見せたいセクションで使う。",
   "code": "<div role=\"tablist\">\n  <button role=\"tab\" aria-selected=\"true\" aria-controls=\"p1\">概要</button>\n  <button role=\"tab\" aria-selected=\"false\" aria-controls=\"p2\">仕様</button>\n</div>\n<div id=\"p1\" role=\"tabpanel\">...</div>\n<div id=\"p2\" role=\"tabpanel\" hidden>...</div>",
   "tags": [
    "HTML",
    "タブ",
    "ARIA",
    "パッと切替",
    "ナビゲーション",
    "分かりやすさ"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"タブ切替のデモ\">\n  <style>\n    .tbsw-ind{animation:tbsw-slide 3s ease-in-out infinite}\n    @keyframes tbsw-slide{0%,42%{transform:translateX(0)}50%,92%{transform:translateX(80px)}100%{transform:translateX(0)}}\n    .tbsw-p1{animation:tbsw-p1 3s ease-in-out infinite}\n    .tbsw-p2{animation:tbsw-p2 3s ease-in-out infinite}\n    @keyframes tbsw-p1{0%,42%{opacity:1}50%,100%{opacity:0}}\n    @keyframes tbsw-p2{0%,42%{opacity:0}50%,92%{opacity:1}100%{opacity:0}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <text x=\"40\" y=\"34\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"13\" fill=\"var(--w-ink,#e8eef9)\">概要</text>\n  <text x=\"120\" y=\"34\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"13\" fill=\"var(--w-sub,#94a3c0)\">仕様</text>\n  <rect class=\"tbsw-ind\" x=\"32\" y=\"42\" width=\"34\" height=\"3\" rx=\"1.5\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <line x1=\"24\" y1=\"46\" x2=\"216\" y2=\"46\" stroke=\"var(--w-sub,#94a3c0)\" stroke-opacity=\".25\"/>\n  <g class=\"tbsw-p1\">\n    <rect x=\"32\" y=\"60\" width=\"176\" height=\"14\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".4\"/>\n    <rect x=\"32\" y=\"82\" width=\"120\" height=\"14\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".4\"/>\n  </g>\n  <g class=\"tbsw-p2\">\n    <rect x=\"32\" y=\"60\" width=\"90\" height=\"60\" rx=\"4\" fill=\"var(--w-amber,#ffc857)\" opacity=\".35\"/>\n    <rect x=\"132\" y=\"60\" width=\"76\" height=\"60\" rx=\"4\" fill=\"var(--w-amber,#ffc857)\" opacity=\".2\"/>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "lightbox-dialog",
    "popover-api",
    "dialog-modal",
    "target-css-toggle"
   ]
  },
  {
   "id": "faq-accordion",
   "num": "W-147",
   "name": "Accordion",
   "nameJa": "FAQアコーディオン",
   "category": "component",
   "description": "質問行をクリックすると回答欄がにゅっと滑らかに開閉するUI。grid-template-rowsを0frから1frへtransitionさせる手法で、高さautoでも滑らかにアニメーションできる。",
   "useCase": "FAQページや料金表の補足説明など、初期は畳んでおき必要な人だけ展開させたい場面で使う。",
   "code": ".acc-item{display:grid;grid-template-rows:0fr;transition:grid-template-rows .3s ease}\n.acc-item.open{grid-template-rows:1fr}\n.acc-item > .acc-body{overflow:hidden}",
   "tags": [
    "CSS",
    "Grid",
    "アコーディオン",
    "開閉",
    "にゅっと",
    "FAQ",
    "省スペース"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"FAQアコーディオンのデモ\">\n  <style>\n    .facc-body{animation:facc-open 3.2s ease-in-out infinite;transform-origin:120px 48px}\n    @keyframes facc-open{0%,10%{transform:scaleY(0)}45%,80%{transform:scaleY(1)}95%,100%{transform:scaleY(0)}}\n    .facc-chev{animation:facc-rot 3.2s ease-in-out infinite;transform-origin:206px 30px}\n    @keyframes facc-rot{0%,10%{transform:rotate(0)}45%,80%{transform:rotate(180deg)}95%,100%{transform:rotate(0)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"20\" y=\"18\" width=\"200\" height=\"26\" rx=\"6\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".18\"/>\n  <text x=\"32\" y=\"35\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"12\" fill=\"var(--w-ink,#e8eef9)\">送料はいくらですか？</text>\n  <path class=\"facc-chev\" d=\"M201 27 l5 6 l5 -6\" stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"2\" fill=\"none\"/>\n  <g class=\"facc-body\">\n    <rect x=\"20\" y=\"48\" width=\"200\" height=\"40\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".15\"/>\n    <text x=\"32\" y=\"65\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#94a3c0)\">全国一律550円、1万円</text>\n    <text x=\"32\" y=\"78\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#94a3c0)\">以上のご注文で送料無料</text>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "details-content",
    "reading-flow",
    "interpolate-size",
    "field-sizing"
   ]
  },
  {
   "id": "before-after-slider",
   "num": "W-148",
   "name": "Before/After Comparison Slider",
   "nameJa": "ビフォーアフター比較スライダー",
   "category": "component",
   "description": "2枚の画像を1本のハンドルで左右にぬるっと見比べるUI。input[type=range]の値を使いclip-pathやwidthで上側画像の表示範囲をリアルタイムに制御する。",
   "useCase": "施術・リフォーム・写真編集など、変化を1枚の見た目で説得力高く見せたい実績紹介ページで使う。",
   "code": "<div class=\"ba-wrap\" id=\"wrap\">\n  <img class=\"ba-after\" src=\"after.jpg\">\n  <img class=\"ba-before\" src=\"before.jpg\" style=\"clip-path:inset(0 var(--pos,50%) 0 0)\">\n  <input type=\"range\" oninput=\"wrap.style.setProperty('--pos',(100-value)+'%')\">\n</div>",
   "tags": [
    "CSS",
    "clip-path",
    "比較",
    "スライダー",
    "ぬるっと",
    "説得力"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ビフォーアフター比較スライダーのデモ\">\n  <defs>\n    <clipPath id=\"bfaf-clip\"><rect x=\"20\" y=\"20\" width=\"200\" height=\"110\" rx=\"8\"/></clipPath>\n  </defs>\n  <style>\n    .bfaf-after{animation:bfaf-w 2.6s ease-in-out infinite}\n    @keyframes bfaf-w{0%{width:0}50%{width:200px}100%{width:0}}\n    .bfaf-handle{animation:bfaf-x 2.6s ease-in-out infinite}\n    @keyframes bfaf-x{0%{transform:translateX(20px)}50%{transform:translateX(220px)}100%{transform:translateX(20px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g clip-path=\"url(#bfaf-clip)\">\n    <rect x=\"20\" y=\"20\" width=\"200\" height=\"110\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".3\"/>\n    <rect class=\"bfaf-after\" x=\"20\" y=\"20\" height=\"110\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".45\"/>\n  </g>\n  <rect x=\"20\" y=\"20\" width=\"200\" height=\"110\" rx=\"8\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-opacity=\".4\"/>\n  <g class=\"bfaf-handle\">\n    <line x1=\"0\" y1=\"20\" x2=\"0\" y2=\"130\" stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"2\"/>\n    <circle cx=\"0\" cy=\"75\" r=\"9\" fill=\"var(--w-ink,#e8eef9)\"/>\n    <path d=\"M-3 71 l-4 4 l4 4 M3 71 l4 4 l-4 4\" stroke=\"var(--w-bg,#101830)\" stroke-width=\"1.4\" fill=\"none\"/>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "clip-path-shapes",
    "carousel-scroll-snap",
    "star-rating",
    "css-shape-function"
   ]
  },
  {
   "id": "pricing-card-hover-lift",
   "num": "W-149",
   "name": "Card Hover Lift",
   "nameJa": "料金カードのホバーリフト",
   "category": "component",
   "description": "カードにカーソルを乗せるとふわっと浮き上がり、影が濃く広がる。transformのtranslateYとbox-shadowを同時にtransitionさせ、軽さと高級感を両立させる。",
   "useCase": "料金プラン・サービスカード一覧で、注目させたい選択肢を操作前から気持ちよく感じさせたいときに使う。",
   "code": ".price-card{transition:transform .2s ease,box-shadow .2s ease}\n.price-card:hover{transform:translateY(-8px);\n  box-shadow:0 16px 32px rgba(0,0,0,.18)}",
   "tags": [
    "CSS",
    "ホバー",
    "カード",
    "ふわっと",
    "浮遊感",
    "高級感",
    "LP"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"料金カードのホバーリフトのデモ\">\n  <style>\n    .pchl-card{animation:pchl-lift 2.4s ease-in-out infinite}\n    @keyframes pchl-lift{0%,20%{transform:translateY(0)}55%,80%{transform:translateY(-14px)}100%{transform:translateY(0)}}\n    .pchl-shadow{animation:pchl-shadow 2.4s ease-in-out infinite;transform-origin:120px 118px}\n    @keyframes pchl-shadow{0%,20%{opacity:.5;transform:scaleX(1)}55%,80%{opacity:.15;transform:scaleX(1.3)}100%{opacity:.5;transform:scaleX(1)}}\n    .pchl-cursor{animation:pchl-cur 2.4s ease-in-out infinite}\n    @keyframes pchl-cur{0%,15%{transform:translateY(20px);opacity:0}30%,75%{transform:translateY(0);opacity:1}95%,100%{transform:translateY(20px);opacity:0}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <ellipse class=\"pchl-shadow\" cx=\"120\" cy=\"118\" rx=\"46\" ry=\"8\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".2\"/>\n  <g class=\"pchl-card\">\n    <rect x=\"76\" y=\"34\" width=\"88\" height=\"70\" rx=\"10\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".2\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"1.5\"/>\n    <text x=\"120\" y=\"60\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"11\" fill=\"var(--w-ink,#e8eef9)\">Pro</text>\n    <text x=\"120\" y=\"82\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"14\" fill=\"var(--w-accent,#4fe3c1)\">¥1,980</text>\n  </g>\n  <path class=\"pchl-cursor\" d=\"M138 96 l14 6 l-6 2 l-2 6 z\" fill=\"var(--w-ink,#e8eef9)\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "card-flip",
    "hover-lift-card",
    "blur-reveal-text",
    "variable-font-weight"
   ]
  },
  {
   "id": "timeline",
   "num": "W-150",
   "name": "Timeline",
   "nameJa": "タイムライン",
   "category": "component",
   "description": "縦（または横）の線上にドットを並べ、各ドットから出来事を配置する構成。線はborder-left、ドットは::beforeの円で表現し、スクロール連動で順に強調してもよい。",
   "useCase": "会社沿革、開発ロードマップ、導入までのステップなど時系列の流れを一望させたいセクションで使う。",
   "code": ".tl{border-left:2px solid #cbd5e1;margin-left:12px}\n.tl-item{position:relative;padding:12px 0 12px 20px}\n.tl-item::before{content:\"\";position:absolute;left:-7px;top:16px;\n  width:12px;height:12px;border-radius:50%;background:#4fe3c1}",
   "tags": [
    "CSS",
    "タイムライン",
    "縦線",
    "沿革",
    "分かりやすさ",
    "流れる"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"タイムラインのデモ\">\n  <style>\n    .tmln-d1{animation:tmln-p 3.6s ease-in-out infinite}\n    .tmln-d2{animation:tmln-p 3.6s ease-in-out infinite;animation-delay:1.2s}\n    .tmln-d3{animation:tmln-p 3.6s ease-in-out infinite;animation-delay:2.4s}\n    @keyframes tmln-p{0%,8%{fill:var(--w-sub,#94a3c0)}20%,90%{fill:var(--w-accent,#4fe3c1)}100%{fill:var(--w-sub,#94a3c0)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <line x1=\"40\" y1=\"24\" x2=\"40\" y2=\"126\" stroke=\"var(--w-sub,#94a3c0)\" stroke-opacity=\".4\" stroke-width=\"2\"/>\n  <circle class=\"tmln-d1\" cx=\"40\" cy=\"34\" r=\"6\" fill=\"var(--w-sub,#94a3c0)\"/>\n  <circle class=\"tmln-d2\" cx=\"40\" cy=\"75\" r=\"6\" fill=\"var(--w-sub,#94a3c0)\"/>\n  <circle class=\"tmln-d3\" cx=\"40\" cy=\"116\" r=\"6\" fill=\"var(--w-sub,#94a3c0)\"/>\n  <rect x=\"60\" y=\"26\" width=\"150\" height=\"16\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".2\"/>\n  <rect x=\"60\" y=\"67\" width=\"130\" height=\"16\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".2\"/>\n  <rect x=\"60\" y=\"108\" width=\"140\" height=\"16\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".2\"/>\n</svg>",
   "useFor": [
    "slide",
    "lp"
   ],
   "weight": "脇役",
   "relatedIds": [
    "stepper",
    "star-rating",
    "logo-marquee",
    "field-sizing"
   ]
  },
  {
   "id": "stepper",
   "num": "W-151",
   "name": "Stepper",
   "nameJa": "ステッパー",
   "category": "component",
   "description": "「1→2→3」のように現在位置を丸数字と接続線で示すナビゲーション。完了ステップは塗り、現在地は強調色、未到達はグレーにして差をつける。",
   "useCase": "フォーム入力・購入手続き・申込フローなど複数画面をまたぐ手続きで、残りの工程数を可視化したいときに使う。",
   "code": "<ol class=\"stepper\">\n  <li class=\"done\">1</li><li class=\"active\">2</li><li>3</li>\n</ol>\n<style>\n.stepper{display:flex;list-style:none;padding:0}\n.stepper li{position:relative;display:flex;align-items:center;justify-content:center;\n  width:32px;height:32px;border-radius:50%;background:#cbd5e1;color:#fff}\n.stepper li:not(:last-child)::after{content:\"\";position:absolute;left:100%;top:50%;\n  width:40px;height:2px;background:#cbd5e1;transform:translateY(-50%)}\n.stepper li.done{background:#4fe3c1}\n.stepper li.done:not(:last-child)::after{background:#4fe3c1}\n.stepper li.active{background:#4fe3c1;box-shadow:0 0 0 3px #c7f3e8}\n</style>",
   "tags": [
    "CSS",
    "ステップ",
    "フォーム",
    "進行状況",
    "分かりやすさ",
    "達成感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ステッパーのデモ\">\n  <style>\n    .step-c2{animation:step-c2 3.6s ease-in-out infinite}\n    .step-c3{animation:step-c3 3.6s ease-in-out infinite}\n    @keyframes step-c2{0%,25%{fill:var(--w-sub,#94a3c0)}40%,90%{fill:var(--w-accent,#4fe3c1)}100%{fill:var(--w-sub,#94a3c0)}}\n    @keyframes step-c3{0%,60%{fill:var(--w-sub,#94a3c0)}75%,100%{fill:var(--w-accent,#4fe3c1)}}\n    .step-l1{animation:step-l1 3.6s ease-in-out infinite;transform-origin:70px 75px}\n    .step-l2{animation:step-l2 3.6s ease-in-out infinite;transform-origin:140px 75px}\n    @keyframes step-l1{0%,25%{transform:scaleX(0)}40%,100%{transform:scaleX(1)}}\n    @keyframes step-l2{0%,60%{transform:scaleX(0)}75%,100%{transform:scaleX(1)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <line class=\"step-l1\" x1=\"55\" y1=\"75\" x2=\"85\" y2=\"75\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"3\"/>\n  <line class=\"step-l2\" x1=\"125\" y1=\"75\" x2=\"155\" y2=\"75\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"3\"/>\n  <circle cx=\"40\" cy=\"75\" r=\"15\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <circle class=\"step-c2\" cx=\"120\" cy=\"75\" r=\"15\" fill=\"var(--w-sub,#94a3c0)\"/>\n  <circle class=\"step-c3\" cx=\"200\" cy=\"75\" r=\"15\" fill=\"var(--w-sub,#94a3c0)\"/>\n  <text x=\"40\" y=\"80\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"12\" fill=\"var(--w-bg,#101830)\">1</text>\n  <text x=\"120\" y=\"80\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"12\" fill=\"var(--w-bg,#101830)\">2</text>\n  <text x=\"200\" y=\"80\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"12\" fill=\"var(--w-bg,#101830)\">3</text>\n</svg>",
   "useFor": [
    "site",
    "lp"
   ],
   "weight": "脇役",
   "relatedIds": [
    "field-sizing",
    "timeline",
    "star-rating",
    "customizable-select"
   ]
  },
  {
   "id": "carousel-scroll-snap",
   "num": "W-152",
   "name": "Scroll-Snap Carousel",
   "nameJa": "カルーセル（scroll-snap製）",
   "category": "component",
   "description": "JS不要でスクロールが各カードにピタッと止まるカルーセル。親要素にoverflow-x:autoとscroll-snap-type:x mandatory、子要素にscroll-snap-align:centerを指定する。",
   "useCase": "商品一覧・お客様の声・実績写真をスワイプや横スクロールで1枚ずつ気持ちよく見せたいときに使う。",
   "code": ".carousel{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;gap:16px}\n.carousel > *{scroll-snap-align:center;flex:0 0 80%}",
   "tags": [
    "CSS",
    "スクロール",
    "カルーセル",
    "吸着",
    "ぬるっと",
    "気持ちいい"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"カルーセル(scroll-snap製)のデモ\">\n  <style>\n    .csnp-track{animation:csnp-move 4.5s cubic-bezier(.7,0,.2,1) infinite}\n    @keyframes csnp-move{0%,26%{transform:translateX(0)}36%,62%{transform:translateX(-80px)}72%,96%{transform:translateX(-160px)}100%{transform:translateX(0)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"csnp-track\">\n    <rect x=\"24\" y=\"32\" width=\"64\" height=\"86\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".9\"/>\n    <rect x=\"104\" y=\"32\" width=\"64\" height=\"86\" rx=\"6\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".55\"/>\n    <rect x=\"184\" y=\"32\" width=\"64\" height=\"86\" rx=\"6\" fill=\"var(--w-amber,#ffc857)\" opacity=\".8\"/>\n  </g>\n  <rect x=\"104\" y=\"126\" width=\"32\" height=\"4\" rx=\"2\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".35\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "scroll-snap",
    "smooth-scroll",
    "scroll-driven-animation",
    "scroll-text-highlight"
   ]
  },
  {
   "id": "lightbox-dialog",
   "num": "W-153",
   "name": "Lightbox (native <dialog>)",
   "nameJa": "ライトボックス（dialog製）",
   "category": "component",
   "description": "画像やコンテンツをクリックするとパッと画面中央にモーダル表示するUI。ネイティブの<dialog>要素とshowModal()を使い、背景は::backdropで暗転させる。",
   "useCase": "ギャラリーの拡大表示や、フォーム・注意事項をページ遷移せずJS最小限で見せたいときに使う。",
   "code": "<dialog id=\"lb\"><img src=\"big.jpg\"><button onclick=\"lb.close()\">×</button></dialog>\n<img src=\"thumb.jpg\" onclick=\"lb.showModal()\">\ndialog::backdrop{background:rgba(0,0,0,.6)}\ndialog{border:none;border-radius:12px;animation:lb-in .2s ease}\n@keyframes lb-in{from{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}",
   "tags": [
    "HTML",
    "dialog",
    "モーダル",
    "ギャラリー",
    "パッと切替",
    "没入感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ライトボックス(dialog製)のデモ\">\n  <style>\n    .lbdg-back{animation:lbdg-back 3.4s ease-in-out infinite}\n    @keyframes lbdg-back{0%,18%{opacity:0}30%,80%{opacity:.65}95%,100%{opacity:0}}\n    .lbdg-modal{animation:lbdg-modal 3.4s ease-in-out infinite;transform-origin:120px 75px}\n    @keyframes lbdg-modal{0%,18%{transform:scale(.7);opacity:0}30%,80%{transform:scale(1);opacity:1}95%,100%{transform:scale(.7);opacity:0}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"24\" y=\"24\" width=\"50\" height=\"36\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/>\n  <rect class=\"lbdg-back\" x=\"0\" y=\"0\" width=\"240\" height=\"150\" fill=\"var(--w-bg,#101830)\" opacity=\".65\"/>\n  <g class=\"lbdg-modal\">\n    <rect x=\"65\" y=\"35\" width=\"110\" height=\"80\" rx=\"10\" fill=\"var(--w-ink,#e8eef9)\"/>\n    <rect x=\"80\" y=\"50\" width=\"80\" height=\"40\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".5\"/>\n    <circle cx=\"160\" cy=\"46\" r=\"7\" fill=\"var(--w-bg,#101830)\" opacity=\".7\"/>\n    <path d=\"M157 43 l6 6 M163 43 l-6 6\" stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"1.3\"/>\n  </g>\n</svg>",
   "useFor": [
    "site",
    "lp"
   ],
   "weight": "脇役",
   "relatedIds": [
    "lightbox-gallery",
    "dialog-closedby",
    "dialog-modal",
    "command-palette"
   ]
  },
  {
   "id": "star-rating",
   "num": "W-154",
   "name": "Star Rating",
   "nameJa": "星評価",
   "category": "component",
   "description": "星アイコンを評価分だけじわっと塗りつぶして表示するUI。灰色の星の上に色つきの星をclip-pathで重ね、幅を評価値に応じて変えて部分塗りを再現する。",
   "useCase": "レビュー・口コミの評価表示や、フォームでユーザーに星をつけて評価してもらう入力UIで使う。",
   "code": ".stars{--rating:3.5;--stars:5;position:relative;display:inline-block;color:#cbd5e1}\n.stars::after{content:'★★★★★';position:absolute;inset:0;color:#ffc857;\n  clip-path:inset(0 calc(100% - (var(--rating)/var(--stars)*100%)) 0 0)}",
   "tags": [
    "CSS",
    "評価",
    "clip-path",
    "レビュー",
    "分かりやすさ",
    "じわっと"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"星評価のデモ\">\n  <defs>\n    <clipPath id=\"strt-clip\"><rect class=\"strt-fill\" x=\"0\" y=\"0\" width=\"0\" height=\"40\"/></clipPath>\n  </defs>\n  <style>\n    .strt-fill{animation:strt-w 3.5s ease-in-out infinite}\n    @keyframes strt-w{0%,10%{width:0}60%,90%{width:105px}100%{width:0}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g transform=\"translate(35,55)\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"30\">\n    <text x=\"0\" y=\"30\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".4\">★★★★★</text>\n    <text x=\"0\" y=\"30\" fill=\"var(--w-amber,#ffc857)\" clip-path=\"url(#strt-clip)\">★★★★★</text>\n  </g>\n  <text x=\"120\" y=\"112\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"12\" fill=\"var(--w-ink,#e8eef9)\">4.2 / 5</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "image-clip-reveal",
    "before-after-slider",
    "timeline",
    "stepper"
   ]
  },
  {
   "id": "flip-clock-countdown",
   "num": "W-155",
   "name": "Flip Clock Countdown",
   "nameJa": "フリップ時計カウントダウン",
   "category": "component",
   "description": "数字カードがぱたんと上下に割れてめくれ、次の数字に切り替わるカウントダウン表示。2枚の半分カードにtransform: rotateXを適用し、境目で数字を切り替える。",
   "useCase": "セール終了・イベント開始までの残り時間を、LPやキャンペーンページで緊張感をもって見せたいときに使う。",
   "code": ".flip-card{perspective:200px}\n.flip-top{transform-origin:bottom;animation:flip .6s ease-in forwards}\n@keyframes flip{to{transform:rotateX(-90deg)}}",
   "tags": [
    "CSS",
    "3D変形",
    "カウントダウン",
    "フリップ",
    "パッと切替",
    "緊張感",
    "キャンペーン"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"フリップ時計カウントダウンのデモ\">\n  <defs>\n    <clipPath id=\"flpc-top\"><rect x=\"80\" y=\"35\" width=\"80\" height=\"35\"/></clipPath>\n  </defs>\n  <style>\n    .flpc-top{animation:flpc-flip 2s ease-in infinite;transform-origin:120px 70px}\n    @keyframes flpc-flip{0%,40%{transform:scaleY(1)}55%{transform:scaleY(0)}70%,100%{transform:scaleY(1)}}\n    .flpc-new{animation:flpc-show 2s steps(1) infinite}\n    @keyframes flpc-show{0%,54%{opacity:0}55%,100%{opacity:1}}\n    .flpc-old{animation:flpc-hide 2s steps(1) infinite}\n    @keyframes flpc-hide{0%,54%{opacity:1}55%,100%{opacity:0}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"80\" y=\"35\" width=\"80\" height=\"70\" rx=\"8\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".2\"/>\n  <line x1=\"80\" y1=\"70\" x2=\"160\" y2=\"70\" stroke=\"var(--w-bg,#101830)\" stroke-width=\"2\"/>\n  <g class=\"flpc-old\"><text x=\"120\" y=\"90\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"40\" fill=\"var(--w-ink,#e8eef9)\">5</text></g>\n  <g class=\"flpc-new\"><text x=\"120\" y=\"90\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"40\" fill=\"var(--w-ink,#e8eef9)\">4</text></g>\n  <g clip-path=\"url(#flpc-top)\" class=\"flpc-top\">\n    <rect x=\"80\" y=\"35\" width=\"80\" height=\"35\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".35\"/>\n    <text x=\"120\" y=\"90\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"40\" fill=\"var(--w-ink,#e8eef9)\">5</text>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "toast-notification",
    "ripple-effect",
    "target-css-toggle",
    "card-flip"
   ]
  },
  {
   "id": "cta-pulse-button",
   "num": "W-156",
   "name": "Pulsing CTA Button",
   "nameJa": "CTAボタンの脈動",
   "category": "component",
   "description": "ボタンの外側にリング状の影がじわっと拡大しながら透明になるのを繰り返し、心臓の鼓動のように視線を引きつける。box-shadowか擬似要素のscaleをkeyframesでループさせる。",
   "useCase": "申込・購入・予約など「今すぐ押してほしい」最重要ボタンを、他の要素より目立たせたいときに使う。",
   "code": ".cta{position:relative;animation:pulse 1.8s ease-out infinite}\n@keyframes pulse{\n  0%{box-shadow:0 0 0 0 rgba(79,227,193,.5)}\n  100%{box-shadow:0 0 0 20px rgba(79,227,193,0)}\n}",
   "tags": [
    "CSS",
    "ボタン",
    "CTA",
    "目を引く",
    "ダイナミック",
    "脈動"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"CTAボタンの脈動のデモ\">\n  <style>\n    .ctap-ring{animation:ctap-pulse 1.8s ease-out infinite;transform-origin:0 0}\n    @keyframes ctap-pulse{0%{transform:scale(1);opacity:.6}100%{transform:scale(2.1);opacity:0}}\n    .ctap-ring2{animation:ctap-pulse 1.8s ease-out infinite;animation-delay:.6s;transform-origin:0 0}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g transform=\"translate(120,75)\">\n    <circle class=\"ctap-ring\" r=\"34\" fill=\"none\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"3\"/>\n    <circle class=\"ctap-ring2\" r=\"34\" fill=\"none\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"3\"/>\n    <rect x=\"-46\" y=\"-18\" width=\"92\" height=\"36\" rx=\"18\" fill=\"var(--w-accent,#4fe3c1)\"/>\n    <text x=\"0\" y=\"5\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"13\" fill=\"var(--w-bg,#101830)\">今すぐ申込む</text>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "text-stroke-outline",
    "neon-glow-text",
    "blend-difference-text",
    "keyframes-multistep"
   ]
  },
  {
   "id": "back-to-top",
   "num": "W-157",
   "name": "Back to Top Button",
   "nameJa": "戻るトップボタン",
   "category": "component",
   "description": "一定量スクロールすると画面右下にすっと現れ、クリックでページ最上部へ滑らかに戻る丸ボタン。表示はscroll判定でopacity切替、移動はscroll-behavior:smoothで実現する。",
   "useCase": "長い記事・LPを読み終えたユーザーが迷わず最初に戻れるようにしたい、縦に長いページで使う。",
   "code": ".back-top{position:fixed;right:20px;bottom:20px;opacity:0;\n  transition:opacity .25s ease}\n.back-top.show{opacity:1}\nhtml{scroll-behavior:smooth}\nconst btn=document.querySelector('.back-top');\naddEventListener('scroll',()=>btn.classList.toggle('show',scrollY>400));",
   "tags": [
    "CSS",
    "スクロール",
    "ボタン",
    "導線",
    "さりげない",
    "すっきり"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"戻るトップボタンのデモ\">\n  <style>\n    .bktp-page{animation:bktp-scroll 3.6s ease-in-out infinite}\n    @keyframes bktp-scroll{0%,10%{transform:translateY(0)}45%,65%{transform:translateY(-40px)}100%{transform:translateY(0)}}\n    .bktp-btn{animation:bktp-show 3.6s ease-in-out infinite}\n    @keyframes bktp-show{0%,14%{opacity:0}22%,60%{opacity:1}70%,100%{opacity:0}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"bktp-page\">\n    <rect x=\"20\" y=\"18\" width=\"140\" height=\"10\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".35\"/>\n    <rect x=\"20\" y=\"36\" width=\"180\" height=\"10\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".25\"/>\n    <rect x=\"20\" y=\"54\" width=\"160\" height=\"10\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".25\"/>\n    <rect x=\"20\" y=\"72\" width=\"170\" height=\"10\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".25\"/>\n    <rect x=\"20\" y=\"90\" width=\"150\" height=\"10\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".25\"/>\n  </g>\n  <g class=\"bktp-btn\" transform=\"translate(202,118)\">\n    <circle r=\"16\" fill=\"var(--w-accent,#4fe3c1)\"/>\n    <path d=\"M-6 4 l6 -8 l6 8\" stroke=\"var(--w-bg,#101830)\" stroke-width=\"2.4\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "sticky-position",
    "sticky-header-shrink",
    "overscroll-behavior",
    "scroll-margin-padding"
   ]
  },
  {
   "id": "loading-spinner",
   "num": "W-158",
   "name": "Loading Spinner",
   "nameJa": "ローディングスピナー各種",
   "category": "component",
   "description": "読み込み待ちをぐるぐる回転や明滅で示すインジケーター群。円弧の一部だけ色を変えてrotateさせる定番タイプから、ドットが順番に明滅するタイプまで実装パターンがある。",
   "useCase": "ボタン押下後の通信待ちや、ページ全体のローディング画面など、待ち時間の長さが読めない場面で使う。",
   "code": ".spinner{width:32px;height:32px;border:4px solid #e2e8f0;\n  border-top-color:#4fe3c1;border-radius:50%;\n  animation:spin .8s linear infinite}\n@keyframes spin{to{transform:rotate(360deg)}}",
   "tags": [
    "CSS",
    "ローディング",
    "回転",
    "定番",
    "待機体感",
    "ぐるっと"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ローディングスピナー各種のデモ\">\n  <style>\n    .lspn-ring{animation:lspn-spin 1s linear infinite;transform-origin:70px 75px}\n    @keyframes lspn-spin{to{transform:rotate(360deg)}}\n    .lspn-d1{animation:lspn-blink 1.2s ease-in-out infinite}\n    .lspn-d2{animation:lspn-blink 1.2s ease-in-out infinite;animation-delay:.2s}\n    .lspn-d3{animation:lspn-blink 1.2s ease-in-out infinite;animation-delay:.4s}\n    @keyframes lspn-blink{0%,100%{opacity:.25}50%{opacity:1}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <circle cx=\"70\" cy=\"75\" r=\"26\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-width=\"6\" opacity=\".25\"/>\n  <path class=\"lspn-ring\" d=\"M70 49 a26 26 0 0 1 26 26\" fill=\"none\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"6\" stroke-linecap=\"round\"/>\n  <circle class=\"lspn-d1\" cx=\"150\" cy=\"75\" r=\"7\" fill=\"var(--w-ink,#e8eef9)\"/>\n  <circle class=\"lspn-d2\" cx=\"172\" cy=\"75\" r=\"7\" fill=\"var(--w-ink,#e8eef9)\"/>\n  <circle class=\"lspn-d3\" cx=\"194\" cy=\"75\" r=\"7\" fill=\"var(--w-ink,#e8eef9)\"/>\n</svg>",
   "useFor": [
    "site",
    "lp"
   ],
   "weight": "脇役",
   "relatedIds": [
    "skeleton-shimmer",
    "smooth-scroll",
    "cube-3d",
    "ring-gallery"
   ]
  },
  {
   "id": "stroke-draw",
   "num": "W-159",
   "name": "Line Drawing Animation",
   "nameJa": "線画が描かれる",
   "category": "svgfx",
   "description": "パスがまるで手描きされるように少しずつ現れる表現。stroke-dasharrayでパス全長分の破線を作り、stroke-dashoffsetを長さ分から0までアニメーションさせて描画過程を再現する。",
   "useCase": "ロゴやアイコンの登場演出、LPのプロセス図や矢印の強調、スライドの図解アニメに使う。",
   "code": ".sdraw-line{\n  stroke-dasharray: 240;\n  stroke-dashoffset: 240;\n  animation: sdraw-go 2.4s ease-in-out infinite;\n}\n@keyframes sdraw-go{\n  0%{stroke-dashoffset:240}\n  55%,70%{stroke-dashoffset:0}\n  100%{stroke-dashoffset:-240}\n}",
   "tags": [
    "SVG",
    "ストローク",
    "線画",
    "描画アニメ",
    "ロゴ",
    "手描き感",
    "じわじわ"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"線画が描かれるのデモ\"><style>.sdraw-line{stroke-dasharray:220;stroke-dashoffset:220;animation:sdraw-go 3s ease-in-out infinite}@keyframes sdraw-go{0%{stroke-dashoffset:220}45%,65%{stroke-dashoffset:0}100%{stroke-dashoffset:-220}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><path class=\"sdraw-line\" d=\"M30,115 C70,40 100,140 130,70 C160,10 190,90 210,45\" fill=\"none\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"5\" stroke-linecap=\"round\"/></svg>",
   "useFor": [
    "slide",
    "lp"
   ],
   "weight": "主役",
   "relatedIds": [
    "svg-pathlength-normalize",
    "svg-vector-effect-stroke",
    "checkmark-draw",
    "progress-ring"
   ]
  },
  {
   "id": "path-morph",
   "num": "W-160",
   "name": "Path Morphing",
   "nameJa": "パスモーフィング",
   "category": "svgfx",
   "description": "図形の輪郭(d属性)を別の形へなめらかに変形させる表現。SMILの<animate attributeName=\"d\">で頂点数と命令の並びを揃えた複数のパスデータ間を補間する。",
   "useCase": "アイコンが別アイコンへ切り替わる演出、ボタンの状態変化、抽象図形の背景アクセントに使う。",
   "code": "<path fill=\"#4fe3c1\">\n  <animate attributeName=\"d\" dur=\"4s\"\n    repeatCount=\"indefinite\"\n    values=\"M.. square-path ..Z;\n            M.. circle-path ..Z;\n            M.. square-path ..Z\"/>\n</path>",
   "tags": [
    "SVG",
    "SMIL",
    "モーフィング",
    "アイコン切替",
    "変形",
    "ぬるっと",
    "有機的"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"パスモーフィングのデモ\"><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><path fill=\"var(--w-accent,#4fe3c1)\"><animate attributeName=\"d\" dur=\"3.6s\" repeatCount=\"indefinite\" values=\"M85,45 C110,35 130,35 155,45 C165,60 165,90 155,105 C130,115 110,115 85,105 C75,90 75,60 85,45 Z;M80,75 C80,50 100,35 120,35 C150,35 160,55 160,75 C160,100 145,115 120,115 C95,115 80,100 80,75 Z;M85,45 C110,35 130,35 155,45 C165,60 165,90 155,105 C130,115 110,115 85,105 C75,90 75,60 85,45 Z\"/></path></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "blob-morph",
    "smil-animate-basic",
    "smil-animatetransform",
    "smil-animatemotion-mpath"
   ]
  },
  {
   "id": "goo-effect",
   "num": "W-161",
   "name": "Goo / Metaball Effect",
   "nameJa": "グーイー効果（メタボール）",
   "category": "svgfx",
   "description": "複数の図形が近づくと融合して見える液状の表現。feGaussianBlurでぼかした後、feColorMatrixのアルファ値を強調して輪郭を再びシャープにし一体化させる。",
   "useCase": "ボタンホバーの吸着演出、ローディングインジケーター、有機的なブロブ背景のアクセントに使う。",
   "code": "<filter id=\"goo\">\n  <feGaussianBlur stdDeviation=\"8\" result=\"blur\"/>\n  <feColorMatrix in=\"blur\" type=\"matrix\"\n    values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 24 -10\"\n    result=\"goo\"/>\n  <feComposite in=\"SourceGraphic\" in2=\"goo\" operator=\"atop\"/>\n</filter>\n<g filter=\"url(#goo)\">…circles…</g>",
   "tags": [
    "SVG",
    "フィルター",
    "メタボール",
    "液体感",
    "ホバー",
    "ぬるっと",
    "一体感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"グーイー効果のデモ\"><defs><filter id=\"gooeff-filter\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\"><feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"8\" result=\"gooeff-blur\"/><feColorMatrix in=\"gooeff-blur\" mode=\"matrix\" values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 24 -10\" result=\"gooeff-goo\"/><feComposite in=\"SourceGraphic\" in2=\"gooeff-goo\" operator=\"atop\"/></filter></defs><style>.gooeff-a{animation:gooeff-move 3.2s ease-in-out infinite}@keyframes gooeff-move{0%,100%{transform:translateX(0)}50%{transform:translateX(38px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g filter=\"url(#gooeff-filter)\"><circle cx=\"90\" cy=\"75\" r=\"26\" fill=\"var(--w-accent,#4fe3c1)\"/><circle class=\"gooeff-a\" cx=\"150\" cy=\"75\" r=\"26\" fill=\"var(--w-accent,#4fe3c1)\"/></g></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "displacement-map",
    "drop-shadow-filter",
    "fe-colormatrix-huerotate",
    "fe-componenttransfer-posterize"
   ]
  },
  {
   "id": "turbulence-wobble",
   "num": "W-162",
   "name": "Turbulence Wobble",
   "nameJa": "ノイズのゆらぎ（feTurbulence）",
   "category": "svgfx",
   "description": "輪郭や塗りがゆらゆら揺れる有機的なノイズ表現。feTurbulenceでフラクタルノイズを生成し、baseFrequencyをアニメーションさせて連続的な揺らぎを作る。",
   "useCase": "水面や炎のような背景演出、見出し文字の揺らぎ、エネルギー感のあるローディング表現に使う。",
   "code": "<filter id=\"wobble\">\n  <feTurbulence type=\"fractalNoise\"\n    baseFrequency=\"0.02 0.06\" numOctaves=\"2\">\n    <animate attributeName=\"baseFrequency\"\n      dur=\"4s\" values=\"0.02 0.06;0.05 0.09;0.02 0.06\"\n      repeatCount=\"indefinite\"/>\n  </feTurbulence>\n  <feDisplacementMap in=\"SourceGraphic\" scale=\"14\"/>\n</filter>",
   "tags": [
    "SVG",
    "フィルター",
    "ノイズ",
    "ゆらぎ",
    "水面",
    "ダイナミック",
    "有機的"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ノイズのゆらぎのデモ\"><defs><filter id=\"twob-filter\" x=\"-20%\" y=\"-20%\" width=\"140%\" height=\"140%\"><feTurbulence type=\"fractalNoise\" baseFrequency=\"0.02 0.08\" numOctaves=\"2\" seed=\"4\" result=\"twob-noise\"><animate attributeName=\"baseFrequency\" dur=\"4.5s\" values=\"0.02 0.08;0.06 0.1;0.02 0.08\" repeatCount=\"indefinite\"/></feTurbulence><feDisplacementMap in=\"SourceGraphic\" in2=\"twob-noise\" scale=\"16\"/></filter></defs><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><circle cx=\"120\" cy=\"75\" r=\"46\" fill=\"var(--w-accent,#4fe3c1)\" filter=\"url(#twob-filter)\"/></svg>",
   "useFor": [
    "lp",
    "slide"
   ],
   "weight": "主役",
   "relatedIds": [
    "displacement-map",
    "fe-colormatrix-huerotate",
    "fe-componenttransfer-posterize",
    "fe-morphology-outline"
   ]
  },
  {
   "id": "displacement-map",
   "num": "W-163",
   "name": "Displacement Map",
   "nameJa": "変位マップ（feDisplacementMap）",
   "category": "svgfx",
   "description": "別レイヤーの明暗を歪みの強さに変換し、元図形を波打たせる表現。feDisplacementMapのinとin2にソースとマップを指定し、scaleの値で歪みの強度を変化させる。",
   "useCase": "見出しの液体感演出、ガラス越しのような屈折表現、画像やロゴの溶けるトランジションに使う。",
   "code": "<filter id=\"disp\">\n  <feTurbulence type=\"turbulence\"\n    baseFrequency=\"0.01 0.04\" numOctaves=\"2\" result=\"map\"/>\n  <feDisplacementMap in=\"SourceGraphic\" in2=\"map\"\n    xChannelSelector=\"R\" yChannelSelector=\"G\">\n    <animate attributeName=\"scale\" values=\"0;40;0\"\n      dur=\"3s\" repeatCount=\"indefinite\"/>\n  </feDisplacementMap>\n</filter>",
   "tags": [
    "SVG",
    "フィルター",
    "歪み",
    "変位",
    "ダイナミック",
    "液体感",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"変位マップのデモ\"><defs><filter id=\"dispm-filter\" x=\"-20%\" y=\"-20%\" width=\"140%\" height=\"140%\"><feTurbulence type=\"turbulence\" baseFrequency=\"0.015 0.05\" numOctaves=\"2\" seed=\"7\" result=\"dispm-map\"/><feDisplacementMap in=\"SourceGraphic\" in2=\"dispm-map\" xChannelSelector=\"R\" yChannelSelector=\"G\"><animate attributeName=\"scale\" values=\"0;36;0\" dur=\"3.4s\" repeatCount=\"indefinite\"/></feDisplacementMap></filter></defs><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g filter=\"url(#dispm-filter)\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"2\" fill=\"none\"><line x1=\"20\" y1=\"35\" x2=\"220\" y2=\"35\"/><line x1=\"20\" y1=\"60\" x2=\"220\" y2=\"60\"/><line x1=\"20\" y1=\"85\" x2=\"220\" y2=\"85\"/><line x1=\"20\" y1=\"110\" x2=\"220\" y2=\"110\"/></g></svg>",
   "useFor": [
    "lp",
    "slide"
   ],
   "weight": "主役",
   "relatedIds": [
    "goo-effect",
    "turbulence-wobble",
    "fe-colormatrix-huerotate",
    "fe-componenttransfer-posterize"
   ]
  },
  {
   "id": "text-on-path",
   "num": "W-164",
   "name": "Text on Path",
   "nameJa": "パスに沿う文字",
   "category": "svgfx",
   "description": "文字列を直線ではなく任意の曲線に沿って配置し流す表現。<textPath href=\"#path\">でパスを参照し、startOffsetをアニメーションさせて文字を巡回させる。",
   "useCase": "円形バッジのロゴ文言、装飾的な見出し、スクロール誘導ラベルの演出に使う。",
   "code": "<path id=\"curve\" d=\"M20,110 Q120,10 220,110\" fill=\"none\"/>\n<text font-size=\"12\" fill=\"#e8eef9\">\n  <textPath href=\"#curve\" startOffset=\"0%\">\n    <animate attributeName=\"startOffset\"\n      values=\"0%;100%\" dur=\"5s\" repeatCount=\"indefinite\"/>\n    SCROLL DOWN • SCROLL DOWN •\n  </textPath>\n</text>",
   "tags": [
    "SVG",
    "テキスト",
    "パス装飾",
    "循環",
    "バッジ",
    "さりげない",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"パスに沿う文字のデモ\"><defs><path id=\"tonp-curve\" d=\"M14 112 Q120 8 226 112\" fill=\"none\"/></defs><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><path d=\"M14 112 Q120 8 226 112\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\" opacity=\".45\"/><text font-size=\"15\" font-weight=\"700\" font-family=\"ui-sans-serif,system-ui,sans-serif\" fill=\"var(--w-accent,#4fe3c1)\"><textPath href=\"#tonp-curve\" startOffset=\"0%\"><animate attributeName=\"startOffset\" values=\"0%;55%;0%\" dur=\"6s\" repeatCount=\"indefinite\"/>SCROLL • FOLLOW THE PATH •</textPath></text><text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"9\" fill=\"var(--w-sub,#a7b4cd)\">textPath + startOffset</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "animated-favicon",
    "svg-text-mask",
    "svg-paint-order-outline",
    "displacement-map"
   ]
  },
  {
   "id": "mask-reveal",
   "num": "W-165",
   "name": "Mask Reveal",
   "nameJa": "マスクによるリビール",
   "category": "svgfx",
   "description": "maskで隠した要素を徐々に見せる表現。<mask>内の白い図形やグラデーションを動かし、見える範囲が広がることで画像や見出しが現れて見える。",
   "useCase": "画像や見出しの登場演出、スクロール連動の切り替え、ビフォーアフター表現に使う。",
   "code": "<mask id=\"reveal\">\n  <rect width=\"0\" height=\"150\" fill=\"#fff\">\n    <animate attributeName=\"width\"\n      values=\"0;240;0\" dur=\"4s\" repeatCount=\"indefinite\"/>\n  </rect>\n</mask>\n<g mask=\"url(#reveal)\">…contents…</g>",
   "tags": [
    "SVG",
    "マスク",
    "リビール",
    "登場演出",
    "スクロール連動",
    "じわっと",
    "高級感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"マスクによるリビールのデモ\"><defs><mask id=\"mrvl-mask\" maskUnits=\"userSpaceOnUse\" x=\"0\" y=\"0\" width=\"240\" height=\"150\"><rect y=\"0\" width=\"0\" height=\"150\" fill=\"var(--w-ink,#e8eef9)\"><animate attributeName=\"width\" values=\"0;240;240;0\" keyTimes=\"0;0.45;0.8;1\" dur=\"4s\" repeatCount=\"indefinite\"/></rect></mask></defs><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g mask=\"url(#mrvl-mask)\"><rect x=\"20\" y=\"30\" width=\"200\" height=\"90\" rx=\"8\" fill=\"var(--w-accent,#4fe3c1)\"/><text x=\"40\" y=\"82\" font-size=\"14\" font-family=\"ui-sans-serif,system-ui,sans-serif\" fill=\"var(--w-bg,#101830)\">REVEAL</text></g></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "svg-clip-path",
    "svg-mask-type",
    "gradient-animate",
    "drop-shadow-filter"
   ]
  },
  {
   "id": "gradient-animate",
   "num": "W-166",
   "name": "Animated Gradient",
   "nameJa": "グラデーションアニメーション",
   "category": "svgfx",
   "description": "linearGradient内のstop-colorや位置を動かし、塗りの色や角度が滑らかに移り変わる表現。各<stop>にCSSアニメーションを適用してstop-colorを時間差で変化させる。",
   "useCase": "ボタンやバッジ背景の高級感演出、見出しのアクセント帯、ローディングバーの質感づけに使う。",
   "code": "<linearGradient id=\"g\" x1=\"0%\" x2=\"100%\">\n  <stop class=\"s1\" offset=\"0%\"/>\n  <stop class=\"s2\" offset=\"100%\"/>\n</linearGradient>\n<style>\n.s1{animation:c1 4s ease-in-out infinite}\n@keyframes c1{50%{stop-color:#ffc857}}\n</style>",
   "tags": [
    "SVG",
    "グラデーション",
    "色アニメ",
    "背景",
    "ボタン",
    "高級感",
    "なめらか"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"グラデーションアニメーションのデモ\"><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><defs><linearGradient id=\"gani-grad\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\"><stop class=\"gani-s1\" offset=\"0%\"/><stop class=\"gani-s2\" offset=\"50%\"/><stop class=\"gani-s3\" offset=\"100%\"/></linearGradient></defs><style>.gani-s1{animation:gani-c1 4s ease-in-out infinite}.gani-s2{animation:gani-c2 4s ease-in-out infinite}.gani-s3{animation:gani-c3 4s ease-in-out infinite}@keyframes gani-c1{0%,100%{stop-color:var(--w-accent,#4fe3c1)}50%{stop-color:var(--w-amber,#ffc857)}}@keyframes gani-c2{0%,100%{stop-color:var(--w-amber,#ffc857)}50%{stop-color:var(--w-sub,#a7b4cd)}}@keyframes gani-c3{0%,100%{stop-color:var(--w-sub,#a7b4cd)}50%{stop-color:var(--w-accent,#4fe3c1)}}</style><rect x=\"32\" y=\"48\" width=\"176\" height=\"54\" rx=\"27\" fill=\"url(#gani-grad)\"/><text x=\"120\" y=\"130\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"9\" fill=\"var(--w-sub,#a7b4cd)\">3 color stops stay visible</text></svg>",
   "useFor": [
    "lp",
    "slide"
   ],
   "weight": "脇役",
   "relatedIds": [
    "gradient-animation",
    "mesh-gradient",
    "grain-noise",
    "svg-spreadmethod"
   ]
  },
  {
   "id": "checkmark-draw",
   "num": "W-167",
   "name": "Checkmark Draw-in",
   "nameJa": "チェックマークが描かれる",
   "category": "svgfx",
   "description": "レ点やチェックアイコンが1本の線として描かれ、丸で囲われて完了を示す表現。円とチェックのパスそれぞれにstroke-dasharray/dashoffsetを設定し時間差でアニメーションさせる。",
   "useCase": "フォーム送信完了、タスク完了、料金プラン比較表のチェック項目強調に使う。",
   "code": ".circle{stroke-dasharray:170;stroke-dashoffset:170;\n  animation:c 2.6s ease-in-out infinite}\n.check{stroke-dasharray:60;stroke-dashoffset:60;\n  animation:k 2.6s ease-in-out infinite}\n@keyframes c{0%{stroke-dashoffset:170}40%,100%{stroke-dashoffset:0}}\n@keyframes k{0%,45%{stroke-dashoffset:60}70%,100%{stroke-dashoffset:0}}",
   "tags": [
    "SVG",
    "ストローク",
    "チェック",
    "完了演出",
    "フォーム",
    "パッと切替",
    "達成感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"チェックマークが描かれるのデモ\"><style>.cdrw-circle{stroke-dasharray:170;stroke-dashoffset:170;animation:cdrw-c 3.2s ease-in-out infinite}.cdrw-check{stroke-dasharray:62;stroke-dashoffset:62;animation:cdrw-k 3.2s ease-in-out infinite}@keyframes cdrw-c{0%{stroke-dashoffset:170}40%,58%{stroke-dashoffset:0}100%{stroke-dashoffset:-170}}@keyframes cdrw-k{0%,40%{stroke-dashoffset:62}66%,85%{stroke-dashoffset:0}100%{stroke-dashoffset:-62}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><circle class=\"cdrw-circle\" cx=\"120\" cy=\"75\" r=\"27\" fill=\"none\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"5\" stroke-linecap=\"round\"/><path class=\"cdrw-check\" d=\"M105,76 L117,90 L140,60\" fill=\"none\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "svg-vector-effect-stroke",
    "stroke-draw",
    "progress-ring",
    "circular-progress"
   ]
  },
  {
   "id": "progress-ring",
   "num": "W-168",
   "name": "Circular Progress Ring",
   "nameJa": "円形プログレスリング",
   "category": "svgfx",
   "description": "円周に沿ったストロークが割合分だけ伸びる進捗表現。stroke-dasharrayを円周長(2πr)に固定し、stroke-dashoffsetを目標値まで動かして進み具合を表す。",
   "useCase": "ローディング表示、スキルレベルやKPIの割合表示、アップロード進捗のUIに使う。",
   "code": ".ring{\n  stroke-dasharray: 220; /* 2*PI*r */\n  stroke-dashoffset: 220;\n  transform: rotate(-90deg);\n  transform-origin: center;\n  animation: fill 2s ease-in-out forwards;\n}\n@keyframes fill{ to{ stroke-dashoffset: 53 } }",
   "tags": [
    "SVG",
    "プログレス",
    "ストローク",
    "ローディング",
    "KPI表示",
    "さりげない",
    "期待感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"円形プログレスリングのデモ\"><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><style>.pring-bar{stroke-dasharray:220;stroke-dashoffset:220;animation:pring-fill 3.4s ease-in-out infinite;transform-origin:120px 75px;transform:rotate(-90deg)}@keyframes pring-fill{0%{stroke-dashoffset:220}15%,85%{stroke-dashoffset:53}100%{stroke-dashoffset:220}}</style><circle cx=\"120\" cy=\"75\" r=\"35\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-width=\"8\" opacity=\".3\"/><circle class=\"pring-bar\" cx=\"120\" cy=\"75\" r=\"35\" fill=\"none\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"8\" stroke-linecap=\"round\"/><text x=\"120\" y=\"80\" text-anchor=\"middle\" font-size=\"14\" font-family=\"ui-sans-serif,system-ui,sans-serif\" fill=\"var(--w-ink,#e8eef9)\">76%</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "svg-vector-effect-stroke",
    "stroke-draw",
    "text-on-path",
    "checkmark-draw"
   ]
  },
  {
   "id": "blob-morph",
   "num": "W-169",
   "name": "Blob Morph",
   "nameJa": "ブロブモーフィング",
   "category": "svgfx",
   "description": "有機的な不定形の塊が呼吸するように輪郭を変え続ける表現。同じ命令数で揃えた複数のパス形状をSMILの<animate attributeName=\"d\">で行き来させる。",
   "useCase": "LPやスライドの背景装飾、アイコンの台座、セクション区切りのアクセント図形に使う。",
   "code": "<path fill=\"#4fe3c1\" opacity=\".85\">\n  <animate attributeName=\"d\" dur=\"5.5s\"\n    repeatCount=\"indefinite\"\n    values=\"M.. blobA ..Z; M.. blobB ..Z; M.. blobA ..Z\"/>\n</path>",
   "tags": [
    "SVG",
    "モーフィング",
    "ブロブ",
    "背景装飾",
    "アイコン台座",
    "ぬるっと",
    "没入感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ブロブモーフィングのデモ\"><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><path fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\"><animate attributeName=\"d\" dur=\"5.5s\" repeatCount=\"indefinite\" values=\"M120,30 C160,25 190,55 185,85 C180,120 145,130 115,125 C80,120 55,100 60,70 C65,40 90,35 120,30 Z;M120,20 C170,30 175,70 165,95 C150,130 100,135 75,105 C50,80 60,45 90,30 C100,25 110,20 120,20 Z;M120,30 C160,25 190,55 185,85 C180,120 145,130 115,125 C80,120 55,100 60,70 C65,40 90,35 120,30 Z\"/></path></svg>",
   "useFor": [
    "lp",
    "slide"
   ],
   "weight": "主役",
   "relatedIds": [
    "path-morph",
    "lava-blob",
    "goo-effect",
    "viewbox-camera"
   ]
  },
  {
   "id": "symbol-sprite",
   "num": "W-170",
   "name": "Symbol + Use Sprite",
   "nameJa": "symbol+useのアイコンスプライト",
   "category": "svgfx",
   "description": "<symbol>で図形を一度だけ定義し、複数の<use href>で使い回して差し替え・一括色変更を可能にする実装パターン。呼び出し側でx/y/widthや色だけを変えて再利用する。",
   "useCase": "アイコンセットの統一管理、ダークモード切替時の一括色変更、ページ読み込みの軽量化に使う。",
   "code": "<symbol id=\"star\" viewBox=\"0 0 24 24\">\n  <path d=\"M12,2 L14.6,9 L22,9 L16,13.5 L18,21 L12,16.5 L6,21 L8,13.5 L2,9 L9.4,9 Z\"/>\n</symbol>\n<use href=\"#star\" x=\"10\" y=\"10\" width=\"24\" height=\"24\" fill=\"#4fe3c1\"/>\n<use href=\"#star\" x=\"50\" y=\"10\" width=\"24\" height=\"24\" fill=\"#ffc857\"/>",
   "tags": [
    "SVG",
    "アイコン",
    "スプライト",
    "再利用",
    "実装効率",
    "統一感",
    "整然とした"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"symbolとuseのアイコンスプライトのデモ\"><defs><symbol id=\"ssp-star\" viewBox=\"0 0 24 24\"><path d=\"M12 1l2.7 7.6h8.1l-6.6 4.8 2.3 7.6-6.5-4.7L5.5 21l2.3-7.6-6.6-4.8h8.1Z\"/></symbol></defs><style>.ssp-u{animation:ssp-pop 3.6s ease-in-out infinite;transform-box:fill-box;transform-origin:center}.ssp-u2{animation-delay:.25s}.ssp-u3{animation-delay:.5s}@keyframes ssp-pop{0%,15%{opacity:.25;transform:scale(.72)}35%,78%{opacity:1;transform:scale(1)}100%{opacity:.25;transform:scale(.72)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><use class=\"ssp-u\" href=\"#ssp-star\" x=\"30\" y=\"48\" width=\"44\" height=\"44\" fill=\"var(--w-accent,#4fe3c1)\"/><use class=\"ssp-u ssp-u2\" href=\"#ssp-star\" x=\"98\" y=\"48\" width=\"44\" height=\"44\" fill=\"var(--w-amber,#ffc857)\"/><use class=\"ssp-u ssp-u3\" href=\"#ssp-star\" x=\"166\" y=\"48\" width=\"44\" height=\"44\" fill=\"var(--w-ink,#e8eef9)\"/><text x=\"120\" y=\"125\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"9\" fill=\"var(--w-sub,#a7b4cd)\">one symbol  →  three uses</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "svg-paint-order-outline",
    "fe-colormatrix-huerotate",
    "fe-componenttransfer-posterize",
    "fe-morphology-outline"
   ]
  },
  {
   "id": "svg-pattern-bg",
   "num": "W-171",
   "name": "SVG Pattern Background",
   "nameJa": "SVGパターン背景",
   "category": "svgfx",
   "description": "<pattern>要素で小さな図形タイルを定義し、fill=\"url(#id)\"で敷き詰めて背景を作る表現。patternTransformをアニメーションさせるとタイルが流れる背景になる。",
   "useCase": "セクション背景のテクスチャ、ドットやグリッドの装飾背景、ヒーローエリアの奥行き演出に使う。",
   "code": "<pattern id=\"dots\" width=\"20\" height=\"20\"\n  patternUnits=\"userSpaceOnUse\">\n  <circle cx=\"3\" cy=\"3\" r=\"2\" fill=\"#94a3c0\"/>\n  <animateTransform attributeName=\"patternTransform\"\n    type=\"translate\" values=\"0 0;20 20\"\n    dur=\"3s\" repeatCount=\"indefinite\"/>\n</pattern>\n<rect width=\"100%\" height=\"100%\" fill=\"url(#dots)\"/>",
   "tags": [
    "SVG",
    "パターン",
    "背景テクスチャ",
    "反復",
    "ヒーロー",
    "さりげない",
    "奥行き感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"SVGパターン背景のデモ\"><defs><pattern id=\"spbg-dots\" width=\"24\" height=\"24\" patternUnits=\"userSpaceOnUse\"><circle cx=\"4\" cy=\"4\" r=\"2.5\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".6\"/><animateTransform attributeName=\"patternTransform\" type=\"translate\" values=\"0 0;24 24\" dur=\"3.5s\" repeatCount=\"indefinite\"/></pattern></defs><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"url(#spbg-dots)\"/><rect x=\"60\" y=\"45\" width=\"120\" height=\"60\" rx=\"8\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\"/></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "fe-tile-pattern",
    "text-on-path",
    "progress-ring",
    "animated-favicon"
   ]
  },
  {
   "id": "viewbox-camera",
   "num": "W-172",
   "name": "viewBox Camera Move",
   "nameJa": "viewBoxのカメラワーク",
   "category": "svgfx",
   "description": "SVGのviewBox値自体をアニメーションさせ、拡大・縮小やパンといったカメラが動くような視点変化を作る表現。<animate attributeName=\"viewBox\">でx/y/width/heightを遷移させる。",
   "useCase": "地図や図解のズームイン演出、インフォグラフィックの視点誘導、スライドの注目箇所ハイライトに使う。",
   "code": "<svg viewBox=\"0 0 240 150\">\n  <animate attributeName=\"viewBox\" dur=\"5s\"\n    repeatCount=\"indefinite\"\n    values=\"0 0 240 150; 70 40 100 62; 0 0 240 150\"/>\n  …contents…\n</svg>",
   "tags": [
    "SVG",
    "viewBox",
    "カメラワーク",
    "ズーム",
    "インフォグラフィック",
    "没入感",
    "ダイナミック"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"viewBoxのカメラワークのデモ\"><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><svg x=\"10\" y=\"10\" width=\"220\" height=\"130\" viewBox=\"0 0 240 150\"><animate attributeName=\"viewBox\" dur=\"4.5s\" repeatCount=\"indefinite\" values=\"0 0 240 150;90 50 90 56;0 0 240 150\"/><rect x=\"30\" y=\"30\" width=\"60\" height=\"40\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/><rect x=\"120\" y=\"40\" width=\"70\" height=\"50\" fill=\"var(--w-accent,#4fe3c1)\"/><circle cx=\"150\" cy=\"60\" r=\"10\" fill=\"var(--w-amber,#ffc857)\"/><text x=\"20\" y=\"120\" font-size=\"10\" font-family=\"ui-sans-serif,system-ui,sans-serif\" fill=\"var(--w-ink,#e8eef9)\">MAP VIEW</text></svg></svg>",
   "useFor": [
    "slide",
    "lp"
   ],
   "weight": "主役",
   "relatedIds": [
    "svg-vector-effect-stroke",
    "svg-preserveaspectratio",
    "turbulence-wobble",
    "displacement-map"
   ]
  },
  {
   "id": "drop-shadow-filter",
   "num": "W-173",
   "name": "Drop Shadow Filter",
   "nameJa": "ドロップシャドウ（feDropShadow）",
   "category": "svgfx",
   "description": "要素に落ち影を付けて浮遊感や立体感を出す表現。feDropShadowでぼかし・オフセット・不透明度を指定し、ホバーやアニメーションで影の伸縮を変化させる。",
   "useCase": "カードやボタンのホバー時の浮遊演出、アイコンの立体感付与、ヒーロー画像の奥行き表現に使う。",
   "code": "<filter id=\"drop-shadow\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\n  <feDropShadow dx=\"0\" dy=\"4\" stdDeviation=\"6\"\n    flood-color=\"#000\" flood-opacity=\".35\"/>\n</filter>\n<rect class=\"card\" filter=\"url(#drop-shadow)\" width=\"80\" height=\"55\" rx=\"10\" fill=\"#4fe3c1\"/>\n<style>\n.card{ animation: float 3s ease-in-out infinite; }\n@keyframes float{\n  50%{ transform: translateY(-8px) }\n}\n</style>",
   "tags": [
    "SVG",
    "フィルター",
    "影",
    "立体感",
    "ホバー",
    "浮遊感",
    "高級感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ドロップシャドウのデモ\"><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><defs><filter id=\"dshd-filter\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\"><feDropShadow dx=\"0\" dy=\"6\" stdDeviation=\"5\" flood-color=\"var(--w-bg,#101830)\" flood-opacity=\".55\"><animate attributeName=\"dy\" values=\"6;18;6\" dur=\"3s\" repeatCount=\"indefinite\"/><animate attributeName=\"stdDeviation\" values=\"5;9;5\" dur=\"3s\" repeatCount=\"indefinite\"/><animate attributeName=\"flood-opacity\" values=\".55;.25;.55\" dur=\"3s\" repeatCount=\"indefinite\"/></feDropShadow></filter></defs><style>.dshd-card{animation:dshd-float 3s ease-in-out infinite}@keyframes dshd-float{0%,100%{transform:translateY(0)}50%{transform:translateY(-14px)}}</style><rect class=\"dshd-card\" x=\"80\" y=\"50\" width=\"80\" height=\"55\" rx=\"10\" fill=\"var(--w-accent,#4fe3c1)\" filter=\"url(#dshd-filter)\"/></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "goo-effect",
    "grain-noise",
    "pricing-card-hover-lift",
    "fe-colormatrix-huerotate"
   ]
  },
  {
   "id": "animated-favicon",
   "num": "W-174",
   "name": "Animated Favicon",
   "nameJa": "アニメするファビコン",
   "category": "svgfx",
   "description": "SVGファビコン内のCSSやSMILでタブアイコンを動かす表現。ブラウザ・省電力状態・バックグラウンドタブによって停止または非対応になるため、通知の唯一の手段にはせず静止時にも意味が通る図柄にする。",
   "useCase": "処理中や新着を補助的に示す場面。常時点滅は注意を奪うため避け、短時間・低頻度にし、ページタイトル等にも同じ状態を示す。",
   "code": "<!-- favicon.svg -->\n<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n  <circle cx=\"12\" cy=\"12\" r=\"8\" fill=\"#4fe3c1\">\n    <animate attributeName=\"r\" values=\"8;10;8\"\n      dur=\"1.4s\" repeatCount=\"indefinite\"/>\n  </circle>\n</svg>\n<!-- <link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.svg\"> -->",
   "tags": [
    "SVG",
    "ファビコン",
    "タブ",
    "通知",
    "ブランディング",
    "さりげない",
    "目を引く"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"アニメするファビコンのデモ\"><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><style>.fav-dot{animation:fav-pulse 2.4s ease-in-out infinite}@keyframes fav-pulse{0%,100%{transform:scale(1);opacity:.7}50%{transform:scale(1.45);opacity:1}}</style><rect x=\"20\" y=\"22\" width=\"200\" height=\"28\" rx=\"7\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><rect x=\"26\" y=\"27\" width=\"112\" height=\"18\" rx=\"5\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".32\"/><circle class=\"fav-dot\" cx=\"39\" cy=\"36\" r=\"6\" fill=\"var(--w-accent,#4fe3c1)\"/><path d=\"M54 36h64\" stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"6\" stroke-linecap=\"round\" opacity=\".55\"/><rect x=\"36\" y=\"72\" width=\"168\" height=\"38\" rx=\"8\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-dasharray=\"5 4\"/><text x=\"120\" y=\"95\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"11\" fill=\"var(--w-ink,#e8eef9)\">状態はタイトルにも表示</text><text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">tab icon · motion is optional</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "text-on-path",
    "displacement-map",
    "progress-ring",
    "svg-pattern-bg"
   ]
  },
  {
   "id": "fullscreen-fit-scale",
   "num": "W-175",
   "name": "Fit-to-Screen Scaling",
   "nameJa": "画面フィット拡大縮小",
   "category": "slide",
   "description": "16:9固定キャンバスをtransform: scaleでビューポート全体にフィットさせ、余白（レターボックス）を発生させつつ比率を保つ手法。resizeイベントでscale値を再計算する。",
   "useCase": "プロジェクターや配信画面などアスペクト比が読めない環境で、スライドを常に16:9のまま破綻なく表示したいときに使う。",
   "code": ":root{--k:1}\n.fit-stage{width:1280px;height:720px;transform-origin:top left;\n  transform:scale(var(--k))}\n<script>\nfunction fit(){document.documentElement.style.setProperty('--k',\n  Math.min(innerWidth/1280, innerHeight/720))}\naddEventListener('resize', fit); fit();\n</script>",
   "tags": [
    "CSS",
    "JavaScript",
    "スケーリング",
    "レスポンシブ",
    "16:9",
    "きっちり",
    "安定感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"画面フィット拡大縮小のデモ\">\n  <style>\n    .ffit-canvas{animation:ffit-scale 5s ease-in-out infinite}\n    @keyframes ffit-scale{0%,100%{transform:scale(1)}50%{transform:scale(.7)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"4\" y=\"4\" width=\"232\" height=\"142\" rx=\"6\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-dasharray=\"4 3\" opacity=\".5\"/>\n  <g class=\"ffit-canvas\" style=\"transform-origin:120px 75px\">\n    <rect x=\"40\" y=\"30\" width=\"160\" height=\"90\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\"/>\n    <rect x=\"52\" y=\"42\" width=\"60\" height=\"8\" rx=\"2\" fill=\"var(--w-bg,#101830)\" opacity=\".6\"/>\n  </g>\n</svg>",
   "useFor": [
    "slide"
   ],
   "weight": "脇役",
   "relatedIds": [
    "aspect-ratio",
    "print-pdf-css",
    "css-custom-highlights",
    "css-shape-function"
   ]
  },
  {
   "id": "scroll-snap-deck",
   "num": "W-176",
   "name": "Full-page Scroll Snap Deck",
   "nameJa": "縦フルページ scroll-snap デッキ",
   "category": "slide",
   "description": "縦に並べた各スライドをscroll-snap-type: y mandatoryで1画面ずつピタッと止める手法。子要素にscroll-snap-alignとheight:100vhを組み合わせる。",
   "useCase": "マウスホイールやスワイプだけでページ送りできる、プレゼン風の縦スクロールLPやスライドサイトを作りたいときに使う。",
   "code": ".snap-deck{\n  height:100vh; overflow-y:scroll;\n  scroll-snap-type:y mandatory;\n}\n.snap-deck > section{\n  height:100vh;\n  scroll-snap-align:start;\n}",
   "tags": [
    "CSS",
    "スクロール",
    "デッキ",
    "フルページ",
    "ピタッと",
    "没入感",
    "ネイティブ実装"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"縦フルページscroll-snapデッキのデモ\">\n  <style>\n    .ssnd-track{animation:ssnd-move 4.5s cubic-bezier(.7,0,.2,1) infinite}\n    @keyframes ssnd-move{0%,26%{transform:translateY(0)}36%,62%{transform:translateY(-56px)}72%,96%{transform:translateY(-112px)}100%{transform:translateY(0)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <clipPath id=\"ssnd-clip\"><rect x=\"70\" y=\"15\" width=\"100\" height=\"56\" rx=\"6\"/></clipPath>\n  <g clip-path=\"url(#ssnd-clip)\">\n    <g class=\"ssnd-track\">\n      <rect x=\"70\" y=\"15\" width=\"100\" height=\"56\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\"/>\n      <rect x=\"70\" y=\"71\" width=\"100\" height=\"56\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".6\"/>\n      <rect x=\"70\" y=\"127\" width=\"100\" height=\"56\" fill=\"var(--w-amber,#ffc857)\" opacity=\".8\"/>\n    </g>\n  </g>\n  <rect x=\"70\" y=\"15\" width=\"100\" height=\"56\" rx=\"6\" fill=\"none\" stroke=\"var(--w-ink,#e8eef9)\" opacity=\".4\"/>\n  <circle cx=\"188\" cy=\"30\" r=\"3\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".8\"/>\n  <circle cx=\"188\" cy=\"43\" r=\"3\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".3\"/>\n  <circle cx=\"188\" cy=\"56\" r=\"3\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".3\"/>\n</svg>",
   "useFor": [
    "slide",
    "lp"
   ],
   "weight": "主役",
   "relatedIds": [
    "vertical-scroll-snap",
    "parallax-layers",
    "scroll-snap",
    "parallax-scroll"
   ]
  },
  {
   "id": "arrow-key-nav",
   "num": "W-177",
   "name": "Arrow Key Navigation",
   "nameJa": "矢印キーでのページ送り",
   "category": "slide",
   "description": "keydownイベントで←→キーを監視し、現在スライドのインデックスを増減して表示を切り替えるJS実装。スペースやPageDown/Upも兼用させることが多い。",
   "useCase": "マウスに触れず登壇者がキーボードだけでスライドを進める、標準的なプレゼン操作を実装したいときに使う。",
   "code": "document.addEventListener('keydown', e => {\n  if (e.key === 'ArrowRight' || e.key === ' ') goTo(idx + 1);\n  if (e.key === 'ArrowLeft') goTo(idx - 1);\n});\nfunction goTo(i){\n  idx = Math.max(0, Math.min(total - 1, i));\n  slides[idx].scrollIntoView();\n}",
   "tags": [
    "JavaScript",
    "キーボード",
    "ナビゲーション",
    "プレゼン操作",
    "キビキビ",
    "サクサク",
    "定番"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"矢印キーでのページ送りのデモ\">\n  <style>\n    .akey-key{animation:akey-press 3s ease-in-out infinite}\n    @keyframes akey-press{0%,40%{transform:translateY(0)}45%{transform:translateY(3px)}50%,100%{transform:translateY(0)}}\n    .akey-panel{animation:akey-swap 3s steps(1) infinite}\n    @keyframes akey-swap{0%,49%{opacity:1}50%,100%{opacity:0}}\n    .akey-panel2{animation:akey-swap2 3s steps(1) infinite}\n    @keyframes akey-swap2{0%,49%{opacity:0}50%,100%{opacity:1}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"akey-panel\" x=\"50\" y=\"20\" width=\"140\" height=\"80\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\"/>\n  <rect class=\"akey-panel2\" x=\"50\" y=\"20\" width=\"140\" height=\"80\" rx=\"6\" fill=\"var(--w-amber,#ffc857)\" opacity=\".85\"/>\n  <g class=\"akey-key\">\n    <rect x=\"100\" y=\"118\" width=\"40\" height=\"24\" rx=\"5\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".4\"/>\n    <text x=\"120\" y=\"134\" font-family=\"ui-monospace,monospace\" font-size=\"12\" fill=\"var(--w-ink,#e8eef9)\" text-anchor=\"middle\">&#8594;</text>\n  </g>\n</svg>",
   "useFor": [
    "slide"
   ],
   "weight": "脇役",
   "relatedIds": [
    "reading-progress-bar",
    "scroll-snap-events",
    "fullscreen-api",
    "smooth-scroll"
   ]
  },
  {
   "id": "fragment-reveal",
   "num": "W-178",
   "name": "Fragment Step Reveal",
   "nameJa": "フラグメント段階表示",
   "category": "slide",
   "description": "箇条書きの各行に段階番号をふり、クリックやキー送りのたびに1行ずつopacityを切り替えて表示していく手法。data-step属性とクラス付与で制御する。",
   "useCase": "説明を要素ごとに小出しにしたい、聞き手の視線を1行ずつ誘導したいスライドの箇条書きパートに使う。",
   "code": ".frag{opacity:0; transition:opacity .3s}\n.frag.is-shown{opacity:1}\nnextBtn.onclick = () => {\n  const next = document.querySelector('.frag:not(.is-shown)');\n  if (next) next.classList.add('is-shown');\n};",
   "tags": [
    "CSS",
    "JavaScript",
    "箇条書き",
    "段階表示",
    "ステップ",
    "じわっと",
    "小出し感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"フラグメント段階表示のデモ\">\n  <style>\n    .frv-l1{animation:frv-a 4.5s ease-in-out infinite}\n    .frv-l2{animation:frv-a 4.5s ease-in-out infinite;animation-delay:1.1s}\n    .frv-l3{animation:frv-a 4.5s ease-in-out infinite;animation-delay:2.2s}\n    @keyframes frv-a{0%{opacity:0}8%{opacity:1}75%{opacity:1}83%,100%{opacity:0}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <circle cx=\"34\" cy=\"40\" r=\"4\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <rect class=\"frv-l1\" x=\"48\" y=\"36\" width=\"150\" height=\"8\" rx=\"4\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".9\"/>\n  <circle cx=\"34\" cy=\"70\" r=\"4\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <rect class=\"frv-l2\" x=\"48\" y=\"66\" width=\"130\" height=\"8\" rx=\"4\" fill=\"var(--w-ink,#e8eef9)\" opacity=\"0\"/>\n  <circle cx=\"34\" cy=\"100\" r=\"4\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <rect class=\"frv-l3\" x=\"48\" y=\"96\" width=\"160\" height=\"8\" rx=\"4\" fill=\"var(--w-ink,#e8eef9)\" opacity=\"0\"/>\n</svg>",
   "useFor": [
    "slide"
   ],
   "weight": "主役",
   "relatedIds": [
    "css-custom-highlights",
    "fullscreen-fit-scale",
    "view-transitions-slide",
    "overview-grid-zoom"
   ]
  },
  {
   "id": "target-only-slide-switch",
   "num": "W-179",
   "name": ":target-only Slide Switching",
   "nameJa": ":targetだけでのスライド切替",
   "category": "slide",
   "description": "各スライドをid付きセクションにし、アンカーリンクとCSSの:target疑似クラスだけでdisplayを切り替える、JS不要のページ送り実装。",
   "useCase": "JSを一切使わず、軽量な単一HTMLだけで簡易スライドショーやLP内タブを作りたいときに使う。",
   "code": "section{display:none}\nsection:target{display:block}\n\n<a href=\"#slide-2\">次へ</a>\n<section id=\"slide-1\">...</section>\n<section id=\"slide-2\">...</section>",
   "tags": [
    "CSS",
    "JS不要",
    "アンカー",
    "軽量",
    "カチッと",
    "割り切り"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\":targetだけでのスライド切替のデモ\">\n  <style>\n    .tgt-a{animation:tgt-a 4s steps(1) infinite}\n    .tgt-b{animation:tgt-b 4s steps(1) infinite}\n    @keyframes tgt-a{0%,49%{opacity:1}50%,100%{opacity:0}}\n    @keyframes tgt-b{0%,49%{opacity:0}50%,100%{opacity:1}}\n    .tgt-link{animation:tgt-blink 4s steps(1) infinite}\n    @keyframes tgt-blink{0%,49%{fill:var(--w-accent,#4fe3c1)}50%,100%{fill:var(--w-amber,#ffc857)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"tgt-a\" x=\"60\" y=\"25\" width=\"120\" height=\"70\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\"/>\n  <text class=\"tgt-a\" x=\"120\" y=\"65\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"12\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\">#slide-1</text>\n  <rect class=\"tgt-b\" x=\"60\" y=\"25\" width=\"120\" height=\"70\" rx=\"6\" fill=\"var(--w-amber,#ffc857)\" opacity=\".85\"/>\n  <text class=\"tgt-b\" x=\"120\" y=\"65\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"12\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\">#slide-2</text>\n  <circle class=\"tgt-link\" cx=\"120\" cy=\"118\" r=\"5\" fill=\"var(--w-accent,#4fe3c1)\"/>\n</svg>",
   "useFor": [
    "slide"
   ],
   "weight": "脇役",
   "relatedIds": [
    "anchor-positioning",
    "target-css-toggle",
    "scroll-margin-padding",
    "has-selector"
   ]
  },
  {
   "id": "url-hash-sync",
   "num": "W-180",
   "name": "URL Hash Sync",
   "nameJa": "URLハッシュとページ同期",
   "category": "slide",
   "description": "現在のスライド番号をlocation.hashへ都度書き込み、hashchangeイベントで逆にスライド位置を復元する双方向同期。リロードや共有URLで途中から開ける。",
   "useCase": "特定ページへ直接リンクしたい、リロードしても同じスライドに留まってほしい社内資料や配布用スライドに使う。",
   "code": "function setSlide(i){\n  idx = i; render();\n  history.replaceState(null, '', '#' + (i + 1));\n}\naddEventListener('hashchange', () => {\n  const i = Number(location.hash.slice(1)) - 1;\n  if (!Number.isNaN(i)) setSlide(i);\n});",
   "tags": [
    "JavaScript",
    "URL",
    "共有",
    "状態保存",
    "さりげない",
    "安心感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"URLハッシュとページ同期のデモ\">\n  <style>\n    .uhs-t1{animation:uhs-show 4.5s steps(1) infinite}\n    .uhs-t2{animation:uhs-show 4.5s steps(1) infinite;animation-delay:1.5s}\n    .uhs-t3{animation:uhs-show 4.5s steps(1) infinite;animation-delay:3s}\n    @keyframes uhs-show{0%{opacity:1}33%{opacity:1}34%,100%{opacity:0}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"20\" y=\"20\" width=\"200\" height=\"22\" rx=\"5\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".25\"/>\n  <text x=\"30\" y=\"36\" font-family=\"ui-monospace,monospace\" font-size=\"10\" fill=\"var(--w-ink,#e8eef9)\">deck.html</text>\n  <text class=\"uhs-t1\" x=\"150\" y=\"36\" font-family=\"ui-monospace,monospace\" font-size=\"10\" fill=\"var(--w-accent,#4fe3c1)\">#1</text>\n  <text class=\"uhs-t2\" x=\"150\" y=\"36\" font-family=\"ui-monospace,monospace\" font-size=\"10\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\"0\">#2</text>\n  <text class=\"uhs-t3\" x=\"150\" y=\"36\" font-family=\"ui-monospace,monospace\" font-size=\"10\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\"0\">#3</text>\n  <rect x=\"70\" y=\"60\" width=\"100\" height=\"60\" rx=\"6\" fill=\"var(--w-amber,#ffc857)\" opacity=\".2\"/>\n  <text class=\"uhs-t1\" x=\"120\" y=\"98\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"14\" fill=\"var(--w-ink,#e8eef9)\" text-anchor=\"middle\">1</text>\n  <text class=\"uhs-t2\" x=\"120\" y=\"98\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"14\" fill=\"var(--w-ink,#e8eef9)\" text-anchor=\"middle\" opacity=\"0\">2</text>\n  <text class=\"uhs-t3\" x=\"120\" y=\"98\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"14\" fill=\"var(--w-ink,#e8eef9)\" text-anchor=\"middle\" opacity=\"0\">3</text>\n</svg>",
   "useFor": [
    "slide"
   ],
   "weight": "脇役",
   "relatedIds": [
    "image-fallback",
    "slide-progress-indicator",
    "presenter-notes-broadcast",
    "scroll-spy-nav"
   ]
  },
  {
   "id": "slide-progress-indicator",
   "num": "W-181",
   "name": "Slide Progress Indicator",
   "nameJa": "スライド番号・プログレス表示",
   "category": "slide",
   "description": "「3 / 20」のような現在ページ番号表示と、画面端の細いバーをwidth: calc()で現在位置に応じて伸ばすプログレスバーを併用する定番UI。",
   "useCase": "聴衆に残り時間・残りページ感を伝えたい、長尺スライドの進行状況を常時可視化したいときに使う。",
   "code": ".progress{\n  position:fixed; bottom:0; left:0; height:4px;\n  background:var(--w-accent,#4fe3c1);\n  width:calc(100% * var(--i) / var(--total));\n  transition:width .3s;\n}\n<span>{{i}} / {{total}}</span>",
   "tags": [
    "CSS",
    "UI",
    "進捗表示",
    "ページ番号",
    "さりげない",
    "安心感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"スライド番号・プログレス表示のデモ\">\n  <style>\n    .spi-bar{animation:spi-grow 4s linear infinite}\n    @keyframes spi-grow{0%{width:0}100%{width:224px}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"60\" y=\"30\" width=\"120\" height=\"70\" rx=\"6\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".25\"/>\n  <text x=\"200\" y=\"30\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#94a3c0)\" text-anchor=\"end\">4 / 12</text>\n  <rect x=\"8\" y=\"136\" width=\"224\" height=\"6\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".25\"/>\n  <rect class=\"spi-bar\" x=\"8\" y=\"136\" height=\"6\" rx=\"3\" fill=\"var(--w-accent,#4fe3c1)\"/>\n</svg>",
   "useFor": [
    "slide"
   ],
   "weight": "脇役",
   "relatedIds": [
    "sticky-position",
    "overscroll-behavior",
    "url-hash-sync",
    "text-emphasis-dots"
   ]
  },
  {
   "id": "view-transitions-slide",
   "num": "W-182",
   "name": "View Transitions Page Change",
   "nameJa": "View Transitionsでのページ転換",
   "category": "slide",
   "description": "document.startViewTransition()でDOM更新を包み、前後のスナップショットをブラウザが自動でクロスフェード/モーフィングするAPI。view-transition-nameで要素単位の連続移動も指定できる。",
   "useCase": "スライド切替の瞬間にふわっとクロスフェードや要素の滑らかな移動を付けたい、映画的な転換を作りたいときに使う。",
   "code": "function go(next){\n  if (!document.startViewTransition) return render(next);\n  document.startViewTransition(() => render(next));\n}\n\n::view-transition-old(root),\n::view-transition-new(root){ animation-duration:.4s; }",
   "tags": [
    "JavaScript",
    "CSS",
    "ページ転換",
    "クロスフェード",
    "ふわっと",
    "目を引く",
    "映画的"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"View Transitionsでのページ転換のデモ\">\n  <style>\n    .vwt-old{animation:vwt-fadeout 4s ease-in-out infinite}\n    .vwt-new{animation:vwt-fadein 4s ease-in-out infinite}\n    @keyframes vwt-fadeout{0%,40%{opacity:1}55%,100%{opacity:0}}\n    @keyframes vwt-fadein{0%,40%{opacity:0}55%,100%{opacity:1}}\n    .vwt-morph{animation:vwt-move 4s ease-in-out infinite}\n    @keyframes vwt-move{0%,40%{transform:translate(0,0) scale(1)}55%,100%{transform:translate(60px,-10px) scale(.7)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"vwt-old\">\n    <rect x=\"30\" y=\"20\" width=\"90\" height=\"100\" rx=\"6\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/>\n  </g>\n  <g class=\"vwt-new\">\n    <rect x=\"120\" y=\"20\" width=\"90\" height=\"100\" rx=\"6\" fill=\"var(--w-amber,#ffc857)\" opacity=\".8\"/>\n  </g>\n  <circle class=\"vwt-morph\" cx=\"60\" cy=\"40\" r=\"14\" fill=\"var(--w-accent,#4fe3c1)\"/>\n</svg>",
   "useFor": [
    "slide"
   ],
   "weight": "主役",
   "relatedIds": [
    "scroll-reveal",
    "stagger-char-reveal",
    "laser-pointer-cursor",
    "starting-style"
   ]
  },
  {
   "id": "presenter-notes-broadcast",
   "num": "W-183",
   "name": "Presenter Notes via BroadcastChannel",
   "nameJa": "発表者ノート（BroadcastChannel + window.open）",
   "category": "slide",
   "description": "window.open()で別ウィンドウを開き、BroadcastChannelでスライド番号・発表メモ・タイマーを親子ウィンドウ間にリアルタイム送信する2画面プレゼン構成。",
   "useCase": "登壇者用モニターにカンペとタイマーを出し、投影画面には本編スライドだけを映す2画面運用をしたいときに使う。",
   "code": "const ch = new BroadcastChannel('deck');\nwindow.open('notes.html', 'notes');\nch.postMessage({ idx, note: notes[idx], elapsed });\n\n// notes.html側\nnew BroadcastChannel('deck').onmessage = e => render(e.data);",
   "tags": [
    "JavaScript",
    "2画面",
    "発表者ノート",
    "裏方",
    "こっそり",
    "安心感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"発表者ノートBroadcastChannelのデモ\">\n  <style>\n    .pns-pulse{animation:pns-move 2.5s linear infinite}\n    @keyframes pns-move{0%{transform:translateX(0);opacity:0}10%{opacity:1}90%{opacity:1}100%{transform:translateX(80px);opacity:0}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"14\" y=\"30\" width=\"90\" height=\"90\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".8\"/>\n  <text x=\"59\" y=\"80\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"11\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\">投影用</text>\n  <rect x=\"136\" y=\"30\" width=\"90\" height=\"90\" rx=\"6\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".3\"/>\n  <text x=\"181\" y=\"60\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-ink,#e8eef9)\" text-anchor=\"middle\">ノート</text>\n  <text x=\"181\" y=\"80\" font-family=\"ui-monospace,monospace\" font-size=\"10\" fill=\"var(--w-amber,#ffc857)\" text-anchor=\"middle\">05:12</text>\n  <circle class=\"pns-pulse\" cx=\"108\" cy=\"75\" r=\"4\" fill=\"var(--w-amber,#ffc857)\"/>\n</svg>",
   "useFor": [
    "slide"
   ],
   "weight": "脇役",
   "relatedIds": [
    "url-hash-sync",
    "image-fallback",
    "scroll-into-view-container",
    "element-scoped-view-transition"
   ]
  },
  {
   "id": "autoplay-timer-advance",
   "num": "W-184",
   "name": "Timed Autoplay",
   "nameJa": "自動再生（タイマー送り）",
   "category": "slide",
   "description": "setIntervalなどを合図に、一定秒数ごとに自動でスライドインデックスを進めるタイマー駆動の自動再生。progress用の円形カウントダウンと組み合わせることが多い。",
   "useCase": "展示会サイネージや無人ブースでループ再生させたい、動画のように放置しても進行するスライドにしたいときに使う。",
   "code": "let idx = 0;\nsetInterval(() => {\n  idx = (idx + 1) % slides.length;\n  render(idx);\n}, 6000);",
   "tags": [
    "JavaScript",
    "タイマー",
    "自動再生",
    "サイネージ",
    "淡々と",
    "一定リズム"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"自動再生タイマー送りのデモ\">\n  <style>\n    .atd-ring{animation:atd-dash 4s linear infinite;stroke-dasharray:88}\n    @keyframes atd-dash{0%{stroke-dashoffset:0}100%{stroke-dashoffset:88}}\n    .atd-p1{animation:atd-p1 4s steps(1) infinite}\n    .atd-p2{animation:atd-p2 4s steps(1) infinite}\n    @keyframes atd-p1{0%,49%{opacity:1}50%,100%{opacity:0}}\n    @keyframes atd-p2{0%,49%{opacity:0}50%,100%{opacity:1}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"atd-p1\" x=\"26\" y=\"95\" width=\"60\" height=\"34\" rx=\"5\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\"/>\n  <rect class=\"atd-p2\" x=\"26\" y=\"95\" width=\"60\" height=\"34\" rx=\"5\" fill=\"var(--w-amber,#ffc857)\" opacity=\".85\"/>\n  <circle cx=\"120\" cy=\"55\" r=\"14\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-width=\"4\" opacity=\".3\"/>\n  <circle class=\"atd-ring\" cx=\"120\" cy=\"55\" r=\"14\" fill=\"none\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"4\" transform=\"rotate(-90 120 55)\"/>\n</svg>",
   "useFor": [
    "slide",
    "lp"
   ],
   "weight": "脇役",
   "relatedIds": [
    "scroll-into-view-container",
    "element-scoped-view-transition",
    "css-registerproperty-js",
    "css-typed-om"
   ]
  },
  {
   "id": "overview-grid-zoom",
   "num": "W-185",
   "name": "Grid Overview Mode",
   "nameJa": "俯瞰モード（全体グリッド表示）",
   "category": "slide",
   "description": "全スライドをtransform: scale()で縮小しCSS Gridに並べて一覧できる俯瞰表示。クリックで該当スライドへズームインして戻る、PowerPointの「すべてのスライド」相当の機能。",
   "useCase": "発表中に構成を見失わないよう全体像を一瞬確認したい、目的のページへ素早くジャンプしたいときに使う。",
   "code": ".overview .deck{\n  display:grid; grid-template-columns:repeat(4,1fr);\n  gap:12px;\n}\n.overview section{\n  transform:scale(.22);\n  transform-origin:top left;\n  transition:transform .3s;\n}",
   "tags": [
    "CSS",
    "JavaScript",
    "一覧性",
    "俯瞰",
    "ズームアウト",
    "見渡せる",
    "すっきり"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"俯瞰モード全体グリッド表示のデモ\">\n  <style>\n    .ogz-big{animation:ogz-shrink 4.5s ease-in-out infinite}\n    @keyframes ogz-shrink{0%,20%{opacity:1;transform:scale(1)}45%,100%{opacity:0;transform:scale(.3)}}\n    .ogz-grid{animation:ogz-appear 4.5s ease-in-out infinite}\n    @keyframes ogz-appear{0%,25%{opacity:0}50%,100%{opacity:1}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"ogz-big\" x=\"60\" y=\"20\" width=\"120\" height=\"90\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\" style=\"transform-origin:120px 65px\"/>\n  <g class=\"ogz-grid\">\n    <rect x=\"26\" y=\"24\" width=\"46\" height=\"30\" rx=\"3\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".8\"/>\n    <rect x=\"80\" y=\"24\" width=\"46\" height=\"30\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".6\"/>\n    <rect x=\"134\" y=\"24\" width=\"46\" height=\"30\" rx=\"3\" fill=\"var(--w-amber,#ffc857)\" opacity=\".8\"/>\n    <rect x=\"26\" y=\"62\" width=\"46\" height=\"30\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".6\"/>\n    <rect x=\"80\" y=\"62\" width=\"46\" height=\"30\" rx=\"3\" fill=\"var(--w-amber,#ffc857)\" opacity=\".7\"/>\n    <rect x=\"134\" y=\"62\" width=\"46\" height=\"30\" rx=\"3\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".6\"/>\n  </g>\n</svg>",
   "useFor": [
    "slide"
   ],
   "weight": "主役",
   "relatedIds": [
    "slide-thumbnail-navigator",
    "css-custom-highlights",
    "text-spacing-trim",
    "font-feature-pwid"
   ]
  },
  {
   "id": "print-pdf-css",
   "num": "W-186",
   "name": "Print-to-PDF Layout",
   "nameJa": "印刷PDF化（@page / print CSS）",
   "category": "slide",
   "description": "@media printと@pageルールでページサイズ・余白を指定し、1スライド=1ページで強制改ページするpage-break-after: alwaysを適用してブラウザの印刷機能でPDF化する。",
   "useCase": "配布資料やハンドアウトとして、URLではなくPDFで納品・共有したいときに使う。",
   "code": "@media print{\n  @page{ size:1280px 720px; margin:0; }\n  section{\n    page-break-after:always;\n    width:1280px; height:720px;\n  }\n  .no-print{ display:none; }\n}",
   "tags": [
    "CSS",
    "印刷",
    "PDF化",
    "配布資料",
    "きっちり",
    "整然"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"印刷PDF化のデモ\">\n  <style>\n    .ppc-page{animation:ppc-out 4s ease-in infinite}\n    @keyframes ppc-out{0%{transform:translateY(0);opacity:0}10%{opacity:1}45%{transform:translateY(40px);opacity:1}55%,100%{opacity:0}}\n    .ppc-p2{animation-delay:1.3s}\n    .ppc-p3{animation-delay:2.6s}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"70\" y=\"18\" width=\"100\" height=\"40\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".4\"/>\n  <rect x=\"82\" y=\"30\" width=\"76\" height=\"16\" rx=\"2\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".2\"/>\n  <rect class=\"ppc-page\" x=\"95\" y=\"58\" width=\"50\" height=\"34\" rx=\"2\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <rect class=\"ppc-page ppc-p2\" x=\"95\" y=\"58\" width=\"50\" height=\"34\" rx=\"2\" fill=\"var(--w-amber,#ffc857)\" opacity=\"0\"/>\n  <rect class=\"ppc-page ppc-p3\" x=\"95\" y=\"58\" width=\"50\" height=\"34\" rx=\"2\" fill=\"var(--w-ink,#e8eef9)\" opacity=\"0\"/>\n  <rect x=\"80\" y=\"118\" width=\"80\" height=\"6\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/>\n</svg>",
   "useFor": [
    "slide"
   ],
   "weight": "脇役",
   "relatedIds": [
    "fullscreen-fit-scale",
    "aspect-ratio",
    "subgrid",
    "holy-grail-layout"
   ]
  },
  {
   "id": "fullscreen-api",
   "num": "W-187",
   "name": "Fullscreen API",
   "nameJa": "フルスクリーンAPI",
   "category": "slide",
   "description": "element.requestFullscreen()でブラウザChromeを消し画面全体をスライド専用にする。fullscreenchangeイベントでボタン表示やレイアウトを切り替える。",
   "useCase": "URLバーやタブを隠して本番同然の見た目でリハーサル・登壇したい、Escで即戻れる形にしたいときに使う。",
   "code": "toggleBtn.onclick = () => {\n  if (!document.fullscreenElement) {\n    deck.requestFullscreen();\n  } else {\n    document.exitFullscreen();\n  }\n};",
   "tags": [
    "JavaScript",
    "API",
    "全画面",
    "没入感",
    "本番感",
    "定番"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"フルスクリーンAPIのデモ\">\n  <style>\n    .fsa-chrome{animation:fsa-hide 4s ease-in-out infinite}\n    @keyframes fsa-hide{0%,20%{opacity:1}40%,100%{opacity:0}}\n    .fsa-content{animation:fsa-grow 4s ease-in-out infinite;transform-origin:120px 90px}\n    @keyframes fsa-grow{0%,20%{transform:scale(1)}40%,100%{transform:scale(1.18)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"fsa-chrome\" x=\"20\" y=\"18\" width=\"200\" height=\"18\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".4\"/>\n  <circle class=\"fsa-chrome\" cx=\"30\" cy=\"27\" r=\"3\" fill=\"var(--w-amber,#ffc857)\"/>\n  <rect class=\"fsa-content\" x=\"30\" y=\"40\" width=\"180\" height=\"90\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\"/>\n</svg>",
   "useFor": [
    "slide"
   ],
   "weight": "脇役",
   "relatedIds": [
    "arrow-key-nav",
    "view-transitions-spa",
    "copy-button",
    "web-share-api"
   ]
  },
  {
   "id": "per-slide-background",
   "num": "W-188",
   "name": "Per-slide Background Switching",
   "nameJa": "スライドごとの背景切替",
   "category": "slide",
   "description": "各セクションにdata-theme属性やクラスを付け、background/CSS変数を差し替えて画面ごとに色・写真・グラデーションを変える手法。transitionで切替時になじませる。",
   "useCase": "章の切れ目を色で伝えたい、写真スライドと図解スライドで空気感を変えたいときに使う。",
   "code": "section[data-bg=\"dark\"]{ --bg:var(--w-bg,#101830); --ink:#fff; }\nsection[data-bg=\"light\"]{ --bg:#fff; --ink:#101830; }\nsection{\n  background:var(--bg); color:var(--ink);\n  transition:background .4s;\n}",
   "tags": [
    "CSS",
    "背景",
    "テーマ切替",
    "章分け",
    "雰囲気",
    "メリハリ"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"スライドごとの背景切替のデモ\">\n  <style>\n    .psb-bg{animation:psb-cycle 4.5s steps(3) infinite}\n    @keyframes psb-cycle{0%{fill:var(--w-accent,#4fe3c1)}34%{fill:var(--w-amber,#ffc857)}67%{fill:var(--w-sub,#94a3c0)}100%{fill:var(--w-accent,#4fe3c1)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"psb-bg\" x=\"20\" y=\"20\" width=\"200\" height=\"110\" rx=\"8\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".35\"/>\n  <rect x=\"40\" y=\"50\" width=\"90\" height=\"10\" rx=\"5\" fill=\"var(--w-ink,#e8eef9)\"/>\n  <rect x=\"40\" y=\"70\" width=\"140\" height=\"6\" rx=\"3\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".5\"/>\n  <rect x=\"40\" y=\"84\" width=\"120\" height=\"6\" rx=\"3\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".5\"/>\n</svg>",
   "useFor": [
    "slide",
    "lp"
   ],
   "weight": "脇役",
   "relatedIds": [
    "parallax-scroll",
    "full-bleed-breakout",
    "gradient-animation",
    "aurora-background"
   ]
  },
  {
   "id": "laser-pointer-cursor",
   "num": "W-189",
   "name": "Laser Pointer Cursor",
   "nameJa": "レーザーポインタ風カーソル",
   "category": "slide",
   "description": "mousemoveの座標を追従する小さな発光ドットをposition: fixedで表示し、box-shadowでにじませてレーザーポインタのように見せる演出。キー操作でON/OFFすることが多い。",
   "useCase": "画面共有やオンライン登壇で、話している箇所を指し示すレーザーポインタが手元に無いときの代替に使う。",
   "code": "const dot = document.querySelector('.laser');\naddEventListener('mousemove', e => {\n  dot.style.left = e.clientX + 'px';\n  dot.style.top  = e.clientY + 'px';\n});\n\n.laser{\n  position:fixed; width:12px; height:12px; border-radius:50%;\n  background:var(--w-amber,#ffc857);\n  box-shadow:0 0 12px 4px var(--w-amber,#ffc857);\n  pointer-events:none;\n}",
   "tags": [
    "JavaScript",
    "CSS",
    "カーソル",
    "指し示す",
    "発光",
    "目を引く",
    "ライブ感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"レーザーポインタ風カーソルのデモ\">\n  <style>\n    .lpc-dot{animation:lpc-move 4s ease-in-out infinite}\n    @keyframes lpc-move{0%{cx:40;cy:45}30%{cx:150;cy:45}55%{cx:150;cy:80}80%{cx:70;cy:110}100%{cx:40;cy:45}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"30\" y=\"38\" width=\"150\" height=\"8\" rx=\"4\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".3\"/>\n  <rect x=\"30\" y=\"73\" width=\"120\" height=\"8\" rx=\"4\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".3\"/>\n  <rect x=\"30\" y=\"103\" width=\"100\" height=\"8\" rx=\"4\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".3\"/>\n  <circle class=\"lpc-dot\" cx=\"40\" cy=\"45\" r=\"10\" fill=\"var(--w-amber,#ffc857)\" opacity=\".25\"/>\n  <circle class=\"lpc-dot\" cx=\"40\" cy=\"45\" r=\"5\" fill=\"var(--w-amber,#ffc857)\"/>\n</svg>",
   "useFor": [
    "slide"
   ],
   "weight": "主役",
   "relatedIds": [
    "custom-cursor",
    "cursor-spotlight",
    "view-transitions-slide",
    "neon-glow-text"
   ]
  },
  {
   "id": "single-html-file-tips",
   "num": "W-190",
   "name": "Single-file HTML Deck",
   "nameJa": "単一HTMLファイル運用の勘所",
   "category": "slide",
   "description": "CSSはstyleタグ、JSはscriptタグ、アイコンはインラインSVGで1ファイルに全部同梱し、外部依存なしでダブルクリックやメール添付だけで動く形に閉じる設計方針。",
   "useCase": "ネット環境が不安な会場や社外への1ファイル送付、file://直開きでも崩れない配布用スライドを作りたいときに使う。",
   "code": "<!-- 1ファイルに全部入り -->\n<style>/* 全CSSをここに */</style>\n<svg><!-- アイコンはインラインSVGでbase64/外部画像を避ける --></svg>\n<script>\n  /* 全JSをここに。fetchやCDN読み込みは使わない */\n</script>",
   "tags": [
    "HTML",
    "単一ファイル",
    "配布",
    "オフライン対応",
    "持ち運びやすい",
    "割り切り"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"単一HTMLファイル運用のデモ\">\n  <style>\n    .shf-in1{animation:shf-move 4s ease-in-out infinite}\n    .shf-in2{animation:shf-move 4s ease-in-out infinite;animation-delay:.3s}\n    .shf-in3{animation:shf-move 4s ease-in-out infinite;animation-delay:.6s}\n    @keyframes shf-move{0%,15%{transform:translate(0,0);opacity:1}55%,100%{transform:translate(0,40px);opacity:0}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"shf-in1\" x=\"30\" y=\"20\" width=\"40\" height=\"26\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\"/>\n  <text class=\"shf-in1\" x=\"50\" y=\"38\" font-family=\"ui-monospace,monospace\" font-size=\"10\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\">CSS</text>\n  <rect class=\"shf-in2\" x=\"100\" y=\"20\" width=\"40\" height=\"26\" rx=\"4\" fill=\"var(--w-amber,#ffc857)\" opacity=\".85\"/>\n  <text class=\"shf-in2\" x=\"120\" y=\"38\" font-family=\"ui-monospace,monospace\" font-size=\"10\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\">JS</text>\n  <rect class=\"shf-in3\" x=\"170\" y=\"20\" width=\"40\" height=\"26\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".85\"/>\n  <text class=\"shf-in3\" x=\"190\" y=\"38\" font-family=\"ui-monospace,monospace\" font-size=\"10\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\">SVG</text>\n  <rect x=\"75\" y=\"70\" width=\"90\" height=\"60\" rx=\"6\" fill=\"none\" stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"2\" opacity=\".7\"/>\n  <text x=\"120\" y=\"105\" font-family=\"ui-monospace,monospace\" font-size=\"11\" fill=\"var(--w-ink,#e8eef9)\" text-anchor=\"middle\">.html</text>\n</svg>",
   "useFor": [
    "slide",
    "lp"
   ],
   "weight": "脇役",
   "relatedIds": [
    "popover-hint",
    "target-only-slide-switch",
    "details-summary-accordion",
    "customizable-select"
   ]
  },
  {
   "id": "slide-thumbnail-navigator",
   "num": "W-191",
   "name": "Thumbnail Rail Navigator",
   "nameJa": "サムネイル一覧ナビゲーター",
   "category": "slide",
   "description": "画面端に全スライドの縮小プレビューを並べたレールを常設し、クリックやキー操作で該当スライドへジャンプする。現在位置はハイライト枠で示す。",
   "useCase": "章数が多い長尺スライドで目的のページへ素早く移動したい、聴衆にも進行の全体像を見せたいときに使う。",
   "code": ".rail{ display:flex; flex-direction:column; gap:6px; overflow-y:auto; }\n.rail button{ width:64px; height:36px; border:2px solid transparent; }\n.rail button.is-active{ border-color:var(--w-accent,#4fe3c1); }\n.rail button:hover{ transform:scale(1.05); }",
   "tags": [
    "CSS",
    "JavaScript",
    "サムネイル",
    "一覧性",
    "ジャンプ移動",
    "見渡せる",
    "サクッと"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"サムネイル一覧ナビゲーターのデモ\">\n  <style>\n    .stn-hi{animation:stn-move 4.5s ease-in-out infinite}\n    @keyframes stn-move{0%,20%{transform:translateY(0)}40%,60%{transform:translateY(38px)}80%,100%{transform:translateY(76px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"16\" y=\"20\" width=\"46\" height=\"30\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/>\n  <rect x=\"16\" y=\"58\" width=\"46\" height=\"30\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/>\n  <rect x=\"16\" y=\"96\" width=\"46\" height=\"30\" rx=\"3\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/>\n  <rect class=\"stn-hi\" x=\"13\" y=\"17\" width=\"52\" height=\"36\" rx=\"4\" fill=\"none\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"3\"/>\n  <rect x=\"90\" y=\"30\" width=\"130\" height=\"90\" rx=\"6\" fill=\"var(--w-amber,#ffc857)\" opacity=\".25\"/>\n  <rect x=\"106\" y=\"50\" width=\"90\" height=\"8\" rx=\"4\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".7\"/>\n</svg>",
   "useFor": [
    "slide"
   ],
   "weight": "脇役",
   "relatedIds": [
    "overview-grid-zoom",
    "css-custom-highlights",
    "fullscreen-fit-scale",
    "fragment-reveal"
   ]
  },
  {
   "id": "touch-swipe-navigation",
   "num": "W-192",
   "name": "Touch Swipe Navigation",
   "nameJa": "スワイプでのページ送り",
   "category": "slide",
   "description": "touchstart/touchmove/touchendの座標差からスワイプ方向を判定し、一定距離を超えたら前後のスライドへ切り替えるモバイル向けジェスチャー実装。",
   "useCase": "スマホやタブレットでスライドを閲覧・発表するとき、画面を左右にフリックするだけでページ送りできるようにしたいときに使う。",
   "code": "let x0;\nel.addEventListener('touchstart', e => x0 = e.touches[0].clientX);\nel.addEventListener('touchend', e => {\n  const dx = e.changedTouches[0].clientX - x0;\n  if (dx < -50) next();\n  else if (dx > 50) prev();\n});",
   "tags": [
    "JavaScript",
    "タッチ",
    "スワイプ",
    "モバイル",
    "フリック",
    "ぬるっと",
    "直感的"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"スワイプでのページ送りのデモ\">\n  <style>\n    .tsw-finger{animation:tsw-swipe 3.5s ease-in-out infinite}\n    @keyframes tsw-swipe{0%,10%{transform:translateX(0);opacity:1}45%{transform:translateX(-90px);opacity:1}55%,100%{opacity:0}}\n    .tsw-p1{animation:tsw-out 3.5s ease-in-out infinite}\n    .tsw-p2{animation:tsw-in 3.5s ease-in-out infinite}\n    @keyframes tsw-out{0%,40%{transform:translateX(0)}70%,100%{transform:translateX(-140px)}}\n    @keyframes tsw-in{0%,40%{transform:translateX(140px)}70%,100%{transform:translateX(0)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <clipPath id=\"tsw-clip\"><rect x=\"55\" y=\"20\" width=\"130\" height=\"90\" rx=\"6\"/></clipPath>\n  <g clip-path=\"url(#tsw-clip)\">\n    <rect class=\"tsw-p1\" x=\"55\" y=\"20\" width=\"130\" height=\"90\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\"/>\n    <rect class=\"tsw-p2\" x=\"55\" y=\"20\" width=\"130\" height=\"90\" fill=\"var(--w-amber,#ffc857)\" opacity=\".85\"/>\n  </g>\n  <circle class=\"tsw-finger\" cx=\"160\" cy=\"65\" r=\"9\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".9\"/>\n</svg>",
   "useFor": [
    "slide",
    "lp"
   ],
   "weight": "脇役",
   "relatedIds": [
    "view-transitions-spa",
    "flip-technique",
    "web-animations-api",
    "magnetic-button"
   ]
  },
  {
   "id": "object-fit",
   "num": "W-193",
   "name": "Object Fit",
   "nameJa": "オブジェクトフィット",
   "category": "media",
   "description": "親要素の枠に対して画像や動画の縦横比を保ったまま埋める/収める表現。object-fit: coverは枠からはみ出た部分を自動トリミングして埋め、containは画像全体を枠内に収めて余白を作る（トリミングはされない）。",
   "useCase": "サムネイルグリッドやヒーロー画像で、元画像の比率がバラバラでも枠を揃えて破綻なく並べたいときに使う。",
   "code": ".ofit-img {\n  width: 100%;\n  height: 240px;\n  object-fit: cover;\n  object-position: center;\n}",
   "tags": [
    "CSS",
    "画像",
    "object-fit",
    "トリミング",
    "レイアウト",
    "すっきり",
    "きれいに整う"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"Object Fitのデモ\">\n  <style>\n    .ofit-pan{animation:ofit-pan 4s ease-in-out infinite}\n    @keyframes ofit-pan{0%,100%{transform:translate(-16px,-8px)}50%{transform:translate(16px,8px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <defs>\n    <clipPath id=\"ofit-clip\"><rect x=\"70\" y=\"35\" width=\"100\" height=\"80\" rx=\"6\"/></clipPath>\n  </defs>\n  <rect x=\"70\" y=\"35\" width=\"100\" height=\"80\" rx=\"6\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-dasharray=\"4 3\"/>\n  <g clip-path=\"url(#ofit-clip)\">\n    <g class=\"ofit-pan\">\n      <rect x=\"50\" y=\"15\" width=\"140\" height=\"120\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".15\"/>\n      <circle cx=\"90\" cy=\"60\" r=\"18\" fill=\"var(--w-amber,#ffc857)\" opacity=\".85\"/>\n      <path d=\"M50 130 L100 70 L130 100 L160 60 L190 130 Z\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".8\"/>\n    </g>\n  </g>\n  <text x=\"120\" y=\"128\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"9\" fill=\"var(--w-sub,#94a3c0)\">cover</text>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "object-position",
    "aspect-ratio-placeholder",
    "line-clamp",
    "text-wrap-balance"
   ]
  },
  {
   "id": "object-position",
   "num": "W-194",
   "name": "Object Position",
   "nameJa": "オブジェクトポジション",
   "category": "media",
   "description": "object-fit:coverと組み合わせ、画像内のどの部分を基準に切り抜くかをobject-positionで指定する（例: top、20% 80%）。",
   "useCase": "人物写真や商品写真をカードに配置する際、顔や重要部分が縦横比変換で切れてしまうのを防ぎたいときに使う。",
   "code": ".opos-img {\n  width: 100%;\n  height: 200px;\n  object-fit: cover;\n  object-position: top center; /* 顔を優先表示 */\n}",
   "tags": [
    "CSS",
    "画像",
    "object-position",
    "トリミング",
    "被写体優先",
    "ジャストフィット",
    "狙い通り"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"Object Positionのデモ\">\n  <style>\n    .opos-img{animation:opos-shift 4s ease-in-out infinite}\n    @keyframes opos-shift{0%,20%{transform:translateY(18px)}50%,80%{transform:translateY(-6px)}100%{transform:translateY(18px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <defs><clipPath id=\"opos-clip\"><rect x=\"80\" y=\"35\" width=\"90\" height=\"80\" rx=\"6\"/></clipPath></defs>\n  <rect x=\"80\" y=\"35\" width=\"90\" height=\"80\" rx=\"6\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-dasharray=\"4 3\"/>\n  <g clip-path=\"url(#opos-clip)\">\n    <g class=\"opos-img\">\n      <rect x=\"70\" y=\"15\" width=\"110\" height=\"130\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".12\"/>\n      <circle cx=\"125\" cy=\"45\" r=\"16\" fill=\"var(--w-amber,#ffc857)\" opacity=\".9\"/>\n      <rect x=\"95\" y=\"65\" width=\"60\" height=\"70\" rx=\"8\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".7\"/>\n    </g>\n  </g>\n  <text x=\"125\" y=\"128\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"9\" fill=\"var(--w-sub,#94a3c0)\">top</text>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "object-fit",
    "aspect-ratio-placeholder",
    "blur-up",
    "clip-path-shapes"
   ]
  },
  {
   "id": "hover-zoom",
   "num": "W-195",
   "name": "Hover Zoom",
   "nameJa": "ホバーズーム",
   "category": "media",
   "description": "カード内画像にマウスを乗せると拡大表示される定番演出。親にoverflow:hidden、画像にtransition付きtransform: scale(1.1)を適用する。",
   "useCase": "商品カードやポートフォリオのサムネイルで、操作可能な印象とインタラクション感を出したいときに使う。",
   "code": ".hzoom-frame { overflow: hidden; border-radius: 8px; }\n.hzoom-img {\n  transition: transform .4s ease;\n}\n.hzoom-frame:hover .hzoom-img { transform: scale(1.12); }",
   "tags": [
    "CSS",
    "ホバー",
    "transform",
    "インタラクション",
    "ズーム",
    "ぬるっと",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ホバーズームのデモ\">\n  <style>\n    .hzoom-img{transform-origin:120px 80px;animation:hzoom-scale 3s ease-in-out infinite}\n    @keyframes hzoom-scale{0%,30%{transform:scale(1)}55%,80%{transform:scale(1.18)}100%{transform:scale(1)}}\n    .hzoom-cursor{animation:hzoom-cur 3s ease-in-out infinite}\n    @keyframes hzoom-cur{0%,25%{opacity:0}30%,80%{opacity:1}85%,100%{opacity:0}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <defs><clipPath id=\"hzoom-clip\"><rect x=\"60\" y=\"25\" width=\"120\" height=\"100\" rx=\"8\"/></clipPath></defs>\n  <g clip-path=\"url(#hzoom-clip)\">\n    <g class=\"hzoom-img\">\n      <rect x=\"60\" y=\"25\" width=\"120\" height=\"100\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".25\"/>\n      <circle cx=\"120\" cy=\"75\" r=\"30\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\"/>\n    </g>\n  </g>\n  <path class=\"hzoom-cursor\" d=\"M150 95 L150 118 L157 111 L162 122 L166 120 L161 109 L170 109 Z\" fill=\"var(--w-ink,#e8eef9)\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "filter-effects",
    "grayscale-hover",
    "caption-slide-in",
    "parallax-card-image"
   ]
  },
  {
   "id": "image-clip-reveal",
   "num": "W-196",
   "name": "Clip-Path Reveal",
   "nameJa": "画像スクロールリビール",
   "category": "media",
   "description": "スクロールに連動してclip-pathやmaskの範囲を広げ、画像が徐々に切り出されて現れる演出。IntersectionObserverでクラスを切り替える。",
   "useCase": "LPのセクション切り替えや作品紹介で、画像が「現れる」印象的な導入を作りたいときに使う。",
   "code": ".creveal-img {\n  clip-path: inset(0 100% 0 0);\n  transition: clip-path .9s cubic-bezier(.2,.8,.2,1);\n}\n.creveal-img.is-visible { clip-path: inset(0 0 0 0); }",
   "tags": [
    "CSS",
    "スクロール",
    "clip-path",
    "演出",
    "没入感",
    "じわっと",
    "ダイナミック"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"画像スクロールリビールのデモ\">\n  <style>\n    .creveal-mask{animation:creveal-sweep 4s cubic-bezier(.3,.7,.3,1) infinite}\n    @keyframes creveal-sweep{0%,10%{width:0}55%,80%{width:160px}100%{width:0}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"40\" y=\"30\" width=\"160\" height=\"90\" rx=\"6\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".2\"/>\n  <defs><clipPath id=\"creveal-clip\"><rect class=\"creveal-mask\" x=\"40\" y=\"30\" height=\"90\"/></clipPath></defs>\n  <g clip-path=\"url(#creveal-clip)\">\n    <rect x=\"40\" y=\"30\" width=\"160\" height=\"90\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\"/>\n    <circle cx=\"90\" cy=\"70\" r=\"16\" fill=\"var(--w-amber,#ffc857)\"/>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "parallax-scroll",
    "horizontal-scroll-section",
    "clip-path-reveal",
    "parallax-background"
   ]
  },
  {
   "id": "lazy-loading",
   "num": "W-197",
   "name": "Lazy Loading",
   "nameJa": "画像の遅延読み込み",
   "category": "media",
   "description": "img要素にloading=\"lazy\"を指定し、ビューポートに近づくまで画像の読み込みを遅らせてページの初期表示を高速化する表現。",
   "useCase": "画像点数の多い記事ページやギャラリーで、初期表示速度とスクロール体験を両立させたいときに使う。",
   "code": "<img src=\"photo.jpg\" alt=\"説明\" loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"600\">",
   "tags": [
    "HTML",
    "パフォーマンス",
    "画像",
    "遅延読み込み",
    "表示速度",
    "サクサク",
    "さりげない"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"画像の遅延読み込みのデモ\">\n  <style>\n    .lazy-scan{animation:lazy-move 4.5s linear infinite}\n    @keyframes lazy-move{0%{transform:translateX(0)}100%{transform:translateX(180px)}}\n    .lazy-fill1{animation:lazy-in1 4.5s linear infinite}\n    .lazy-fill2{animation:lazy-in2 4.5s linear infinite}\n    .lazy-fill3{animation:lazy-in3 4.5s linear infinite}\n    @keyframes lazy-in1{0%,5%{opacity:.15}15%,100%{opacity:.9}}\n    @keyframes lazy-in2{0%,40%{opacity:.15}50%,100%{opacity:.9}}\n    @keyframes lazy-in3{0%,75%{opacity:.15}85%,100%{opacity:.9}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"lazy-fill1\" x=\"16\" y=\"55\" width=\"56\" height=\"56\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <rect class=\"lazy-fill2\" x=\"92\" y=\"55\" width=\"56\" height=\"56\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <rect class=\"lazy-fill3\" x=\"168\" y=\"55\" width=\"56\" height=\"56\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <rect class=\"lazy-scan\" x=\"8\" y=\"40\" width=\"4\" height=\"86\" fill=\"var(--w-amber,#ffc857)\" opacity=\".8\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "responsive-srcset",
    "youtube-facade",
    "image-fallback",
    "details-summary-accordion"
   ]
  },
  {
   "id": "responsive-srcset",
   "num": "W-198",
   "name": "Responsive srcset/sizes",
   "nameJa": "レスポンシブ画像 (srcset/sizes)",
   "category": "media",
   "description": "srcsetで複数解像度の画像候補を用意し、sizesで表示幅の目安を伝え、ブラウザが端末に最適な画像を自動選択して読み込む。",
   "useCase": "モバイルから大画面まで同じ画像スロットで、通信量と表示画質のバランスを最適化したいときに使う。",
   "code": "<img\n  src=\"photo-800.jpg\"\n  srcset=\"photo-400.jpg 400w, photo-800.jpg 800w, photo-1600.jpg 1600w\"\n  sizes=\"(max-width: 600px) 100vw, 50vw\"\n  alt=\"説明\">",
   "tags": [
    "HTML",
    "レスポンシブ",
    "画像最適化",
    "srcset",
    "パフォーマンス",
    "きびきび",
    "さりげない"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"レスポンシブ画像のデモ\">\n  <style>\n    .sset-pick{animation:sset-cycle 4.5s steps(1) infinite}\n    @keyframes sset-cycle{0%,30%{opacity:1}31%,100%{opacity:.25}}\n    .sset-pick2{animation:sset-cycle2 4.5s steps(1) infinite}\n    @keyframes sset-cycle2{0%,30%{opacity:.25}31%,63%{opacity:1}64%,100%{opacity:.25}}\n    .sset-pick3{animation:sset-cycle3 4.5s steps(1) infinite}\n    @keyframes sset-cycle3{0%,63%{opacity:.25}64%,96%{opacity:1}97%,100%{opacity:.25}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"sset-pick\"><rect x=\"20\" y=\"40\" width=\"30\" height=\"50\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\"/><rect x=\"26\" y=\"48\" width=\"18\" height=\"18\" fill=\"var(--w-accent,#4fe3c1)\"/></g>\n  <g class=\"sset-pick2\"><rect x=\"95\" y=\"30\" width=\"50\" height=\"70\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\"/><rect x=\"103\" y=\"42\" width=\"34\" height=\"34\" fill=\"var(--w-accent,#4fe3c1)\"/></g>\n  <g class=\"sset-pick3\"><rect x=\"175\" y=\"20\" width=\"50\" height=\"70\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\"/><rect x=\"181\" y=\"30\" width=\"38\" height=\"50\" fill=\"var(--w-accent,#4fe3c1)\"/></g>\n  <text x=\"120\" y=\"128\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"9\" fill=\"var(--w-amber,#ffc857)\">400w -&gt; 800w -&gt; 1600w</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "lazy-loading",
    "picture-art-direction",
    "transition-basics",
    "details-summary-accordion"
   ]
  },
  {
   "id": "picture-art-direction",
   "num": "W-199",
   "name": "Picture Art Direction",
   "nameJa": "pictureでのアートディレクション",
   "category": "media",
   "description": "<picture>内に複数<source media=\"...\">を並べ、画面幅ごとに構図の異なる画像を出し分ける。狭い画面では縦構図トリミング版を出すなど。",
   "useCase": "ヒーロービジュアルで、スマホでは被写体アップ、PCでは全景を見せるなど画面幅ごとに最適な構図を出したいときに使う。",
   "code": "<picture>\n  <source media=\"(max-width: 599px)\" srcset=\"hero-portrait.jpg\">\n  <source media=\"(min-width: 600px)\" srcset=\"hero-wide.jpg\">\n  <img src=\"hero-wide.jpg\" alt=\"説明\">\n</picture>",
   "tags": [
    "HTML",
    "レスポンシブ",
    "picture",
    "アートディレクション",
    "構図",
    "ジャストフィット",
    "さりげない"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"pictureアートディレクションのデモ\">\n  <style>\n    .pad-mobile{animation:pad-swap1 5s steps(1) infinite}\n    .pad-desktop{animation:pad-swap2 5s steps(1) infinite}\n    @keyframes pad-swap1{0%,45%{opacity:1}46%,100%{opacity:0}}\n    @keyframes pad-swap2{0%,45%{opacity:0}46%,100%{opacity:1}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"pad-mobile\">\n    <rect x=\"90\" y=\"20\" width=\"60\" height=\"105\" rx=\"8\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\"/>\n    <circle cx=\"120\" cy=\"70\" r=\"22\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  </g>\n  <g class=\"pad-desktop\">\n    <rect x=\"30\" y=\"45\" width=\"180\" height=\"60\" rx=\"8\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\"/>\n    <circle cx=\"90\" cy=\"75\" r=\"16\" fill=\"var(--w-accent,#4fe3c1)\"/>\n    <path d=\"M130 95 L160 55 L190 95 Z\" fill=\"var(--w-amber,#ffc857)\" opacity=\".85\"/>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "responsive-srcset",
    "details-summary-accordion",
    "lazy-loading",
    "video-autoplay-loop"
   ]
  },
  {
   "id": "aspect-ratio-placeholder",
   "num": "W-200",
   "name": "Aspect Ratio Placeholder",
   "nameJa": "アスペクト比プレースホルダ",
   "category": "media",
   "description": "aspect-ratioプロパティで画像読み込み前から確保領域を予約し、読み込み完了時のレイアウトシフト（CLS）を防ぐ。",
   "useCase": "記事やカード一覧で画像がガクッと表示位置をずらす現象を防ぎ、読み込み中も安定したレイアウトを保ちたいときに使う。",
   "code": ".aratio-box {\n  aspect-ratio: 16 / 9;\n  background: var(--placeholder, #1a2540);\n  width: 100%;\n}\n.aratio-box img { width: 100%; height: 100%; object-fit: cover; }",
   "tags": [
    "CSS",
    "レイアウト",
    "CLS対策",
    "画像",
    "aspect-ratio",
    "安定感",
    "さりげない"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"アスペクト比プレースホルダのデモ\">\n  <style>\n    .arph-fill{animation:arph-fade 4s ease-in-out infinite}\n    @keyframes arph-fade{0%,15%{opacity:0}35%,80%{opacity:1}95%,100%{opacity:0}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"30\" y=\"25\" width=\"180\" height=\"70\" rx=\"6\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-dasharray=\"4 3\"/>\n  <rect class=\"arph-fill\" x=\"30\" y=\"25\" width=\"180\" height=\"70\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".8\"/>\n  <rect x=\"30\" y=\"105\" width=\"140\" height=\"8\" rx=\"4\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".4\"/>\n  <rect x=\"30\" y=\"120\" width=\"90\" height=\"8\" rx=\"4\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".25\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "object-fit",
    "vertical-writing",
    "scroll-margin-padding",
    "line-clamp"
   ]
  },
  {
   "id": "blur-up",
   "num": "W-201",
   "name": "Blur-Up",
   "nameJa": "ぼかしプレースホルダ",
   "category": "media",
   "description": "極小のぼやけたプレビュー画像を先に表示し、本画像の読み込み完了と同時にfilter: blur(0)へトランジションしてくっきり切り替える手法。",
   "useCase": "写真中心のギャラリーやヒーロー画像で、読み込み待ちの間も体感速度を良く見せたいときに使う。",
   "code": ".bup-img {\n  filter: blur(16px);\n  transition: filter .6s ease-out;\n}\n.bup-img.is-loaded { filter: blur(0); }",
   "tags": [
    "CSS",
    "画像",
    "ぼかし",
    "blur-up",
    "体感速度",
    "ふわっと",
    "じわっと"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ぼかしプレースホルダのデモ\">\n  <style>\n    .bup-img{animation:bup-clear 4s ease-in-out infinite}\n    @keyframes bup-clear{0%,15%{filter:blur(8px)}45%,85%{filter:blur(0)}100%{filter:blur(8px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"bup-img\">\n    <rect x=\"50\" y=\"30\" width=\"140\" height=\"90\" rx=\"8\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".3\"/>\n    <circle cx=\"100\" cy=\"70\" r=\"20\" fill=\"var(--w-accent,#4fe3c1)\"/>\n    <path d=\"M60 110 L110 60 L140 90 L180 50 L180 110 Z\" fill=\"var(--w-amber,#ffc857)\" opacity=\".8\"/>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "mask-gradient-fade",
    "object-fit",
    "object-position",
    "image-clip-reveal"
   ]
  },
  {
   "id": "grayscale-hover",
   "num": "W-202",
   "name": "Grayscale to Color Hover",
   "nameJa": "モノクロ→カラー ホバー",
   "category": "media",
   "description": "通常時はfilter: grayscale(1)で白黒表示し、ホバー時にgrayscale(0)へtransitionしてカラーへ切り替わる演出。",
   "useCase": "実績一覧やチームメンバー紹介で、静的な一覧に抑揚をつけカーソルを合わせた項目だけ目立たせたいときに使う。",
   "code": ".ghov-img {\n  filter: grayscale(1);\n  transition: filter .35s ease;\n}\n.ghov-img:hover { filter: grayscale(0); }",
   "tags": [
    "CSS",
    "ホバー",
    "filter",
    "グレースケール",
    "インタラクション",
    "パッと切替",
    "高級感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"モノクロからカラーホバーのデモ\">\n  <style>\n    .ghov-mono{animation:ghov-fade 3.5s ease-in-out infinite}\n    .ghov-color{animation:ghov-fade2 3.5s ease-in-out infinite}\n    @keyframes ghov-fade{0%,30%{opacity:1}50%,100%{opacity:0}}\n    @keyframes ghov-fade2{0%,30%{opacity:0}50%,100%{opacity:1}}\n    .ghov-cursor{animation:ghov-cur 3.5s ease-in-out infinite}\n    @keyframes ghov-cur{0%,25%{transform:translate(0,20px);opacity:0}35%,100%{transform:translate(0,0);opacity:1}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"ghov-mono\">\n    <rect x=\"70\" y=\"30\" width=\"100\" height=\"80\" rx=\"8\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".5\"/>\n    <circle cx=\"120\" cy=\"70\" r=\"18\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".8\"/>\n  </g>\n  <g class=\"ghov-color\">\n    <rect x=\"70\" y=\"30\" width=\"100\" height=\"80\" rx=\"8\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\"/>\n    <circle cx=\"120\" cy=\"70\" r=\"18\" fill=\"var(--w-amber,#ffc857)\"/>\n  </g>\n  <path class=\"ghov-cursor\" d=\"M175 95 L175 118 L182 111 L187 122 L191 120 L186 109 L195 109 Z\" fill=\"var(--w-ink,#e8eef9)\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "card-flip",
    "hover-zoom",
    "blur-reveal-text",
    "variable-font-weight"
   ]
  },
  {
   "id": "lightbox-gallery",
   "num": "W-203",
   "name": "Lightbox Gallery",
   "nameJa": "ギャラリーグリッド + ライトボックス",
   "category": "media",
   "description": "サムネイルグリッドをクリックすると背景を暗転させたオーバーレイに拡大画像を表示する。dialog要素やposition:fixedのオーバーレイで実装する。",
   "useCase": "作品集や施工事例など、一覧性を保ちつつクリックした写真だけ大きくじっくり見せたいときに使う。",
   "code": "<dialog class=\"lbox-modal\">\n  <img src=\"full.jpg\" alt=\"拡大画像\">\n</dialog>\n<script>\n  thumb.addEventListener('click', () => document.querySelector('.lbox-modal').showModal());\n</script>",
   "tags": [
    "HTML",
    "JS",
    "モーダル",
    "ギャラリー",
    "dialog",
    "パッと切替",
    "没入感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ライトボックスギャラリーのデモ\">\n  <style>\n    .lbox-grid{animation:lbox-fade 4s steps(1) infinite}\n    @keyframes lbox-fade{0%,55%{opacity:1}56%,100%{opacity:.15}}\n    .lbox-overlay{animation:lbox-in 4s ease-in-out infinite}\n    @keyframes lbox-in{0%,50%{opacity:0;transform:scale(.4)}65%,90%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(.4)}}\n    .lbox-dim{animation:lbox-dim 4s steps(1) infinite}\n    @keyframes lbox-dim{0%,50%{opacity:0}51%,95%{opacity:.75}100%{opacity:0}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"lbox-grid\">\n    <rect x=\"20\" y=\"20\" width=\"46\" height=\"46\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".6\"/>\n    <rect x=\"74\" y=\"20\" width=\"46\" height=\"46\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".7\"/>\n    <rect x=\"128\" y=\"20\" width=\"46\" height=\"46\" rx=\"4\" fill=\"var(--w-amber,#ffc857)\" opacity=\".6\"/>\n    <rect x=\"20\" y=\"74\" width=\"46\" height=\"46\" rx=\"4\" fill=\"var(--w-amber,#ffc857)\" opacity=\".5\"/>\n    <rect x=\"74\" y=\"74\" width=\"46\" height=\"46\" rx=\"4\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".6\"/>\n    <rect x=\"128\" y=\"74\" width=\"46\" height=\"46\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".5\"/>\n  </g>\n  <rect class=\"lbox-dim\" width=\"240\" height=\"150\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"lbox-overlay\" transform-origin=\"120px 75px\">\n    <rect x=\"70\" y=\"35\" width=\"100\" height=\"80\" rx=\"8\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "lightbox-dialog",
    "command-palette",
    "dialog-closedby",
    "youtube-facade"
   ]
  },
  {
   "id": "video-autoplay-loop",
   "num": "W-204",
   "name": "Autoplay Loop Video",
   "nameJa": "動画の自動再生ループ",
   "category": "media",
   "description": "video要素にautoplay・muted・loop・playsinline属性を付け、音声なしの短尺映像を背景のように無限ループ再生する。muted必須が自動再生条件。",
   "useCase": "LPのヒーロー背景や機能紹介の動きの説明で、画像より情報量の多い映像を音無しでさりげなく流したいときに使う。",
   "code": "<video autoplay muted loop playsinline poster=\"poster.jpg\">\n  <source src=\"hero.mp4\" type=\"video/mp4\">\n</video>",
   "tags": [
    "HTML",
    "動画",
    "自動再生",
    "ループ",
    "背景演出",
    "さりげない",
    "ダイナミック"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"動画の自動再生ループのデモ\">\n  <style>\n    .vloop-shape{animation:vloop-move 4s linear infinite}\n    @keyframes vloop-move{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}\n    .vloop-bar{animation:vloop-progress 4s linear infinite}\n    @keyframes vloop-progress{0%{width:0}100%{width:160px}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"40\" y=\"25\" width=\"160\" height=\"85\" rx=\"8\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".15\"/>\n  <g class=\"vloop-shape\" transform-origin=\"120px 65px\">\n    <path d=\"M110 50 L110 82 L136 66 Z\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  </g>\n  <rect x=\"40\" y=\"120\" width=\"160\" height=\"5\" rx=\"2.5\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".2\"/>\n  <rect class=\"vloop-bar\" x=\"40\" y=\"120\" height=\"5\" rx=\"2.5\" fill=\"var(--w-amber,#ffc857)\"/>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "details-summary-accordion",
    "lazy-loading",
    "responsive-srcset",
    "picture-art-direction"
   ]
  },
  {
   "id": "scroll-scrub-video",
   "num": "W-205",
   "name": "Scroll-Scrubbed Video",
   "nameJa": "スクロールで動画スクラブ",
   "category": "media",
   "description": "スクロール位置に応じてvideo要素のcurrentTimeをJSで書き換え、動画の再生を早送り・巻き戻しのようにスクロール操作へ同期させる。",
   "useCase": "製品の分解・組み立てや360度回転をスクロールに合わせて見せたい、映画的な縦スクロール演出をしたいときに使う。",
   "code": "window.addEventListener('scroll', () => {\n  const progress = getScrollProgress(section);\n  video.currentTime = video.duration * progress;\n});",
   "tags": [
    "JS",
    "スクロール",
    "動画",
    "スクラブ",
    "currentTime",
    "没入感",
    "ダイナミック"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"スクロールで動画スクラブのデモ\">\n  <style>\n    .sscr-dot{animation:sscr-move 4.5s ease-in-out infinite}\n    @keyframes sscr-move{0%,100%{transform:translateY(0)}50%{transform:translateY(70px)}}\n    .sscr-f1{animation:sscr-a 4.5s steps(1) infinite}\n    .sscr-f2{animation:sscr-b 4.5s steps(1) infinite}\n    .sscr-f3{animation:sscr-c 4.5s steps(1) infinite}\n    @keyframes sscr-a{0%,16%{opacity:1}17%,83%{opacity:0}84%,100%{opacity:1}}\n    @keyframes sscr-b{0%,16%{opacity:0}17%,33%{opacity:1}34%,66%{opacity:0}67%,83%{opacity:1}84%,100%{opacity:0}}\n    @keyframes sscr-c{0%,33%{opacity:0}34%,66%{opacity:1}67%,100%{opacity:0}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"40\" y=\"30\" width=\"4\" height=\"90\" rx=\"2\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".4\"/>\n  <circle class=\"sscr-dot\" cx=\"42\" cy=\"35\" r=\"6\" fill=\"var(--w-amber,#ffc857)\"/>\n  <rect x=\"90\" y=\"30\" width=\"120\" height=\"90\" rx=\"8\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".15\"/>\n  <g class=\"sscr-f1\"><path d=\"M130 55 L130 95 L160 75 Z\" fill=\"var(--w-accent,#4fe3c1)\"/></g>\n  <g class=\"sscr-f2\"><circle cx=\"150\" cy=\"75\" r=\"20\" fill=\"var(--w-accent,#4fe3c1)\"/></g>\n  <g class=\"sscr-f3\"><rect x=\"130\" y=\"55\" width=\"40\" height=\"40\" fill=\"var(--w-accent,#4fe3c1)\"/></g>\n</svg>",
   "useFor": [
    "lp"
   ],
   "weight": "主役",
   "relatedIds": [
    "horizontal-scroll-section",
    "parallax-background",
    "image-clip-reveal",
    "parallax-scroll"
   ]
  },
  {
   "id": "youtube-facade",
   "num": "W-206",
   "name": "YouTube Embed Facade",
   "nameJa": "YouTube埋め込みのファサード",
   "category": "media",
   "description": "初期表示はサムネイル画像＋再生ボタンの静的HTMLのみとし、クリックされた時点で初めてiframe（YouTube本体）を生成・挿入する遅延読み込み手法。",
   "useCase": "記事や解説ページに動画を複数埋め込む際、YouTube側の重い初期スクリプトでページ表示が遅くなるのを避けたいときに使う。",
   "code": "facade.addEventListener('click', () => {\n  facade.innerHTML =\n    `<iframe src=\"https://www.youtube.com/embed/${id}?autoplay=1\"\n      allow=\"autoplay\" allowfullscreen></iframe>`;\n}, { once: true });",
   "tags": [
    "HTML",
    "JS",
    "動画",
    "パフォーマンス",
    "iframe遅延",
    "サクサク",
    "パッと切替"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"YouTube埋め込みファサードのデモ\">\n  <style>\n    .yfac-thumb{animation:yfac-out 4s steps(1) infinite}\n    @keyframes yfac-out{0%,45%{opacity:1}46%,100%{opacity:0}}\n    .yfac-frame{animation:yfac-in 4s steps(1) infinite}\n    @keyframes yfac-in{0%,45%{opacity:0}46%,100%{opacity:1}}\n    .yfac-btn{animation:yfac-pulse 4s ease-in-out infinite}\n    @keyframes yfac-pulse{0%,40%{transform:scale(1)}44%{transform:scale(.8)}48%,100%{transform:scale(1)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"yfac-thumb\">\n    <rect x=\"40\" y=\"25\" width=\"160\" height=\"90\" rx=\"8\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".3\"/>\n    <g class=\"yfac-btn\" transform-origin=\"120px 70px\">\n      <circle cx=\"120\" cy=\"70\" r=\"22\" fill=\"var(--w-amber,#ffc857)\"/>\n      <path d=\"M113 58 L113 82 L136 70 Z\" fill=\"var(--w-bg,#101830)\"/>\n    </g>\n  </g>\n  <g class=\"yfac-frame\">\n    <rect x=\"40\" y=\"25\" width=\"160\" height=\"90\" rx=\"8\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\"/>\n    <text x=\"120\" y=\"75\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-bg,#101830)\">iframe</text>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "lazy-loading",
    "lightbox-gallery",
    "command-palette",
    "css-typed-om"
   ]
  },
  {
   "id": "caption-slide-in",
   "num": "W-207",
   "name": "Caption Slide-In",
   "nameJa": "キャプションのスライドイン",
   "category": "media",
   "description": "figure内の画像にfigcaptionを重ね、通常は画面外へtranslateYで隠しておき、ホバーやスクロール表示時にtranslateY(0)へ滑り込ませる。",
   "useCase": "写真ギャラリーや事例紹介で、画像本体はすっきり見せつつ説明文をインタラクション時だけ提示したいときに使う。",
   "code": ".cslide-fig { position: relative; overflow: hidden; }\n.cslide-cap {\n  position: absolute; inset: auto 0 0 0;\n  transform: translateY(100%);\n  transition: transform .35s ease;\n}\n.cslide-fig:hover .cslide-cap { transform: translateY(0); }",
   "tags": [
    "CSS",
    "ホバー",
    "キャプション",
    "figcaption",
    "スライドイン",
    "ぬるっと",
    "さりげない"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"キャプションスライドインのデモ\"><style>.cslide-cap{animation:cslide-up 4s ease-in-out infinite}@keyframes cslide-up{0%,25%{transform:translateY(38px)}50%,80%{transform:translateY(0)}100%{transform:translateY(38px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><defs><clipPath id=\"cslide-clip\"><rect x=\"42\" y=\"20\" width=\"156\" height=\"105\" rx=\"9\"/></clipPath></defs><rect x=\"42\" y=\"20\" width=\"156\" height=\"105\" rx=\"9\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".32\"/><circle cx=\"120\" cy=\"63\" r=\"24\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".65\"/><g clip-path=\"url(#cslide-clip)\"><g class=\"cslide-cap\"><rect x=\"42\" y=\"84\" width=\"156\" height=\"41\" fill=\"var(--w-bg,#101830)\" opacity=\".92\"/><text x=\"120\" y=\"109\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"12\" font-weight=\"700\" fill=\"var(--w-ink,#e8eef9)\">作品タイトル</text></g></g></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "clip-path-shapes",
    "hover-zoom",
    "parallax-card-image",
    "variable-font-weight"
   ]
  },
  {
   "id": "text-image-mask",
   "num": "W-208",
   "name": "Image Text Mask",
   "nameJa": "画像内テキストマスク",
   "category": "media",
   "description": "background-clip: textとcolor: transparentを組み合わせ、太い見出し文字の中に画像を流し込んで見せる表現。",
   "useCase": "ヒーロー見出しやタイトルカードで、文字自体を強い視覚要素として画像と一体化させたいときに使う。",
   "code": ".tmask-title {\n  background: url('photo.jpg') center/cover;\n  background-clip: text;\n  -webkit-background-clip: text;\n  color: transparent;\n  font-weight: 900;\n}",
   "tags": [
    "CSS",
    "見出し",
    "background-clip",
    "テキストマスク",
    "タイポグラフィ",
    "高級感",
    "目を引く"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"画像内テキストマスクのデモ\">\n  <style>\n    .tmask-fill{animation:tmask-pan 5s linear infinite}\n    @keyframes tmask-pan{0%{transform:translateX(-20px)}100%{transform:translateX(20px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <defs>\n    <clipPath id=\"tmask-clip\">\n      <path fill-rule=\"evenodd\" d=\"M60 120 L110 25 L160 120 L138 120 L128 96 L92 96 L82 120 Z M97 80 L123 80 L110 50 Z\"/>\n    </clipPath>\n  </defs>\n  <g clip-path=\"url(#tmask-clip)\">\n    <g class=\"tmask-fill\">\n      <rect x=\"0\" y=\"10\" width=\"260\" height=\"120\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".3\"/>\n      <circle cx=\"60\" cy=\"75\" r=\"30\" fill=\"var(--w-accent,#4fe3c1)\"/>\n      <circle cx=\"140\" cy=\"75\" r=\"30\" fill=\"var(--w-amber,#ffc857)\"/>\n      <circle cx=\"220\" cy=\"75\" r=\"30\" fill=\"var(--w-accent,#4fe3c1)\"/>\n    </g>\n  </g>\n</svg>",
   "useFor": [
    "slide",
    "lp"
   ],
   "weight": "主役",
   "relatedIds": [
    "text-image-fill",
    "gradient-text",
    "text-extrude",
    "outline-text-bg"
   ]
  },
  {
   "id": "parallax-card-image",
   "num": "W-209",
   "name": "Card Parallax Image",
   "nameJa": "カード内パララックス画像",
   "category": "media",
   "description": "マウス移動やスクロール量に応じてカード内の背景画像だけを前景よりゆっくり／別方向に動かし奥行きを出す。transformのtranslateをJSで駆動する。",
   "useCase": "商品カードやプロフィールカードに立体感を出し、他の平坦なカードより印象に残る一枚にしたいときに使う。",
   "code": "card.addEventListener('mousemove', (e) => {\n  const x = (e.offsetX / card.clientWidth - .5) * 20;\n  const y = (e.offsetY / card.clientHeight - .5) * 20;\n  bgImg.style.transform = `translate(${x}px, ${y}px) scale(1.1)`;\n});",
   "tags": [
    "JS",
    "CSS",
    "ホバー",
    "パララックス",
    "奥行き",
    "ぬるっと",
    "没入感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"カード内パララックス画像のデモ\">\n  <style>\n    .pcard-bg{animation:pcard-bg-move 4s ease-in-out infinite}\n    .pcard-fg{animation:pcard-fg-move 4s ease-in-out infinite}\n    @keyframes pcard-bg-move{0%,100%{transform:translateX(-8px)}50%{transform:translateX(8px)}}\n    @keyframes pcard-fg-move{0%,100%{transform:translateX(4px)}50%{transform:translateX(-4px)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <defs><clipPath id=\"pcard-clip\"><rect x=\"40\" y=\"25\" width=\"160\" height=\"100\" rx=\"10\"/></clipPath></defs>\n  <rect x=\"40\" y=\"25\" width=\"160\" height=\"100\" rx=\"10\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-dasharray=\"4 3\"/>\n  <g clip-path=\"url(#pcard-clip)\">\n    <g class=\"pcard-bg\">\n      <rect x=\"20\" y=\"15\" width=\"200\" height=\"120\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".25\"/>\n      <circle cx=\"120\" cy=\"75\" r=\"34\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".5\"/>\n    </g>\n    <g class=\"pcard-fg\">\n      <rect x=\"60\" y=\"95\" width=\"80\" height=\"18\" rx=\"4\" fill=\"var(--w-amber,#ffc857)\"/>\n    </g>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "view-transitions-spa",
    "parallax-background",
    "hover-zoom",
    "caption-slide-in"
   ]
  },
  {
   "id": "image-fallback",
   "num": "W-210",
   "name": "Broken Image Fallback",
   "nameJa": "壊れた画像のフォールバック",
   "category": "media",
   "description": "img要素のonerrorイベントで読み込み失敗を検知し、代替画像やプレースホルダSVGへsrcを差し替えて表示崩れを防ぐ。",
   "useCase": "CMS入稿画像やユーザー投稿画像などURL切れが起こり得る場面で、壊れたアイコン表示のまま放置しないようにしたいときに使う。",
   "code": "<img src=\"user-photo.jpg\" alt=\"ユーザー画像\"\n     onerror=\"this.onerror=null;this.src='/img/fallback.svg';\">",
   "tags": [
    "HTML",
    "JS",
    "エラー処理",
    "フォールバック",
    "画像",
    "さりげない",
    "安心感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"壊れた画像フォールバックのデモ\">\n  <style>\n    .ifb-broken{animation:ifb-swap1 4s steps(1) infinite}\n    .ifb-fallback{animation:ifb-swap2 4s steps(1) infinite}\n    @keyframes ifb-swap1{0%,40%{opacity:1}41%,100%{opacity:0}}\n    @keyframes ifb-swap2{0%,40%{opacity:0}41%,100%{opacity:1}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"70\" y=\"30\" width=\"100\" height=\"80\" rx=\"8\" fill=\"var(--w-sub,#94a3c0)\" opacity=\".2\"/>\n  <g class=\"ifb-broken\">\n    <path d=\"M85 90 L110 55 L125 75 L140 60 L155 90 Z\" fill=\"none\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"3\"/>\n    <circle cx=\"95\" cy=\"50\" r=\"6\" fill=\"none\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"3\"/>\n    <line x1=\"80\" y1=\"40\" x2=\"160\" y2=\"100\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"3\"/>\n  </g>\n  <g class=\"ifb-fallback\">\n    <rect x=\"95\" y=\"50\" width=\"50\" height=\"40\" rx=\"4\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".85\"/>\n    <circle cx=\"108\" cy=\"63\" r=\"5\" fill=\"var(--w-bg,#101830)\"/>\n    <path d=\"M100 82 L115 68 L130 82 Z\" fill=\"var(--w-bg,#101830)\"/>\n  </g>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "lazy-loading",
    "url-hash-sync",
    "details-summary-accordion",
    "responsive-srcset"
   ]
  },
  {
   "id": "css-scroll-controls",
   "num": "W-211",
   "name": "CSS Scroll Buttons and Markers",
   "nameJa": "CSSだけのスクロールボタン／マーカー",
   "category": "scroll",
   "description": "スクロールコンテナから::scroll-button()と::scroll-markerを生成し、JavaScriptなしでカルーセルの前後ボタンと現在位置マーカーを作る。生成された操作部品にはブラウザがキーボード操作の意味も付与する。",
   "useCase": "商品カードや事例一覧を横送りにしつつ、操作ボタン・ページ位置・スクロールスナップを一体で実装したい場面。非対応ブラウザでも通常の横スクロールへフォールバックできる。",
   "code": ".rail { overflow-x: auto; scroll-snap-type: x mandatory; scroll-marker-group: after; }\n.rail::scroll-button(left)  { content: \"←\"; }\n.rail::scroll-button(right) { content: \"→\"; }\n.card { scroll-snap-align: center; }\n.card::scroll-marker { content: \"\"; }\n.card::scroll-marker:target-current { background: currentColor; }",
   "tags": [
    "CSS",
    "カルーセル",
    "scroll-snap",
    "アクセシビリティ",
    "省コード"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"CSSだけのスクロールボタンとマーカーのデモ\"><style>.csc-track{animation:csc-slide 4s ease-in-out infinite}@keyframes csc-slide{0%,35%{transform:translateX(0)}60%,85%{transform:translateX(-72px)}100%{transform:translateX(0)}}.csc-dot1{animation:csc-mark1 4s ease-in-out infinite}.csc-dot2{animation:csc-mark2 4s ease-in-out infinite}@keyframes csc-mark1{0%,35%{fill:var(--w-accent,#4fe3c1);opacity:1}60%,85%{fill:var(--w-sub,#a7b4cd);opacity:.45}100%{fill:var(--w-accent,#4fe3c1);opacity:1}}@keyframes csc-mark2{0%,35%{fill:var(--w-sub,#a7b4cd);opacity:.45}60%,85%{fill:var(--w-accent,#4fe3c1);opacity:1}100%{fill:var(--w-sub,#a7b4cd);opacity:.45}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g class=\"csc-track\"><rect x=\"42\" y=\"35\" width=\"64\" height=\"70\" rx=\"8\" fill=\"var(--w-accent,#4fe3c1)\"/><rect x=\"114\" y=\"35\" width=\"64\" height=\"70\" rx=\"8\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".45\"/></g><circle cx=\"22\" cy=\"70\" r=\"13\" fill=\"none\" stroke=\"var(--w-ink,#e8eef9)\"/><path d=\"M26 64l-6 6 6 6\" fill=\"none\" stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"2\"/><circle cx=\"218\" cy=\"70\" r=\"13\" fill=\"none\" stroke=\"var(--w-ink,#e8eef9)\"/><path d=\"M214 64l6 6-6 6\" fill=\"none\" stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"2\"/><g transform=\"translate(108 116)\"><circle class=\"csc-dot1\" r=\"4\"/><circle class=\"csc-dot2\" cx=\"16\" r=\"4\"/></g><text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">::scroll-button()  +  ::scroll-marker</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "reading-flow",
    "sibling-index-stagger",
    "customizable-select",
    "contrast-color"
   ]
  },
  {
   "id": "scroll-state-queries",
   "num": "W-212",
   "name": "Container Scroll-State Queries",
   "nameJa": "スクロール状態コンテナクエリ",
   "category": "scroll",
   "description": "container-type: scroll-stateで、スクロール可能・スナップ中・stickyで固定中などの状態をCSSから問い合わせる。スクロール監視用JavaScriptを減らし、子要素の見た目を状態に応じて切り替えられる。",
   "useCase": "固定された見出しへ影を付ける、まだ下へ進めるときだけスクロール誘導を出す、スナップ中のカードを強調する、といった状態表示に使う。",
   "code": ".scroller { container: scroller / scroll-state; overflow: auto; }\n@container scroller scroll-state(scrollable: bottom) {\n  .more-hint { opacity: 1; }\n}\n.sticky { position: sticky; top: 0; container-type: scroll-state; }\n@container scroll-state(stuck: top) { .title { box-shadow: 0 4px 12px #0004; } }",
   "tags": [
    "CSS",
    "コンテナクエリ",
    "スクロール状態",
    "sticky",
    "省JavaScript"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"スクロール状態コンテナクエリのデモ\"><style>.ssq-lines{animation:ssq-scroll 4s ease-in-out infinite}@keyframes ssq-scroll{0%,20%{transform:translateY(0)}55%,80%{transform:translateY(-24px)}100%{transform:translateY(0)}}.ssq-head{animation:ssq-shadow 4s ease-in-out infinite}@keyframes ssq-shadow{0%,20%{filter:drop-shadow(0 0 0 transparent)}40%,85%{filter:drop-shadow(0 7px 5px var(--w-bg,#101830))}100%{filter:drop-shadow(0 0 0 transparent)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"48\" y=\"24\" width=\"144\" height=\"92\" rx=\"8\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" opacity=\".45\"/><g class=\"ssq-head\"><rect x=\"52\" y=\"29\" width=\"136\" height=\"24\" rx=\"5\" fill=\"var(--w-accent,#4fe3c1)\"/><path d=\"M65 41h62\" stroke=\"var(--w-bg,#101830)\" stroke-width=\"5\" stroke-linecap=\"round\"/></g><g class=\"ssq-lines\" stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"5\" stroke-linecap=\"round\" opacity=\".55\"><path d=\"M64 70h98\"/><path d=\"M64 86h82\"/><path d=\"M64 102h108\"/></g><text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">scroll-state(stuck: top)</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "container-style-queries",
    "scroll-triggered-animation",
    "field-sizing",
    "container-queries"
   ]
  },
  {
   "id": "scroll-target-group",
   "num": "W-213",
   "name": "Scroll Target Group",
   "nameJa": "現在セクションを示す:target-current",
   "category": "scroll",
   "description": "ナビゲーションへscroll-target-group: autoを指定すると、内部リンクのうち現在表示中の対象を:target-currentで選べる。IntersectionObserverを使わず、目次やスクロールスパイの現在位置をCSSで示せる。",
   "useCase": "長い記事の目次、1ページLPの固定ナビ、カルーセルの自作マーカーで、閲覧中の章を自動ハイライトしたい場面。",
   "code": ".toc { scroll-target-group: auto; }\n.toc a { color: #94a3c0; }\n.toc a:target-current { color: #4fe3c1; font-weight: 700; }",
   "tags": [
    "CSS",
    "目次",
    "scroll-spy",
    ":target-current",
    "ナビゲーション"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"現在セクションを示すtarget-currentのデモ\">\n  <style>.stg-pages{animation:stg-page 4.5s ease-in-out infinite}@keyframes stg-page{0%,30%{transform:translateY(0)}55%,80%{transform:translateY(-14px)}100%{transform:translateY(0)}}.stg-dot{animation:stg-current 4.5s steps(1) infinite}@keyframes stg-current{0%,45%{transform:translateY(0)}46%,85%{transform:translateY(25px)}86%,100%{transform:translateY(0)}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g transform=\"translate(26 30)\"><rect width=\"62\" height=\"86\" rx=\"7\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".12\"/><g class=\"stg-dot\"><circle cx=\"13\" cy=\"18\" r=\"4\" fill=\"var(--w-accent,#4fe3c1)\"/><path d=\"M24 18h26\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"4\" stroke-linecap=\"round\"/></g><g fill=\"var(--w-sub,#a7b4cd)\" opacity=\".55\"><circle cx=\"13\" cy=\"43\" r=\"3\"/><circle cx=\"13\" cy=\"68\" r=\"3\"/></g></g><g class=\"stg-pages\"><rect x=\"104\" y=\"27\" width=\"106\" height=\"78\" rx=\"8\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".75\"/><path d=\"M119 48h62M119 63h76M119 78h50\" stroke=\"var(--w-bg,#101830)\" stroke-width=\"5\" stroke-linecap=\"round\"/></g>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">scroll-target-group: auto</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "smooth-scroll",
    "sticky-position",
    "css-scroll-controls",
    "scroll-state-queries"
   ]
  },
  {
   "id": "scroll-into-view-container",
   "num": "W-214",
   "name": "scrollIntoView Container Option",
   "nameJa": "scrollIntoViewのcontainer指定",
   "category": "scroll",
   "description": "scrollIntoView()のcontainerオプションで、対象へ移動するときに最も近いスクロール領域だけを動かすか、すべての祖先を動かすかを選べる。入れ子スクロールで外側ページまで意図せず動く問題を避けられる。",
   "useCase": "モーダル内リスト、横カルーセル内の選択項目、埋め込みエディタなど、ページ全体の位置を保ったまま内側だけスクロールさせたい場面。",
   "code": "item.scrollIntoView({\n  behavior: 'smooth',\n  block: 'nearest',\n  inline: 'center',\n  container: 'nearest'\n});",
   "tags": [
    "JavaScript",
    "scrollIntoView",
    "入れ子スクロール",
    "UX"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"scrollIntoViewのcontainer指定のデモ\">\n  <style>.siv-items{animation:siv-near 4s ease-in-out infinite}@keyframes siv-near{0%,25%{transform:translateX(22px)}55%,80%{transform:translateX(-22px)}100%{transform:translateX(22px)}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"28\" y=\"24\" width=\"184\" height=\"94\" rx=\"10\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" opacity=\".45\"/><rect x=\"54\" y=\"43\" width=\"132\" height=\"56\" rx=\"8\" fill=\"none\" stroke=\"var(--w-ink,#e8eef9)\" opacity=\".55\"/><g class=\"siv-items\"><rect x=\"62\" y=\"51\" width=\"36\" height=\"40\" rx=\"5\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><rect x=\"106\" y=\"51\" width=\"36\" height=\"40\" rx=\"5\" fill=\"var(--w-accent,#4fe3c1)\"/><rect x=\"150\" y=\"51\" width=\"36\" height=\"40\" rx=\"5\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/></g>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">container: \"nearest\"</text>\n</svg>",
   "useFor": [
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "element-scoped-view-transition",
    "css-registerproperty-js",
    "css-typed-om",
    "canvas-ctx-filter"
   ]
  },
  {
   "id": "text-box-trim",
   "num": "W-215",
   "name": "Text Box Trim",
   "nameJa": "文字の上下余白を字面でトリミング",
   "category": "text",
   "description": "text-box-trimとtext-box-edgeで、フォントの行ボックスに含まれる見えない上下余白を大文字上端やベースラインに合わせて切り詰める。異なるフォントでも見出し周囲の間隔を設計値へ揃えやすい。",
   "useCase": "ヒーロー見出し、ボタン、カードタイトルなど、文字の見た目上の端と隣接要素の間隔を精密に揃えたい場面。",
   "code": ".heading {\n  text-box-trim: trim-both;\n  text-box-edge: cap alphabetic;\n}",
   "tags": [
    "CSS",
    "タイポグラフィ",
    "行ボックス",
    "余白調整"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"文字上下余白のトリミングのデモ\">\n  <style>.tbt-box{animation:tbt-trim 4s ease-in-out infinite;transform-origin:120px 72px}@keyframes tbt-trim{0%,30%{transform:scaleY(1)}55%,80%{transform:scaleY(.72)}100%{transform:scaleY(1)}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"tbt-guides\" stroke=\"var(--w-amber,#ffc857)\" stroke-dasharray=\"4 3\" opacity=\".65\"><path d=\"M32 42h176\"/><path d=\"M32 103h176\"/></g><rect class=\"tbt-box\" x=\"48\" y=\"29\" width=\"144\" height=\"86\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\"/><text x=\"120\" y=\"91\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"56\" font-weight=\"800\" fill=\"var(--w-accent,#4fe3c1)\">Ag</text>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">text-box-trim: trim-both</text>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "text-autospace",
    "text-emphasis-dots",
    "fluid-typography",
    "text-extrude"
   ]
  },
  {
   "id": "css-custom-highlights",
   "num": "W-216",
   "name": "CSS Custom Highlight API",
   "nameJa": "Custom Highlight API",
   "category": "text",
   "description": "RangeとHighlightをCSS.highlightsへ登録し、DOMをspanで分割せずに任意の文字範囲を::highlight()で装飾する。検索結果・校正箇所・共同編集の選択範囲を元の文書構造のまま重ねられる。",
   "useCase": "ページ内検索、文章校正、コードレビュー、複数ユーザーのカーソル表示など、同じ文章へ複数種類のハイライトを重ねたい場面。",
   "code": "const range = new Range();\nrange.setStart(textNode, 4);\nrange.setEnd(textNode, 10);\nCSS.highlights.set('search', new Highlight(range));\n\n::highlight(search) { background: #ffc857; color: #101830; }",
   "tags": [
    "JavaScript",
    "CSS",
    "Range",
    "検索",
    "ハイライト"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"Custom Highlight APIのデモ\">\n  <style>.chi-mark{animation:chi-find 4s ease-in-out infinite}@keyframes chi-find{0%,20%{width:0}45%,80%{width:118px}100%{width:0}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <text x=\"30\" y=\"58\" font-family=\"ui-monospace,monospace\" font-size=\"13\" fill=\"var(--w-ink,#e8eef9)\">Search without</text><rect class=\"chi-mark\" x=\"29\" y=\"69\" width=\"0\" height=\"22\" rx=\"4\" fill=\"var(--w-amber,#ffc857)\" opacity=\".9\"/><text x=\"30\" y=\"85\" font-family=\"ui-monospace,monospace\" font-size=\"13\" fill=\"var(--w-ink,#e8eef9)\">changing the DOM.</text>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">CSS.highlights + ::highlight()</text>\n</svg>",
   "useFor": [
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "stagger-char-reveal",
    "view-transitions-spa",
    "will-change-gpu",
    "ripple-effect"
   ]
  },
  {
   "id": "text-autospace",
   "num": "W-217",
   "name": "Text Autospace",
   "nameJa": "日本語と英数字の間隔を自動調整",
   "category": "text",
   "description": "text-autospaceで、日本語などの表意文字と英字・数字が隣接する箇所へ読みやすい間隔を自動挿入する。手入力の半角スペースを混ぜずに、日本語組版のリズムを一貫させられる。",
   "useCase": "日本語の記事、製品名に英字を含むLP、数値の多い資料など、和文と欧文が頻繁に混ざる本文や見出し。",
   "code": ".article {\n  text-autospace: normal;\n}\n.code { text-autospace: no-autospace; }",
   "tags": [
    "CSS",
    "日本語組版",
    "タイポグラフィ",
    "可読性"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"日本語と英数字の自動間隔のデモ\">\n  <style>.tas-after{animation:tas-gap 4s ease-in-out infinite}@keyframes tas-gap{0%,25%{opacity:.25;transform:translateY(-8px)}50%,85%{opacity:1;transform:translateY(0)}100%{opacity:.25;transform:translateY(-8px)}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <text x=\"30\" y=\"62\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"21\" fill=\"var(--w-sub,#a7b4cd)\">AIで作る</text><g class=\"tas-after\"><text x=\"30\" y=\"100\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"21\" fill=\"var(--w-accent,#4fe3c1)\">AI で作る</text><path d=\"M54 106h9\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"2\"/></g>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">text-autospace: normal</text>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "text-box-trim",
    "diagram-label-min-size",
    "text-emphasis-dots",
    "word-break-auto-phrase"
   ]
  },
  {
   "id": "grid-lanes",
   "num": "W-218",
   "name": "CSS Grid Lanes",
   "nameJa": "Grid Lanes（ネイティブ・マソンリー）",
   "category": "layout",
   "description": "display: grid-lanesで、高さの異なる項目を空きの少ないレーンへ配置するネイティブなマソンリーレイアウト。DOM・Tab・読み上げはソース順のままだが、視覚順は空きレーン優先でずれ得るため、操作要素では順序も検証する。",
   "useCase": "写真ギャラリー、カード型ポートフォリオ、記事一覧など、高さが不揃いな要素を自然に詰めて並べたい場面。視覚順とキーボード順の差が理解を妨げない内容に使う。",
   "code": ".gallery {\n  display: grid-lanes;\n  grid-template-columns: repeat(3, minmax(0, 1fr));\n  gap: 1rem;\n}",
   "tags": [
    "CSS",
    "Grid Lanes",
    "マソンリー",
    "ギャラリー"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"Grid Lanesのマソンリー配置のデモ\">\n  <style>.gln-cards{animation:gln-pack 4.5s ease-in-out infinite;transform-origin:120px 70px}@keyframes gln-pack{0%,20%{transform:scale(.9);opacity:.55}45%,85%{transform:scale(1);opacity:1}100%{transform:scale(.9);opacity:.55}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"gln-cards\"><rect x=\"38\" y=\"25\" width=\"48\" height=\"42\" rx=\"5\" fill=\"var(--w-accent,#4fe3c1)\"/><rect x=\"96\" y=\"25\" width=\"48\" height=\"72\" rx=\"5\" fill=\"var(--w-amber,#ffc857)\"/><rect x=\"154\" y=\"25\" width=\"48\" height=\"52\" rx=\"5\" fill=\"var(--w-sub,#a7b4cd)\"/><rect x=\"38\" y=\"75\" width=\"48\" height=\"38\" rx=\"5\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".55\"/><rect x=\"154\" y=\"85\" width=\"48\" height=\"28\" rx=\"5\" fill=\"var(--w-accent,#4fe3c1)\" opacity=\".7\"/></g>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">display: grid-lanes</text>\n</svg>",
   "useFor": [
    "site",
    "lp"
   ],
   "weight": "主役",
   "relatedIds": [
    "masonry-columns",
    "ring-gallery",
    "carousel-3d",
    "content-visibility"
   ]
  },
  {
   "id": "content-visibility",
   "num": "W-219",
   "name": "Content Visibility",
   "nameJa": "content-visibilityで画面外描画を省略",
   "category": "layout",
   "description": "content-visibility: autoで画面外セクションのレイアウト・描画を必要になるまで省略し、長いページの初期レンダリング負荷を下げる。contain-intrinsic-sizeで未描画時の予測サイズを与えるとスクロール位置の揺れも抑えられる。",
   "useCase": "長文記事、大量カードのカタログ、下部に多くのセクションを持つLPなど、初期表示外のDOMが重いページ。",
   "code": ".section {\n  content-visibility: auto;\n  contain-intrinsic-size: auto 520px;\n}",
   "tags": [
    "CSS",
    "パフォーマンス",
    "レンダリング",
    "長いページ"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"画面外描画の省略のデモ\">\n  <style>.cvis-lazy{animation:cvis-render 4s ease-in-out infinite}@keyframes cvis-render{0%,30%{opacity:.12}55%,85%{opacity:1}100%{opacity:.12}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"50\" y=\"20\" width=\"140\" height=\"95\" rx=\"8\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\"/><rect x=\"57\" y=\"27\" width=\"126\" height=\"34\" rx=\"5\" fill=\"var(--w-accent,#4fe3c1)\"/><g class=\"cvis-lazy\"><rect x=\"57\" y=\"68\" width=\"126\" height=\"40\" rx=\"5\" fill=\"var(--w-amber,#ffc857)\"/><path d=\"M68 80h72M68 94h92\" stroke=\"var(--w-bg,#101830)\" stroke-width=\"5\" stroke-linecap=\"round\"/></g><path d=\"M39 62v34\" stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"2\"/><path d=\"m34 90 5 7 5-7\" fill=\"none\" stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"2\"/>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">content-visibility: auto</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "unicode-range-subset",
    "font-metric-override",
    "transition-basics",
    "grid-lanes"
   ]
  },
  {
   "id": "container-style-queries",
   "num": "W-220",
   "name": "Container Style Queries",
   "nameJa": "コンテナのCSS変数でスタイル分岐",
   "category": "layout",
   "description": "@container style()で祖先のカスタムプロパティ値を問い合わせ、コンポーネントの見た目を状態やテーマに応じて分岐する。サイズではなく「variantがfeaturedか」のような設計トークンを条件にできる。",
   "useCase": "同じカード部品を通常・強調・警告へ切り替える、埋め込まれた領域のテーマへ子部品を追従させる、といったコンポーネント設計。",
   "code": ".card { --variant: featured; }\n@container style(--variant: featured) {\n  .card__body { border-color: #4fe3c1; }\n  .card__badge { display: inline-flex; }\n}",
   "tags": [
    "CSS",
    "コンテナクエリ",
    "デザイントークン",
    "コンポーネント"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"コンテナスタイルクエリのデモ\">\n  <style>.csq-card{animation:csq-variant 4s ease-in-out infinite}@keyframes csq-variant{0%,25%{filter:saturate(.2);transform:scale(.94)}50%,85%{filter:saturate(1);transform:scale(1)}100%{filter:saturate(.2);transform:scale(.94)}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"csq-card\"><rect x=\"58\" y=\"30\" width=\"124\" height=\"78\" rx=\"10\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".18\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"2\"/><rect x=\"72\" y=\"48\" width=\"66\" height=\"8\" rx=\"4\" fill=\"var(--w-ink,#e8eef9)\"/><rect x=\"72\" y=\"66\" width=\"92\" height=\"6\" rx=\"3\" fill=\"var(--w-sub,#a7b4cd)\"/><rect x=\"135\" y=\"40\" width=\"34\" height=\"16\" rx=\"8\" fill=\"var(--w-amber,#ffc857)\"/></g>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">@container style(--variant)</text>\n</svg>",
   "useFor": [
    "site",
    "lp"
   ],
   "weight": "脇役",
   "relatedIds": [
    "container-queries",
    "css-nesting",
    "css-scope",
    "scroll-state-queries"
   ]
  },
  {
   "id": "css-scope",
   "num": "W-221",
   "name": "CSS @scope",
   "nameJa": "@scopeで部品内だけスタイル適用",
   "category": "layout",
   "description": "@scopeでセレクタが一致する範囲を部品のルートから下限までに限定し、外側や入れ子部品へのルール流出を抑える。外側CSSの流入や継承は遮断しないため、Shadow DOMのような完全なカプセル化ではない。",
   "useCase": "CMS内の埋め込み部品やカードの入れ子で、この部品から出ていくセレクタの影響範囲を限定したい場面。外側から入るカスケードは別途確認する。",
   "code": "@scope (.profile-card) to (.profile-card .nested) {\n  :scope { border: 1px solid #4fe3c1; }\n  h2 { color: #4fe3c1; }\n}",
   "tags": [
    "CSS",
    "@scope",
    "スコープ",
    "コンポーネント",
    "保守性"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"CSS scopeの適用範囲のデモ\">\n  <style>.scp-stop{animation:scp-bound 4s ease-in-out infinite}@keyframes scp-bound{0%,30%{opacity:.25}55%,85%{opacity:1}100%{opacity:.25}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"34\" y=\"25\" width=\"172\" height=\"88\" rx=\"10\" fill=\"none\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"2\"/><text x=\"49\" y=\"46\" font-family=\"ui-monospace,monospace\" font-size=\"9\" fill=\"var(--w-accent,#4fe3c1)\">scope start</text><rect x=\"64\" y=\"55\" width=\"112\" height=\"42\" rx=\"7\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".16\"/><rect class=\"scp-stop\" x=\"112\" y=\"65\" width=\"52\" height=\"22\" rx=\"5\" fill=\"var(--w-amber,#ffc857)\" opacity=\".8\"/>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">@scope (.card) to (.nested)</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "css-nesting",
    "container-style-queries",
    "container-queries",
    "grid-lanes"
   ]
  },
  {
   "id": "css-nesting",
   "num": "W-222",
   "name": "Native CSS Nesting",
   "nameJa": "ネイティブCSSネスト",
   "category": "layout",
   "description": "CSSルールの中へ子セレクタや状態セレクタを直接入れ子にし、プリプロセッサなしで部品の関係を近くにまとめる。&で親セレクタを明示でき、メディアクエリも部品内へ置ける。",
   "useCase": "カードやボタンなど状態の多い部品で、hover・focus・子要素・レスポンシブ指定を読みやすく保ちたい場面。",
   "code": ".card {\n  padding: 1rem;\n  & h2 { margin: 0; }\n  &:hover { border-color: #4fe3c1; }\n  @media (width < 40rem) { padding: .75rem; }\n}",
   "tags": [
    "CSS",
    "ネスト",
    "保守性",
    "コンポーネント"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ネイティブCSSネストのデモ\">\n  <style>.nest-child{animation:nest-in 4s ease-in-out infinite}@keyframes nest-in{0%,25%{transform:translateX(-14px);opacity:.3}50%,85%{transform:translateX(0);opacity:1}100%{transform:translateX(-14px);opacity:.3}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"43\" y=\"27\" width=\"154\" height=\"84\" rx=\"9\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".13\" stroke=\"var(--w-accent,#4fe3c1)\"/><path d=\"M64 47h52M64 63h86\" stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"6\" stroke-linecap=\"round\"/><g class=\"nest-child\"><rect x=\"76\" y=\"77\" width=\"98\" height=\"22\" rx=\"5\" fill=\"var(--w-accent,#4fe3c1)\"/><text x=\"125\" y=\"92\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"9\" fill=\"var(--w-bg,#101830)\">&amp; .child</text></g>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">&amp;:hover  /  &amp; .child</text>\n</svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "css-scope",
    "container-style-queries",
    "container-queries",
    "grid-lanes"
   ]
  },
  {
   "id": "reading-flow",
   "num": "W-223",
   "name": "CSS Reading Flow",
   "nameJa": "見た目と読み上げ順をそろえるreading-flow",
   "category": "layout",
   "description": "reading-flowでGridやFlexの視覚順に合わせて、Tab移動と支援技術の読み順を指定する。基本は意味の通るDOM順を優先し、レスポンシブ再配置で見た目とのずれが避けられない場合に補助する。",
   "useCase": "ダッシュボードやカードグリッドで表示順をCSSにより大きく並べ替えた際、キーボード操作が画面上を不自然に飛ばないよう整える場面。",
   "code": ".dashboard {\n  display: grid;\n  grid-template-columns: 1fr 1fr;\n  reading-flow: grid-rows;\n}",
   "tags": [
    "CSS",
    "アクセシビリティ",
    "Tab順",
    "Grid",
    "Flex"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"見た目と読み上げ順のデモ\">\n  <style>.rfl-path{animation:rfl-follow 4s linear infinite}@keyframes rfl-follow{to{stroke-dashoffset:-36}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g font-family=\"ui-monospace,monospace\" font-size=\"16\" text-anchor=\"middle\"><rect x=\"48\" y=\"28\" width=\"60\" height=\"34\" rx=\"6\" fill=\"var(--w-accent,#4fe3c1)\"/><text x=\"78\" y=\"51\" fill=\"var(--w-bg,#101830)\">1</text><rect x=\"132\" y=\"28\" width=\"60\" height=\"34\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\"/><text x=\"162\" y=\"51\" fill=\"var(--w-bg,#101830)\">2</text><rect x=\"48\" y=\"76\" width=\"60\" height=\"34\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\"/><text x=\"78\" y=\"99\" fill=\"var(--w-bg,#101830)\">3</text><rect x=\"132\" y=\"76\" width=\"60\" height=\"34\" rx=\"6\" fill=\"var(--w-amber,#ffc857)\"/><text x=\"162\" y=\"99\" fill=\"var(--w-bg,#101830)\">4</text></g><path class=\"rfl-path\" d=\"M78 65C78 70 162 65 162 70S78 70 78 75M108 93h20\" fill=\"none\" stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"2\" stroke-dasharray=\"5 4\"/>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">reading-flow: grid-rows</text>\n</svg>",
   "useFor": [
    "site",
    "lp"
   ],
   "weight": "脇役",
   "relatedIds": [
    "media-preferences",
    "css-scroll-controls",
    "customizable-select",
    "contrast-color"
   ]
  },
  {
   "id": "corner-shape",
   "num": "W-224",
   "name": "CSS Corner Shape",
   "nameJa": "corner-shapeで角の形を選ぶ",
   "category": "shape",
   "description": "border-radiusの曲率にcorner-shapeを組み合わせ、丸・squircle・scoop・bevelなどの角形状をCSSだけで選ぶ。clip-pathを個別に描かず、サイズ変更へ追従する装飾的なカードを作れる。",
   "useCase": "ブランドカード、バッジ、写真フレーム、CTAなど、通常の角丸より個性を出しながらレスポンシブに保ちたい場面。",
   "code": ".card {\n  border-radius: 28px;\n  corner-shape: squircle;\n}\n.ticket {\n  border-radius: 20px;\n  corner-shape: scoop;\n}",
   "tags": [
    "CSS",
    "角丸",
    "squircle",
    "scoop",
    "カード"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"corner-shapeの角形状のデモ\">\n  <style>.csh-a,.csh-b,.csh-c{animation:csh-pop 4s ease-in-out infinite}.csh-a{transform-origin:60px 69px}.csh-b{transform-origin:125px 69px;animation-delay:.2s}.csh-c{transform-origin:191px 69px;animation-delay:.4s}@keyframes csh-pop{0%,20%{transform:scale(.82);opacity:.35}45%,85%{transform:scale(1);opacity:1}100%{transform:scale(.82);opacity:.35}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"csh-a\" x=\"34\" y=\"43\" width=\"52\" height=\"52\" rx=\"18\" fill=\"var(--w-sub,#a7b4cd)\"/><path class=\"csh-b\" d=\"M108 43h34q18 0 18 18v16q0 18-18 18h-34q-18 0-18-18V61q0-18 18-18Z\" fill=\"var(--w-accent,#4fe3c1)\"/><path class=\"csh-c\" d=\"M176 43h30v18a12 12 0 0 0 0 24v10h-30V85a12 12 0 0 0 0-24Z\" fill=\"var(--w-amber,#ffc857)\"/>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">round  →  squircle  →  scoop</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "gradient-border",
    "card-flip",
    "hover-lift-card",
    "skeleton-shimmer"
   ]
  },
  {
   "id": "css-shape-function",
   "num": "W-225",
   "name": "CSS shape() Function",
   "nameJa": "shape()でレスポンシブな輪郭を描く",
   "category": "shape",
   "description": "shape()関数でline・curve・arcなどの命令をCSS内に書き、clip-pathやoffset-pathの輪郭を割合・CSS変数でレスポンシブに定義する。固定座標のpath()よりサイズ変更へ追従しやすい。",
   "useCase": "斜めに切ったヒーロー、吹き出し、可変サイズのボタン輪郭、モーションパスを同じ設計トークンから作りたい場面。",
   "code": ".hero {\n  --notch: 12%;\n  clip-path: shape(from 0 0,\n    line to 100% 0, line to 100% 88%,\n    line to var(--notch) 100%, line to 0 82%, close);\n}",
   "tags": [
    "CSS",
    "clip-path",
    "shape()",
    "レスポンシブ",
    "図形"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"CSS shape関数のデモ\">\n  <style>.shp-form{animation:shp-notch 4s ease-in-out infinite}@keyframes shp-notch{0%,25%{d:path('M38 34H202V92L79 112 38 89Z')}55%,80%{d:path('M38 34H202V78L154 112 38 96Z')}100%{d:path('M38 34H202V92L79 112 38 89Z')}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <path class=\"shp-form\" d=\"M38 34H202V92L79 112 38 89Z\" fill=\"var(--w-accent,#4fe3c1)\"/><path d=\"M58 58h95M58 75h120\" stroke=\"var(--w-bg,#101830)\" stroke-width=\"7\" stroke-linecap=\"round\"/>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">shape(from … line to … close)</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "clip-path-polygon",
    "clip-path-shapes",
    "clip-path-reveal",
    "aspect-ratio"
   ]
  },
  {
   "id": "view-transition-class",
   "num": "W-226",
   "name": "View Transition Class",
   "nameJa": "複数要素をまとめるview-transition-class",
   "category": "motion",
   "description": "各要素には固有のview-transition-nameを与えたまま、共通のview-transition-classを付けると、複数の遷移擬似要素へ1本のCSSルールを適用できる。カード群の速度や方向を一括管理しやすい。",
   "useCase": "一覧から詳細への遷移や並べ替えで、複数カードへ同じタイミング関数・時間・スライド方向を適用したい場面。",
   "code": ".card { view-transition-class: card; }\n#card-a { view-transition-name: card-a; }\n#card-b { view-transition-name: card-b; }\n::view-transition-group(.card) {\n  animation-duration: .45s;\n  animation-timing-function: ease-in-out;\n}",
   "tags": [
    "CSS",
    "View Transitions",
    "ページ遷移",
    "一括指定"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"view-transition-classのデモ\">\n  <style>\n    .vtc-card{animation:vtc-pulse 2.6s ease-in-out infinite}\n    @keyframes vtc-pulse{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-10px) scale(1.06)}}\n  </style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"vtc-card\" x=\"30\" y=\"55\" width=\"50\" height=\"46\" rx=\"7\" fill=\"var(--w-accent,#4fe3c1)\"/>\n  <rect class=\"vtc-card\" x=\"95\" y=\"55\" width=\"50\" height=\"46\" rx=\"7\" fill=\"var(--w-amber,#ffc857)\"/>\n  <rect class=\"vtc-card\" x=\"160\" y=\"55\" width=\"50\" height=\"46\" rx=\"7\" fill=\"var(--w-ink,#e8eef9)\"/>\n  <text x=\"120\" y=\"128\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">3 names, 1 shared class rule</text>\n</svg>",
   "useFor": [
    "site",
    "lp"
   ],
   "weight": "脇役",
   "relatedIds": [
    "view-transitions-mpa",
    "view-transitions-spa",
    "element-scoped-view-transition",
    "scroll-triggered-animation"
   ]
  },
  {
   "id": "element-scoped-view-transition",
   "num": "W-227",
   "name": "Element-Scoped View Transition",
   "nameJa": "要素内だけのView Transition",
   "category": "motion",
   "description": "document全体ではなく任意の要素でstartViewTransition()を呼び、そのサブツリーだけを遷移対象にする。独立した部品の更新を同時実行でき、ページ全体の遷移との競合も減らせる。",
   "useCase": "ダッシュボードの各ウィジェット、モーダル内の表示切替、複数カードの独立更新など、局所的な状態変化を滑らかにつなぎたい場面。",
   "code": "const transition = panel.startViewTransition(() => {\n  panel.classList.toggle('compact');\n});\nawait transition.finished;",
   "tags": [
    "JavaScript",
    "View Transitions",
    "コンポーネント",
    "局所更新"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"要素内だけのView Transitionのデモ\">\n  <style>.evt-panel{animation:evt-local 4s ease-in-out infinite;transform-origin:120px 71px}@keyframes evt-local{0%,30%{transform:scale(1)}55%,80%{transform:scale(.78)}100%{transform:scale(1)}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"30\" y=\"24\" width=\"180\" height=\"92\" rx=\"10\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\"/><g class=\"evt-panel\"><rect x=\"48\" y=\"42\" width=\"65\" height=\"58\" rx=\"7\" fill=\"var(--w-accent,#4fe3c1)\"/><rect x=\"127\" y=\"42\" width=\"65\" height=\"58\" rx=\"7\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".25\"/></g>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">element.startViewTransition()</text>\n</svg>",
   "useFor": [
    "site",
    "lp"
   ],
   "weight": "脇役",
   "relatedIds": [
    "view-transitions-spa",
    "view-transition-class",
    "css-registerproperty-js",
    "scroll-into-view-container"
   ]
  },
  {
   "id": "scroll-triggered-animation",
   "num": "W-228",
   "name": "CSS Scroll-Triggered Animation",
   "nameJa": "CSSスクロールトリガー",
   "category": "motion",
   "description": "timeline-triggerでスクロール範囲を監視し、animation-triggerで通常の時間ベースアニメーションを再生・逆再生する。スクロール量へ直結するscroll-driven animationと違い、境界を越えた瞬間から一定時間で完走する。",
   "useCase": "要素が画面へ入ったら一度だけ展開する、離れたら逆再生する、といったIntersectionObserver相当の出現制御を宣言的に書きたい場面。",
   "code": ".card {\n  timeline-trigger: --reveal view() contain 15% contain 85%;\n  animation: reveal .45s ease both;\n  animation-trigger: --reveal play-forwards play-backwards;\n}\n@keyframes reveal { from { opacity: 0; translate: 0 24px; } }",
   "tags": [
    "CSS",
    "スクロール",
    "timeline-trigger",
    "出現",
    "省JavaScript"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"CSSスクロールトリガーのデモ\">\n  <style>.sta-scroll{animation:sta-scroll 4s ease-in-out infinite}@keyframes sta-scroll{0%,20%{transform:translateY(0)}55%,80%{transform:translateY(58px)}100%{transform:translateY(0)}}.sta-card{animation:sta-enter 4s ease-in-out infinite}@keyframes sta-enter{0%,25%{opacity:.15;transform:translateY(16px)}50%,85%{opacity:1;transform:none}100%{opacity:.15;transform:translateY(16px)}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <path d=\"M35 25v90\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"3\"/><circle class=\"sta-scroll\" cx=\"35\" cy=\"40\" r=\"6\" fill=\"var(--w-amber,#ffc857)\"/><g class=\"sta-card\"><rect x=\"70\" y=\"42\" width=\"130\" height=\"62\" rx=\"9\" fill=\"var(--w-accent,#4fe3c1)\"/><path d=\"M86 62h80M86 80h60\" stroke=\"var(--w-bg,#101830)\" stroke-width=\"6\" stroke-linecap=\"round\"/></g>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">timeline-trigger  →  animation-trigger</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "view-timeline-reveal",
    "scroll-reveal",
    "starting-style",
    "scroll-state-queries"
   ]
  },
  {
   "id": "sibling-index-stagger",
   "num": "W-229",
   "name": "Sibling Index Stagger",
   "nameJa": "sibling-index()で自動スタガー",
   "category": "motion",
   "description": "sibling-index()とsibling-count()で、兄弟要素の位置と総数をCSS計算へ使う。各要素へstyle属性や:nth-child()を列挙せず、個数が変わるリストにも自動で時間差を付けられる。",
   "useCase": "動的に件数が増減するメニュー、カード一覧、文字分割アニメーションで、保守しやすい連続ディレイを作りたい場面。",
   "code": ".item {\n  animation: enter .5s ease both;\n  animation-delay: calc((sibling-index() - 1) * 80ms);\n}\n.item { --progress: calc(sibling-index() / sibling-count()); }",
   "tags": [
    "CSS",
    "スタガー",
    "sibling-index()",
    "リスト",
    "省コード"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"sibling-indexで自動スタガーのデモ\">\n  <style>.sib-1,.sib-2,.sib-3,.sib-4{animation:sib-pop 3.6s ease-in-out infinite;transform-origin:center}.sib-2{animation-delay:.15s}.sib-3{animation-delay:.3s}.sib-4{animation-delay:.45s}@keyframes sib-pop{0%,18%{transform:translateY(18px) scale(.7);opacity:.2}40%,76%{transform:none;opacity:1}100%{transform:translateY(18px) scale(.7);opacity:.2}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g><circle class=\"sib-1\" cx=\"54\" cy=\"72\" r=\"16\" fill=\"var(--w-accent,#4fe3c1)\"/><circle class=\"sib-2\" cx=\"98\" cy=\"72\" r=\"16\" fill=\"var(--w-accent,#4fe3c1)\"/><circle class=\"sib-3\" cx=\"142\" cy=\"72\" r=\"16\" fill=\"var(--w-accent,#4fe3c1)\"/><circle class=\"sib-4\" cx=\"186\" cy=\"72\" r=\"16\" fill=\"var(--w-accent,#4fe3c1)\"/></g>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">delay = sibling-index() × 80ms</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "css-scroll-controls",
    "has-selector-interact",
    "anchor-positioning",
    "view-transition-class"
   ]
  },
  {
   "id": "customizable-select",
   "num": "W-230",
   "name": "Customizable Select",
   "nameJa": "ネイティブselectの完全カスタマイズ",
   "category": "interact",
   "description": "appearance: base-selectでネイティブselectの動作とアクセシビリティを保ちながら、開閉ボタン・選択中内容・picker・optionをCSSで詳細に装飾する。selectedcontentは選択optionの内容を閉じたボタンへ複製する。",
   "useCase": "画像付き商品選択、ブランドに合わせたプルダウン、検索可能な選択UIの土台など、独自div製selectを避けたい場面。",
   "code": "<label for=\"theme-select\">テーマ</label>\n<select id=\"theme-select\" class=\"theme-select\">\n  <button><selectedcontent></selectedcontent></button>\n  <option><span aria-hidden=\"true\">🌿</span> Forest</option>\n  <option><span aria-hidden=\"true\">🌊</span> Ocean</option>\n</select>\n<style>\n.theme-select, .theme-select::picker(select) { appearance: base-select; }\n.theme-select option:checked { font-weight: 700; }\n</style>",
   "tags": [
    "HTML",
    "CSS",
    "select",
    "フォーム",
    "アクセシビリティ"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"カスタマイズ可能なselectのデモ\">\n  <style>.csel-menu{animation:csel-open 4s ease-in-out infinite;transform-origin:120px 66px}@keyframes csel-open{0%,25%{opacity:0;transform:scaleY(.3)}50%,82%{opacity:1;transform:scaleY(1)}100%{opacity:0;transform:scaleY(.3)}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"49\" y=\"27\" width=\"142\" height=\"34\" rx=\"8\" fill=\"var(--w-accent,#4fe3c1)\"/><text x=\"67\" y=\"49\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"11\" fill=\"var(--w-bg,#101830)\">🌿 Forest</text><path d=\"m174 40 6 6 6-6\" fill=\"none\" stroke=\"var(--w-bg,#101830)\" stroke-width=\"2\"/><g class=\"csel-menu\"><rect x=\"49\" y=\"66\" width=\"142\" height=\"48\" rx=\"8\" fill=\"var(--w-ink,#e8eef9)\"/><text x=\"65\" y=\"86\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-bg,#101830)\">🌿 Forest ✓</text><text x=\"65\" y=\"105\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-bg,#101830)\">🌊 Ocean</text></g>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">appearance: base-select</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "open-pseudo-class",
    "form-associated-custom-elements",
    "hover-focus-states",
    "target-css-toggle"
   ]
  },
  {
   "id": "command-invokers",
   "num": "W-231",
   "name": "Invoker Commands",
   "nameJa": "command／commandforでUIを操作",
   "category": "interact",
   "description": "buttonのcommandforとcommandで、JavaScriptを書かずにdialogやpopoverへshow-modal・close・toggle-popoverなどの命令を送る。独自コマンドは--から始め、commandイベントで受け取れる。",
   "useCase": "モーダルの開閉、ポップオーバーメニュー、確認UIなど、HTMLだけで操作の関連付けを明示し、イベント処理を減らしたい場面。",
   "code": "<button commandfor=\"settings\" command=\"show-modal\">設定</button>\n<dialog id=\"settings\">\n  <button commandfor=\"settings\" command=\"close\">閉じる</button>\n</dialog>",
   "tags": [
    "HTML",
    "button",
    "dialog",
    "popover",
    "省JavaScript"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"Invoker Commandsのデモ\">\n  <style>.cmd-dialog{animation:cmd-open 4s ease-in-out infinite;transform-origin:176px 71px}@keyframes cmd-open{0%,25%{opacity:.15;transform:scale(.6)}50%,85%{opacity:1;transform:scale(1)}100%{opacity:.15;transform:scale(.6)}}.cmd-arrow{animation:cmd-send 4s ease-in-out infinite}@keyframes cmd-send{0%,25%{stroke-dasharray:0 30}50%,85%{stroke-dasharray:30 0}100%{stroke-dasharray:0 30}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"28\" y=\"55\" width=\"72\" height=\"32\" rx=\"8\" fill=\"var(--w-amber,#ffc857)\"/><text x=\"64\" y=\"76\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-bg,#101830)\">command</text><path class=\"cmd-arrow\" d=\"M106 71h28\" stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"2\" marker-end=\"url(#cmd-tip)\"/><defs><marker id=\"cmd-tip\" viewBox=\"0 0 6 6\" refX=\"5\" refY=\"3\" markerWidth=\"6\" markerHeight=\"6\" orient=\"auto\"><path d=\"M0 0l6 3-6 3Z\" fill=\"var(--w-ink,#e8eef9)\"/></marker></defs><g class=\"cmd-dialog\"><rect x=\"140\" y=\"38\" width=\"72\" height=\"66\" rx=\"8\" fill=\"var(--w-accent,#4fe3c1)\"/><path d=\"M154 58h44M154 73h34\" stroke=\"var(--w-bg,#101830)\" stroke-width=\"5\" stroke-linecap=\"round\"/></g>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">commandfor  +  command</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "dialog-closedby",
    "lightbox-dialog",
    "lightbox-gallery",
    "popover-hint"
   ]
  },
  {
   "id": "dialog-closedby",
   "num": "W-232",
   "name": "Dialog Closedby Attribute",
   "nameJa": "dialogの閉じ方をclosedbyで制御",
   "category": "interact",
   "description": "dialogのclosedby属性で、Escなどの閉じ要求だけを許すcloserequest、背景クリックも許すany、操作ボタン以外では閉じないnoneを宣言できる。用途ごとの閉じ方をJavaScriptなしで揃えられる。",
   "useCase": "画像ライトボックスはany、重要な同意確認はnone、通常モーダルはcloserequest、と誤操作リスクに応じて閉じ方を選びたい場面。",
   "code": "<dialog id=\"lightbox\" closedby=\"any\">…</dialog>\n<dialog id=\"confirm\" closedby=\"none\">\n  <button commandfor=\"confirm\" command=\"close\">確認</button>\n</dialog>",
   "tags": [
    "HTML",
    "dialog",
    "モーダル",
    "UX",
    "省JavaScript"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"dialogのclosedby属性のデモ\">\n  <style>.cby-modal{animation:cby-close 4s ease-in-out infinite;transform-origin:120px 71px}@keyframes cby-close{0%,25%{opacity:.32;transform:scale(.75)}50%,82%{opacity:1;transform:scale(1)}100%{opacity:.32;transform:scale(.75)}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"cby-back\" x=\"20\" y=\"16\" width=\"200\" height=\"110\" rx=\"9\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".13\"/><g class=\"cby-modal\"><rect x=\"58\" y=\"38\" width=\"124\" height=\"66\" rx=\"9\" fill=\"var(--w-ink,#e8eef9)\"/><circle cx=\"168\" cy=\"51\" r=\"8\" fill=\"var(--w-amber,#ffc857)\"/><path d=\"m165 48 6 6m0-6-6 6\" stroke=\"var(--w-bg,#101830)\" stroke-width=\"1.5\"/><path d=\"M76 62h58M76 80h82\" stroke=\"var(--w-bg,#101830)\" stroke-width=\"5\" stroke-linecap=\"round\" opacity=\".5\"/></g>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">any  /  closerequest  /  none</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "command-invokers",
    "lightbox-dialog",
    "lightbox-gallery",
    "dialog-modal"
   ]
  },
  {
   "id": "open-pseudo-class",
   "num": "W-233",
   "name": "Open Pseudo-Class",
   "nameJa": ":openで開いているUIを装飾",
   "category": "interact",
   "description": ":openはselectやdialogなど、開いた状態を持つUIを共通の考え方で選択する疑似クラス。属性の有無やブラウザ固有セレクタへ分岐せず、開いているコントロールの枠や背景を変えられる。",
   "useCase": "プルダウンを開いたときの枠・背景変更、開いているdialogの導入アニメーションなど、開閉中のUIへ明確な状態感を出したい場面。",
   "code": "select:open {\n  border-color: #4fe3c1;\n  background: color-mix(in srgb, #4fe3c1 12%, Canvas);\n}\ndialog:open {\n  opacity: 1;\n  outline: 2px solid #4fe3c1;\n}",
   "tags": [
    "CSS",
    ":open",
    "select",
    "dialog",
    "状態"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"open疑似クラスのデモ\">\n  <style>.opn-box{animation:opn-box 4s ease-in-out infinite}@keyframes opn-box{0%,25%{stroke:var(--w-sub,#94a3c0)}50%,82%{stroke:var(--w-accent,#4fe3c1)}100%{stroke:var(--w-sub,#94a3c0)}}.opn-menu{animation:opn-state 4s ease-in-out infinite;transform-origin:120px 67px}@keyframes opn-state{0%,25%{opacity:0;transform:scaleY(.2)}50%,82%{opacity:1;transform:scaleY(1)}100%{opacity:0;transform:scaleY(.2)}}.opn-arrow{animation:opn-rotate 4s ease-in-out infinite;transform-origin:166px 44px}@keyframes opn-rotate{0%,25%,100%{transform:rotate(0)}50%,82%{transform:rotate(180deg)}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"opn-box\" x=\"60\" y=\"27\" width=\"120\" height=\"34\" rx=\"8\" fill=\"none\" stroke=\"var(--w-sub,#94a3c0)\" stroke-width=\"2\"/><text x=\"75\" y=\"49\" font-family=\"ui-monospace,monospace\" font-size=\"10\" fill=\"var(--w-ink,#e8eef9)\">select</text><path class=\"opn-arrow\" d=\"m159 40 7 7 7-7\" fill=\"none\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"2\"/><g class=\"opn-menu\"><rect x=\"60\" y=\"67\" width=\"120\" height=\"47\" rx=\"8\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><path d=\"M75 82h56M75 99h78\" stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"5\" stroke-linecap=\"round\"/></g>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">:open</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "customizable-select",
    "command-invokers",
    "dialog-closedby",
    "text-box-trim"
   ]
  },
  {
   "id": "navigation-api",
   "num": "W-234",
   "name": "Navigation API",
   "nameJa": "Navigation APIで遷移を一元管理",
   "category": "interact",
   "description": "window.navigationのnavigateイベントでリンク遷移・履歴移動・再読み込みを一つの入口から扱い、intercept()でSPA更新へ差し替える。History APIより現在エントリや遷移完了を追いやすい。",
   "useCase": "ルーターを自作する小規模SPA、View Transitionsと組み合わせたページ切替、保存確認を挟むナビゲーション制御。",
   "code": "navigation.addEventListener('navigate', (event) => {\n  if (!event.canIntercept || new URL(event.destination.url).origin !== location.origin) return;\n  event.intercept({ handler: async () => {\n    main.replaceChildren(await render(event.destination.url));\n  }});\n});",
   "tags": [
    "JavaScript",
    "Navigation API",
    "SPA",
    "履歴",
    "ルーティング"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"Navigation APIのデモ\">\n  <style>.nav-old{animation:nav-out 4s ease-in-out infinite}@keyframes nav-out{0%,25%{opacity:1;transform:none}55%,85%{opacity:.2;transform:translateX(12px)}100%{opacity:1;transform:none}}.nav-new{animation:nav-in 4s ease-in-out infinite}@keyframes nav-in{0%,25%{opacity:.2;transform:translateX(-12px)}55%,85%{opacity:1;transform:none}100%{opacity:.2;transform:translateX(-12px)}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"nav-old\"><rect x=\"25\" y=\"35\" width=\"76\" height=\"68\" rx=\"8\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".35\"/></g><path d=\"M108 69h24\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"3\"/><path d=\"m126 63 7 6-7 6\" fill=\"none\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"3\"/><g class=\"nav-new\"><rect x=\"140\" y=\"35\" width=\"76\" height=\"68\" rx=\"8\" fill=\"var(--w-accent,#4fe3c1)\"/><path d=\"M154 55h48M154 72h35M154 88h52\" stroke=\"var(--w-bg,#101830)\" stroke-width=\"5\" stroke-linecap=\"round\"/></g>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">navigate  →  intercept  →  render</text>\n</svg>",
   "useFor": [
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "view-transitions-spa",
    "css-typed-om",
    "offscreen-canvas-worker",
    "scroll-into-view-container"
   ]
  },
  {
   "id": "popover-hint",
   "num": "W-235",
   "name": "Hint Popover",
   "nameJa": "popover=\"hint\"の軽量ヒント",
   "category": "interact",
   "description": "popover=\"hint\"はツールチップなど短時間の補助情報向けの状態。同じhint階層では他のhintを閉じる一方、APIで表示するか、開いているauto内のinvokerから表示すればautoと共存できる。外部ボタンのクリックはautoをlight-dismissし得る。",
   "useCase": "ツールバー内のボタン補足、用語説明、グラフのポイント情報など、既存のメニューを保ったまま一時的な説明を重ねたい場面。表示条件とアクセシブルな名前は別途設計する。",
   "code": "<button id=\"term\" aria-describedby=\"tip\">用語</button>\n<div id=\"tip\" popover=\"hint\" role=\"tooltip\">短い補足説明</div>\n<script>\nconst show = () => tip.showPopover();\nterm.addEventListener('mouseenter', show);\nterm.addEventListener('focus', show);\nterm.addEventListener('mouseleave', () => tip.hidePopover());\nterm.addEventListener('blur', () => tip.hidePopover());\n</script>",
   "tags": [
    "HTML",
    "Popover API",
    "ツールチップ",
    "トップレイヤー"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"hintポップオーバーのデモ\">\n  <style>.poh-tip{animation:poh-show 4s ease-in-out infinite;transform-origin:120px 74px}@keyframes poh-show{0%,25%{opacity:0;transform:translateY(8px) scale(.9)}50%,82%{opacity:1;transform:none}100%{opacity:0;transform:translateY(8px) scale(.9)}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"84\" y=\"83\" width=\"72\" height=\"30\" rx=\"8\" fill=\"var(--w-accent,#4fe3c1)\"/><text x=\"120\" y=\"103\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-bg,#101830)\">用語</text><g class=\"poh-tip\"><rect x=\"62\" y=\"28\" width=\"116\" height=\"38\" rx=\"8\" fill=\"var(--w-ink,#e8eef9)\"/><path d=\"m113 66 7 8 7-8\" fill=\"var(--w-ink,#e8eef9)\"/><text x=\"120\" y=\"52\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-bg,#101830)\">短い補足説明</text></g>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">popover=\"hint\"</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "details-summary-accordion",
    "customizable-select",
    "command-invokers",
    "dialog-closedby"
   ]
  },
  {
   "id": "field-sizing",
   "num": "W-236",
   "name": "Field Sizing",
   "nameJa": "入力内容に合わせるfield-sizing",
   "category": "component",
   "description": "field-sizing: contentでinput・textarea・selectのサイズを入力内容へ自動追従させる。JavaScriptでscrollHeightを測らず、min/maxサイズだけCSSで制約して自然に伸びる入力欄を作れる。",
   "useCase": "チャット入力、短いタグ入力、自由記述フォームなど、内容量に応じて欄を広げつつ画面を占有しすぎないようにしたい場面。",
   "code": "textarea {\n  field-sizing: content;\n  min-block-size: 3lh;\n  max-block-size: 10lh;\n}",
   "tags": [
    "CSS",
    "フォーム",
    "textarea",
    "自動サイズ",
    "省JavaScript"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"入力内容に合わせるfield-sizingのデモ\">\n  <style>.fsz-box{animation:fsz-grow 4s ease-in-out infinite}@keyframes fsz-grow{0%,25%{height:42px}55%,82%{height:66px}100%{height:42px}}.fsz-more{animation:fsz-lines 4s ease-in-out infinite}@keyframes fsz-lines{0%,25%{opacity:0}55%,82%{opacity:1}100%{opacity:0}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"fsz-box\" x=\"45\" y=\"40\" width=\"150\" height=\"42\" rx=\"8\" fill=\"none\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"2\"/><g stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"5\" stroke-linecap=\"round\"><path d=\"M60 57h82\"/><path class=\"fsz-more\" d=\"M60 73h112M60 89h68\"/></g>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">field-sizing: content</text>\n</svg>",
   "useFor": [
    "site",
    "lp"
   ],
   "weight": "脇役",
   "relatedIds": [
    "stepper",
    "scroll-state-queries",
    "scroll-triggered-animation",
    "customizable-select"
   ]
  },
  {
   "id": "details-content",
   "num": "W-237",
   "name": "Details Content Pseudo-Element",
   "nameJa": "detailsの本文を::details-contentで選ぶ",
   "category": "component",
   "description": "::details-contentでdetails要素のsummary以外の本文ラッパーを直接選択できる。余分なdivを足さずに、開閉本文のoverflow・opacity・block-sizeなどをまとめて装飾できる。",
   "useCase": "FAQや仕様表のアコーディオンで、意味のある最小HTMLを保ちながら本文だけへ開閉アニメーションや余白を適用したい場面。",
   "code": ":root { interpolate-size: allow-keywords; }\ndetails::details-content {\n  block-size: 0; opacity: 0; overflow: clip;\n  transition: block-size .3s, opacity .3s, content-visibility .3s allow-discrete;\n}\ndetails[open]::details-content { block-size: auto; opacity: 1; }",
   "tags": [
    "CSS",
    "details",
    "アコーディオン",
    "擬似要素",
    "省HTML"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"details本文の疑似要素のデモ\">\n  <style>.dtc-body{animation:dtc-open 4s ease-in-out infinite;transform-origin:120px 64px}@keyframes dtc-open{0%,25%{opacity:.3;transform:scaleY(.16)}50%,82%{opacity:1;transform:scaleY(1)}100%{opacity:.3;transform:scaleY(.16)}}.dtc-arrow{animation:dtc-turn 4s ease-in-out infinite;transform-origin:191px 44px}@keyframes dtc-turn{0%,25%,100%{transform:rotate(0)}50%,82%{transform:rotate(180deg)}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"37\" y=\"30\" width=\"166\" height=\"28\" rx=\"7\" fill=\"var(--w-accent,#4fe3c1)\"/><path class=\"dtc-arrow\" d=\"m184 40 7 7 7-7\" fill=\"none\" stroke=\"var(--w-bg,#101830)\" stroke-width=\"2\"/><g class=\"dtc-body\"><rect x=\"37\" y=\"64\" width=\"166\" height=\"48\" rx=\"7\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".2\"/><path d=\"M52 79h107M52 95h82\" stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"5\" stroke-linecap=\"round\"/></g>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">::details-content</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "faq-accordion",
    "interpolate-size",
    "speech-bubble",
    "field-sizing"
   ]
  },
  {
   "id": "search-element-landmark",
   "num": "W-238",
   "name": "Search Element",
   "nameJa": "search要素で検索領域を示す",
   "category": "component",
   "description": "<search>はサイト内検索や絞り込み操作のまとまりを意味するHTMLランドマーク。単なるdivではなく支援技術へ検索領域として伝わり、同じページに複数ある場合はaria-labelで区別できる。",
   "useCase": "ヘッダー検索、商品絞り込み、地図内検索など、入力欄と送信・フィルター操作を一つの検索領域として明示したい場面。",
   "code": "<search aria-label=\"サイト内検索\">\n  <form action=\"/search\">\n    <label for=\"site-q\">キーワード</label>\n    <input id=\"site-q\" name=\"q\" type=\"search\">\n    <button>検索</button>\n  </form>\n</search>",
   "tags": [
    "HTML",
    "セマンティクス",
    "アクセシビリティ",
    "検索",
    "ランドマーク"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"search要素のランドマークのデモ\">\n  <style>.sea-lens{animation:sea-find 4s ease-in-out infinite;transform-origin:61px 66px}@keyframes sea-find{0%,25%{transform:translateX(0)}55%,82%{transform:translateX(87px)}100%{transform:translateX(0)}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect x=\"36\" y=\"43\" width=\"168\" height=\"46\" rx=\"23\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"2\"/><circle class=\"sea-lens\" cx=\"61\" cy=\"66\" r=\"9\" fill=\"none\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"3\"/><path class=\"sea-lens\" d=\"m68 73 8 8\" stroke=\"var(--w-accent,#4fe3c1)\" stroke-width=\"3\"/><path d=\"M88 66h74\" stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"6\" stroke-linecap=\"round\" opacity=\".55\"/><rect x=\"170\" y=\"51\" width=\"25\" height=\"30\" rx=\"15\" fill=\"var(--w-amber,#ffc857)\"/>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">&lt;search aria-label=\"…\"&gt;</text>\n</svg>",
   "useFor": [
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "customizable-select",
    "inert-attribute",
    "command-palette",
    "form-associated-custom-elements"
   ]
  },
  {
   "id": "contrast-color",
   "num": "W-239",
   "name": "CSS contrast-color()",
   "nameJa": "背景に対する文字色をcontrast-color()で選ぶ",
   "category": "background",
   "description": "contrast-color()は指定色に対し、白と黒のうちコントラストが高い方をブラウザに選ばせる。手作業の色分岐を減らせるが、中間色では小さい文字のWCAG基準を満たさない場合があるため、実際の配色でコントラストを測定する。",
   "useCase": "動的カラーのタグ、カテゴリバッジ、カラーピッカーのプレビューなど、背景色を事前に固定できない部品の初期選択に使い、重要な文字色は検査結果で補正する。",
   "code": ".badge {\n  --surface: oklch(72% .18 155);\n  background: var(--surface);\n  color: contrast-color(var(--surface));\n}",
   "tags": [
    "CSS",
    "色",
    "コントラスト",
    "アクセシビリティ",
    "動的テーマ"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"contrast-colorによる前景色選択のデモ\">\n  <style>.ccr-bg,.ccr-bg2{animation:ccr-tone 4s ease-in-out infinite}@keyframes ccr-tone{0%,25%{filter:brightness(.65)}55%,82%{filter:brightness(1.25)}100%{filter:brightness(.65)}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <rect class=\"ccr-bg\" x=\"35\" y=\"40\" width=\"74\" height=\"62\" rx=\"9\" fill=\"var(--w-accent,#4fe3c1)\"/><text x=\"72\" y=\"77\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"20\" font-weight=\"800\" fill=\"var(--w-bg,#101830)\">Aa</text><rect class=\"ccr-bg2\" x=\"131\" y=\"40\" width=\"74\" height=\"62\" rx=\"9\" fill=\"var(--w-bg,#101830)\" stroke=\"var(--w-sub,#94a3c2)\" stroke-width=\"1.5\"/><text x=\"168\" y=\"77\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"20\" font-weight=\"800\" fill=\"var(--w-ink,#e8eef9)\">Aa</text>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#94a3c2)\">contrast-color(var(--surface))</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "light-dark-color",
    "css-scroll-controls",
    "reading-flow",
    "customizable-select"
   ]
  },
  {
   "id": "light-dark-color",
   "num": "W-240",
   "name": "CSS light-dark()",
   "nameJa": "light-dark()でテーマ色を1宣言にする",
   "category": "background",
   "description": "color-schemeをlight darkにした上でlight-dark()を使うと、ライト時とダーク時の色を一つの宣言に記述できる。OS設定やcolor-schemeの切替へフォーム部品も含めて自然に追従する。",
   "useCase": "ライト／ダーク両対応のページで、背景・文字・境界線などの色トークンを短く一貫して定義したい場面。",
   "code": ":root {\n  color-scheme: light dark;\n  --surface: light-dark(#ffffff, #111a31);\n  --text: light-dark(#17233c, #e8eef9);\n}\nbody { background: var(--surface); color: var(--text); }",
   "tags": [
    "CSS",
    "ダークモード",
    "color-scheme",
    "テーマ",
    "色"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"light-darkによるテーマ色のデモ\">\n  <style>.ldc-world{animation:ldc-switch 4s ease-in-out infinite;transform-origin:120px 70px}@keyframes ldc-switch{0%,25%{transform:translateX(18px)}55%,82%{transform:translateX(-18px)}100%{transform:translateX(18px)}}</style>\n  <rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/>\n  <g class=\"ldc-world\"><rect x=\"36\" y=\"34\" width=\"78\" height=\"72\" rx=\"10\" fill=\"var(--w-ink,#e8eef9)\"/><circle cx=\"75\" cy=\"58\" r=\"12\" fill=\"var(--w-amber,#ffc857)\"/><path d=\"M54 86h43\" stroke=\"var(--w-bg,#101830)\" stroke-width=\"6\" stroke-linecap=\"round\"/><rect x=\"126\" y=\"34\" width=\"78\" height=\"72\" rx=\"10\" fill=\"var(--w-bg,#101830)\" stroke=\"var(--w-sub,#94a3c2)\" stroke-width=\"2\"/><path d=\"M174 47a13 13 0 1 0 10 19 15 15 0 0 1-10-19\" fill=\"var(--w-accent,#4fe3c1)\"/><path d=\"M145 86h43\" stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"6\" stroke-linecap=\"round\"/></g>\n  <text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#94a3c2)\">light-dark(light, dark)</text>\n</svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "contrast-color",
    "media-preferences",
    "text-box-trim",
    "text-autospace"
   ]
  },
  {
   "id": "vertical-scroll-snap",
   "num": "W-241",
   "name": "Vertical Writing with Scroll Snap",
   "nameJa": "縦書きの章送り（スクロール連動）",
   "category": "scroll",
   "description": "writing-mode: vertical-rlの文章は右から左へ列が進むため、横方向のスクロールがそのまま縦書きの読み進行と一致する。overflow-x: autoとscroll-snap-typeを組み合わせると、縦組みの1ページ分がぴたっと吸着しながら右から左へ章送りされる、書籍のような読書体験になる。",
   "useCase": "縦書きの小説・コラム記事をWeb上でページめくり風に読ませたいとき、和風のスクロールストーリーテリングを作りたいとき。",
   "code": ".wj-vss-track{\n  writing-mode: vertical-rl;\n  display:flex;\n  overflow-x:auto;\n  scroll-snap-type:x mandatory;\n}\n.wj-vss-track>section{\n  flex:0 0 100%;\n  scroll-snap-align:start;\n}",
   "tags": [
    "CSS",
    "縦書き",
    "スクロール",
    "和風",
    "没入感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"縦書きの章送りのデモ\"><style>.wj-vss-track{animation:wj-vss-move 4.5s cubic-bezier(.7,0,.2,1) infinite}@keyframes wj-vss-move{0%,26%{transform:translateX(0)}36%,62%{transform:translateX(80px)}72%,96%{transform:translateX(160px)}100%{transform:translateX(0)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g class=\"wj-vss-track\"><rect x=\"-64\" y=\"24\" width=\"64\" height=\"102\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".5\"/><rect x=\"8\" y=\"24\" width=\"64\" height=\"102\" rx=\"6\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".9\"/><rect x=\"80\" y=\"24\" width=\"64\" height=\"102\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".5\"/></g><rect x=\"104\" y=\"132\" width=\"32\" height=\"4\" rx=\"2\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".35\"/></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "text-combine-upright",
    "scroll-snap",
    "parallax-scroll",
    "scrollytelling"
   ]
  },
  {
   "id": "ruby-mono",
   "num": "W-242",
   "name": "Mono Ruby Annotation",
   "nameJa": "モノルビ（1字ずつのふりがな）",
   "category": "text",
   "description": "<ruby>と<rt>で、漢字1字ごとに読みを個別に添えるふりがな表記。文字ごとに<rt>を分けて書くと、各文字の真上に読みがぴったり揃う「モノルビ」になる。<rp>で非対応ブラウザ用の丸カッコ表記も用意できる。",
   "useCase": "難読な人名・専門用語で、どの読みがどの文字に対応するかを一字単位ではっきり示したいとき。教材や辞書的な見出しに向く。",
   "code": "<ruby>\n  漢<rp>(</rp><rt>かん</rt><rp>)</rp>\n  字<rp>(</rp><rt>じ</rt><rp>)</rp>\n</ruby>",
   "tags": [
    "HTML",
    "日本語",
    "ふりがな",
    "タイポグラフィ",
    "正確"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"モノルビのデモ\"><style>.wj-rbmn-rt{animation:wj-rbmn-in 4.5s ease-in-out infinite}@keyframes wj-rbmn-in{0%,8%{opacity:0;transform:translateY(6px)}22%,100%{opacity:1;transform:translateY(0)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g><rect x=\"30\" y=\"70\" width=\"50\" height=\"50\" rx=\"6\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".9\"/><text x=\"55\" y=\"102\" font-size=\"22\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\" font-weight=\"700\">漢</text><rect x=\"34\" y=\"46\" width=\"42\" height=\"16\" rx=\"4\" fill=\"var(--w-amber,#ffc857)\" class=\"wj-rbmn-rt\" style=\"animation-delay:0s\"/></g><g><rect x=\"94\" y=\"70\" width=\"50\" height=\"50\" rx=\"6\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".9\"/><text x=\"119\" y=\"102\" font-size=\"22\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\" font-weight=\"700\">字</text><rect x=\"98\" y=\"46\" width=\"42\" height=\"16\" rx=\"4\" fill=\"var(--w-amber,#ffc857)\" class=\"wj-rbmn-rt\" style=\"animation-delay:.35s\"/></g><line x1=\"30\" y1=\"128\" x2=\"240\" y2=\"128\" stroke=\"var(--w-sub,#a7b4cd)\" opacity=\".25\"/><rect x=\"164\" y=\"86\" width=\"46\" height=\"8\" rx=\"4\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".35\"/><rect x=\"164\" y=\"100\" width=\"30\" height=\"8\" rx=\"4\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".25\"/></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "ruby-group-jukugo",
    "ruby-overhang",
    "text-emphasis-dots",
    "text-box-trim"
   ]
  },
  {
   "id": "ruby-group-jukugo",
   "num": "W-243",
   "name": "Group Ruby for Compound Words",
   "nameJa": "グループルビ・熟語ルビ（熟語まとめ読み）",
   "category": "text",
   "description": "<rt>を文字ごとに分けず、熟語全体に1つだけ付けると、読みが base 全体の幅へ均等に配置される「グループルビ」になる。ruby-align: space-around（既定値）が両端に半分の余白を残しながら文字間へ均等配分し、モノルビとは違う一体感のある見た目になる。印刷組版では、文字ごとの対応をできる限り保ちつつ収まらない分だけ全体配分に切り替える「熟語ルビ」という中間的な流儀もあるが、CSSのルビモジュールにはその専用アルゴリズムはなく、Web上はグループルビと同じ仕組み（ひとつの<rt>＋ruby-align）で近似することになる。",
   "useCase": "「明日」「今日」のように読みが文字単位に分解しにくい熟語・当て字。見出しやキャッチコピーで熟語をひとまとまりに読ませたいとき。",
   "code": "<ruby>\n  明日<rp>(</rp><rt>あした</rt><rp>)</rp>\n</ruby>\n\nruby { ruby-align: space-around; }",
   "tags": [
    "HTML",
    "CSS",
    "日本語",
    "ふりがな",
    "熟語",
    "整列"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"グループルビのデモ\"><style>.wj-rbgp-dot{animation:wj-rbgp-pop 4.5s ease-in-out infinite}@keyframes wj-rbgp-pop{0%,6%{opacity:0;transform:scale(.4)}20%,100%{opacity:1;transform:scale(1)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"52\" y=\"66\" width=\"60\" height=\"56\" rx=\"6\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".9\"/><rect x=\"118\" y=\"66\" width=\"60\" height=\"56\" rx=\"6\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".75\"/><text x=\"82\" y=\"102\" font-size=\"22\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\" font-weight=\"700\">明</text><text x=\"148\" y=\"102\" font-size=\"22\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\" font-weight=\"700\">日</text><rect x=\"52\" y=\"42\" width=\"126\" height=\"14\" rx=\"7\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-dasharray=\"2 3\" opacity=\".4\"/><circle class=\"wj-rbgp-dot\" cx=\"66\" cy=\"49\" r=\"4\" fill=\"var(--w-amber,#ffc857)\" style=\"animation-delay:0s\"/><circle class=\"wj-rbgp-dot\" cx=\"98\" cy=\"49\" r=\"4\" fill=\"var(--w-amber,#ffc857)\" style=\"animation-delay:.2s\"/><circle class=\"wj-rbgp-dot\" cx=\"132\" cy=\"49\" r=\"4\" fill=\"var(--w-amber,#ffc857)\" style=\"animation-delay:.4s\"/><circle class=\"wj-rbgp-dot\" cx=\"164\" cy=\"49\" r=\"4\" fill=\"var(--w-amber,#ffc857)\" style=\"animation-delay:.6s\"/></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "ruby-overhang",
    "ruby-mono",
    "line-break-strict",
    "hanging-punctuation"
   ]
  },
  {
   "id": "ruby-overhang",
   "num": "W-244",
   "name": "Ruby Overhang Control",
   "nameJa": "ルビのはみ出し配置（ruby-overhang）",
   "category": "text",
   "description": "ruby-overhangは、ルビ文字が base より幅広いときに隣の文字の上へはみ出してよいかを指定する。autoなら隣接する空白や約物の上に自然にはみ出し、noneなら<ruby>要素の幅の中に収まるよう詰め込まれる。",
   "useCase": "短い漢字1字に長い読みを付けるとき、行間の詰まった本文でルビ同士がぶつからないように制御したい場面。",
   "code": "ruby { ruby-overhang: auto; }  /* 隣へはみ出しを許可 */\n.tight ruby { ruby-overhang: none; } /* 幅の中に収める */",
   "tags": [
    "CSS",
    "日本語",
    "ふりがな",
    "先端"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ルビのはみ出し配置のデモ\"><style>.wj-rbov-rt{animation:wj-rbov-shift 5s ease-in-out infinite}@keyframes wj-rbov-shift{0%,20%{transform:translateX(0)}30%,72%{transform:translateX(-18px)}88%,100%{transform:translateX(0)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"26\" y=\"70\" width=\"44\" height=\"46\" rx=\"6\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".9\"/><text x=\"48\" y=\"100\" font-size=\"19\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\" font-weight=\"700\">字</text><rect x=\"76\" y=\"70\" width=\"44\" height=\"46\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><rect x=\"16\" y=\"46\" width=\"72\" height=\"15\" rx=\"7\" fill=\"var(--w-amber,#ffc857)\" class=\"wj-rbov-rt\"/><line x1=\"70\" y1=\"40\" x2=\"70\" y2=\"122\" stroke=\"var(--w-ink,#e8eef9)\" stroke-dasharray=\"2 3\" opacity=\".3\"/></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "word-break-auto-phrase",
    "ruby-group-jukugo",
    "text-orientation-upright",
    "unicode-range-subset"
   ]
  },
  {
   "id": "text-emphasis-dots",
   "num": "W-245",
   "name": "Text Emphasis Marks",
   "nameJa": "圏点・傍点（文字上の強調点）",
   "category": "text",
   "description": "text-emphasisで、文中の特定の文字だけに小さな点や三角を打って強調する日本語の伝統的な傍点表現。filled sesameやfilled dotなど記号の形と色をCSSだけで指定でき、太字や下線と違って字面を崩さずに強調できる。",
   "useCase": "小説的なテキストで特定の語だけに視線を誘導したいとき、注意書きの重要語を目立たせたいときに使う。",
   "code": ".wj-emph{\n  text-emphasis: filled sesame var(--w-amber,#ffc857);\n  text-emphasis-position: over;\n}",
   "tags": [
    "CSS",
    "日本語",
    "強調",
    "タイポグラフィ",
    "さりげない"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"圏点・傍点のデモ\"><style>.wj-tem-mk{animation:wj-tem-pulse 3.6s ease-in-out infinite}@keyframes wj-tem-pulse{0%,100%{opacity:.55;transform:scale(1)}50%{opacity:1;transform:scale(1.25)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g><rect x=\"34\" y=\"66\" width=\"38\" height=\"46\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".28\"/><rect x=\"80\" y=\"66\" width=\"38\" height=\"46\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".28\"/><rect x=\"126\" y=\"66\" width=\"38\" height=\"46\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".28\"/><rect x=\"172\" y=\"66\" width=\"38\" height=\"46\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".28\"/><circle class=\"wj-tem-mk\" cx=\"53\" cy=\"52\" r=\"5\" fill=\"var(--w-amber,#ffc857)\" style=\"animation-delay:0s\"/><circle class=\"wj-tem-mk\" cx=\"99\" cy=\"52\" r=\"5\" fill=\"var(--w-amber,#ffc857)\" style=\"animation-delay:0.15s\"/><circle class=\"wj-tem-mk\" cx=\"145\" cy=\"52\" r=\"5\" fill=\"var(--w-amber,#ffc857)\" style=\"animation-delay:0.3s\"/><circle class=\"wj-tem-mk\" cx=\"191\" cy=\"52\" r=\"5\" fill=\"var(--w-amber,#ffc857)\" style=\"animation-delay:0.44999999999999996s\"/><rect x=\"34\" y=\"66\" width=\"38\" height=\"46\" rx=\"6\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".9\"/><rect x=\"80\" y=\"66\" width=\"38\" height=\"46\" rx=\"6\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".9\"/></g></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "vertical-writing",
    "outline-text-bg",
    "text-box-trim",
    "text-autospace"
   ]
  },
  {
   "id": "text-combine-upright",
   "num": "W-246",
   "name": "Tate-Chu-Yoko (Combine Upright)",
   "nameJa": "縦中横（縦書き中の数字を横向きに収める）",
   "category": "text",
   "description": "text-combine-upright: allで、縦書きの中に出てくる短い数字やアルファベットを1文字分の枠に横向きのまま収める「縦中横」を実装する。桁数の多い数字を1文字ずつ縦に並べず、読みやすい横並びのまま縦書きの流れに埋め込める。",
   "useCase": "縦書きの本文中に出てくる西暦・電話番号・略号などの2〜4桁の数字を、縦書きのリズムを崩さず自然に見せたいとき。",
   "code": ".tcu-vert{\n  writing-mode: vertical-rl;\n}\n.tcu-num{\n  text-combine-upright: all;\n}",
   "tags": [
    "CSS",
    "縦書き",
    "日本語",
    "数字",
    "和風"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"縦中横のデモ\"><style>.wj-tcu-box{animation:wj-tcu-glow 4.5s ease-in-out infinite}@keyframes wj-tcu-glow{0%,100%{opacity:.85}50%{opacity:1;filter:brightness(1.15)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g><rect x=\"102\" y=\"18\" width=\"36\" height=\"24\" rx=\"5\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><rect x=\"102\" y=\"46\" width=\"36\" height=\"24\" rx=\"5\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><rect x=\"102\" y=\"102\" width=\"36\" height=\"24\" rx=\"5\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><rect x=\"102\" y=\"130\" width=\"36\" height=\"24\" rx=\"5\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><rect x=\"102\" y=\"74\" width=\"36\" height=\"24\" rx=\"5\" fill=\"var(--w-amber,#ffc857)\" class=\"wj-tcu-box\"/><text x=\"120\" y=\"91\" font-size=\"14\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\" font-weight=\"700\">23</text></g><line x1=\"150\" y1=\"14\" x2=\"150\" y2=\"136\" stroke=\"var(--w-ink,#e8eef9)\" opacity=\".15\"/><text x=\"176\" y=\"80\" font-size=\"11\" fill=\"var(--w-sub,#a7b4cd)\">1マス分</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "text-orientation-upright",
    "vertical-embed-override",
    "font-feature-vert-vkrn",
    "font-feature-pwid"
   ]
  },
  {
   "id": "word-break-auto-phrase",
   "num": "W-247",
   "name": "Phrase-Based Line Breaking",
   "nameJa": "文節改行（word-break: auto-phrase）",
   "category": "text",
   "description": "word-break: auto-phraseは、lang=\"ja\"の文章を形態素解析し、文節の途中で行が折り返らないよう自動調整する。今までは助詞の直前で改行されて読みにくくなることがあったが、意味のまとまりを保ったまま折り返せる。",
   "useCase": "幅の狭いカードやスマホ幅の見出し・キャプションで、日本語の文節が不自然な位置でちぎれるのを防ぎたいとき。",
   "code": ".wba-phrase{\n  word-break: auto-phrase;\n}\n/* lang=\"ja\" が指定された要素にのみ効果がある */",
   "tags": [
    "CSS",
    "日本語",
    "改行",
    "可読性",
    "先端"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"文節改行のデモ\"><style>.wj-wba-bad{animation:wj-wba-fade 5s ease-in-out infinite}.wj-wba-good{animation:wj-wba-fade2 5s ease-in-out infinite}@keyframes wj-wba-fade{0%,45%{opacity:1}55%,100%{opacity:.15}}@keyframes wj-wba-fade2{0%,45%{opacity:.15}55%,100%{opacity:1}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g class=\"wj-wba-bad\"><rect x=\"20\" y=\"34\" width=\"150\" height=\"14\" rx=\"4\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".7\"/><rect x=\"20\" y=\"54\" width=\"18\" height=\"14\" rx=\"4\" fill=\"var(--w-amber,#ffc857)\"/><text x=\"98\" y=\"90\" font-size=\"11\" fill=\"var(--w-sub,#a7b4cd)\">文節の途中で分断</text></g><g class=\"wj-wba-good\"><rect x=\"20\" y=\"34\" width=\"132\" height=\"14\" rx=\"4\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".85\"/><rect x=\"20\" y=\"54\" width=\"36\" height=\"14\" rx=\"4\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".85\"/><text x=\"98\" y=\"90\" font-size=\"11\" fill=\"var(--w-ink,#e8eef9)\">文節の切れ目で改行</text></g><rect x=\"20\" y=\"112\" width=\"200\" height=\"2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".25\"/></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "ruby-overhang",
    "line-break-strict",
    "text-autospace",
    "text-orientation-upright"
   ]
  },
  {
   "id": "line-break-strict",
   "num": "W-248",
   "name": "Line Break Strictness",
   "nameJa": "禁則の強さ調整（line-break）",
   "category": "text",
   "description": "line-breakは、行頭に句読点や小書き文字を置かない禁則処理の厳しさを4段階で切り替える。strictは新聞のように最も厳格な禁則、looseは短い行幅でも詰まりすぎないゆるい禁則にする。",
   "useCase": "見出しの折り返しは行末の記号をやや許容したい、本文は厳格な禁則で品位を保ちたいなど、要素ごとに禁則の厳しさを使い分けたいとき。",
   "code": ".wj-body{ line-break: strict; }  /* 句読点の行頭禁止を厳格に */\n.wj-caption{ line-break: loose; }  /* 狭い幅向けにゆるく */",
   "tags": [
    "CSS",
    "日本語",
    "禁則処理",
    "改行",
    "整列"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"禁則の強さ調整のデモ\"><style>.wj-lbs-mk{animation:wj-lbs-snap 4.5s ease-in-out infinite}@keyframes wj-lbs-snap{0%,15%{transform:translate(0,0)}27%,72%{transform:translate(14px,-28px)}88%,100%{transform:translate(0,0)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"24\" y=\"46\" width=\"192\" height=\"14\" rx=\"4\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".55\"/><rect x=\"24\" y=\"76\" width=\"60\" height=\"14\" rx=\"4\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".55\"/><rect class=\"wj-lbs-mk\" x=\"8\" y=\"76\" width=\"12\" height=\"14\" rx=\"3\" fill=\"var(--w-amber,#ffc857)\"/><line x1=\"24\" y1=\"70\" x2=\"216\" y2=\"70\" stroke=\"var(--w-ink,#e8eef9)\" opacity=\".15\"/></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "word-break-auto-phrase",
    "hanging-punctuation",
    "ruby-group-jukugo",
    "palt-tracking"
   ]
  },
  {
   "id": "overflow-wrap-wbr",
   "num": "W-249",
   "name": "Manual Break Opportunities",
   "nameJa": "改行位置を明示的に制御（overflow-wrap / wbr）",
   "category": "text",
   "description": "overflow-wrap: anywhereは、URLやIDのように途中に区切りがない長い文字列でも強制的に折り返してはみ出しを防ぐ。逆に自然文では<wbr>を挟むことで、余分な空白を入れずに任意の位置だけへ改行の候補地点を用意できる。",
   "useCase": "狭いカードにURLや長い英数字の識別子を収めたいとき、日本語の長いカタカナ複合語の途中に改行してもよい箇所だけ指定したいとき。",
   "code": "<p style=\"overflow-wrap:anywhere\">https://example.com/very/long/path</p>\n\n<p>今日のオ<wbr>ススメ<wbr>アプリ</p>",
   "tags": [
    "CSS",
    "HTML",
    "改行",
    "レイアウト",
    "はみ出し防止"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"改行位置を明示的に制御するデモ\"><style>.wj-owr-of{animation:wj-owr-ov 4.8s ease-in-out infinite}.wj-owr-fx{animation:wj-owr-fx 4.8s ease-in-out infinite}@keyframes wj-owr-ov{0%,42%{opacity:1}52%,100%{opacity:0}}@keyframes wj-owr-fx{0%,42%{opacity:0}52%,100%{opacity:1}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"20\" y=\"30\" width=\"200\" height=\"34\" rx=\"6\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-dasharray=\"3 3\" opacity=\".4\"/><g class=\"wj-owr-of\"><rect x=\"26\" y=\"40\" width=\"230\" height=\"14\" rx=\"4\" fill=\"var(--w-amber,#ffc857)\" opacity=\".8\"/></g><g class=\"wj-owr-fx\"><rect x=\"26\" y=\"40\" width=\"188\" height=\"14\" rx=\"4\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".85\"/><rect x=\"26\" y=\"86\" width=\"70\" height=\"14\" rx=\"4\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".85\"/></g></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "text-orientation-upright",
    "word-break-auto-phrase",
    "line-break-strict",
    "vertical-embed-override"
   ]
  },
  {
   "id": "hanging-punctuation",
   "num": "W-250",
   "name": "Hanging Punctuation",
   "nameJa": "句読点のぶら下げ組み（hanging-punctuation）",
   "category": "text",
   "description": "hanging-punctuationは、行末の句読点をテキストボックスの外側へはみ出させ、文字の並びの右端をそろえて見せる組版技法。allow-endを指定すると、行末に来た「、」「。」が右マージンの外へぶら下がり、他の行と視覚的な右端がぴったり揃う。",
   "useCase": "雑誌的なエディトリアルLPや引用ブロックで、行末の見た目を厳密に整列させたい高級感のある本文レイアウトに使う。",
   "code": ".wj-hang{\n  hanging-punctuation: allow-end;\n  text-align: justify;\n}",
   "tags": [
    "CSS",
    "日本語",
    "組版",
    "整列",
    "高級感"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"句読点のぶら下げ組みのデモ\"><style>.wj-hgp-mk{animation:wj-hgp-out 4.5s ease-in-out infinite}@keyframes wj-hgp-out{0%,15%{transform:translateX(0)}27%,75%{transform:translateX(14px)}88%,100%{transform:translateX(0)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><line x1=\"204\" y1=\"34\" x2=\"204\" y2=\"120\" stroke=\"var(--w-ink,#e8eef9)\" opacity=\".25\" stroke-dasharray=\"3 3\"/><rect x=\"24\" y=\"42\" width=\"180\" height=\"12\" rx=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".55\"/><rect x=\"24\" y=\"62\" width=\"176\" height=\"12\" rx=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".55\"/><circle class=\"wj-hgp-mk\" cx=\"200\" cy=\"68\" r=\"4\" fill=\"var(--w-amber,#ffc857)\"/><rect x=\"24\" y=\"82\" width=\"168\" height=\"12\" rx=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".55\"/></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "palt-tracking",
    "line-break-strict",
    "text-spacing-trim",
    "vertical-writing"
   ]
  },
  {
   "id": "text-spacing-trim",
   "num": "W-251",
   "name": "Punctuation Spacing Trim",
   "nameJa": "約物の前後アキ詰め（text-spacing-trim）",
   "category": "text",
   "description": "全角の括弧や句読点はグリフの内部に半角分の余白を持つため、続けて並ぶと間延びして見える。text-spacing-trimはその余白を規則に沿ってトリミングし、隣り合う約物どうしの間隔を締める。日本語と英数字の間隔を自動挿入するtext-autospaceとは逆に、約物どうしの余分な間隔を詰める側の調整。",
   "useCase": "括弧書きや記号が連続する見出し・キャプションで、約物の間が間延びして見えるのを引き締めたいとき。",
   "code": ".wj-trim{\n  text-spacing-trim: space-first; /* 行頭以外の開き括弧を詰める */\n}",
   "tags": [
    "CSS",
    "日本語",
    "組版",
    "約物",
    "すっきり"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"約物の前後アキ詰めのデモ\"><style>.wj-tst-gap{animation:wj-tst-close 4.5s ease-in-out infinite}@keyframes wj-tst-close{0%,45%{transform:translateX(0)}70%,100%{transform:translateX(-56px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"60\" y=\"62\" width=\"20\" height=\"34\" rx=\"4\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".9\"/><g class=\"wj-tst-gap\"><rect x=\"140\" y=\"62\" width=\"20\" height=\"34\" rx=\"4\" fill=\"var(--w-amber,#ffc857)\" opacity=\".9\"/></g><line x1=\"80\" y1=\"58\" x2=\"80\" y2=\"100\" stroke=\"var(--w-sub,#a7b4cd)\" opacity=\".2\" stroke-dasharray=\"2 3\"/><text x=\"120\" y=\"128\" font-size=\"11\" fill=\"var(--w-sub,#a7b4cd)\" text-anchor=\"middle\">」（ の間を詰める</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "palt-tracking",
    "hanging-punctuation",
    "font-feature-pwid",
    "ruby-overhang"
   ]
  },
  {
   "id": "text-orientation-upright",
   "num": "W-252",
   "name": "Upright Text Orientation",
   "nameJa": "縦書き中の英数字を直立させる（text-orientation）",
   "category": "text",
   "description": "縦書き（writing-mode: vertical-rl）の既定はtext-orientation: mixedで、英数字を90度横倒しにして縦の流れへ埋め込む。text-orientation: uprightに切り替えると、アルファベットも回転させず1文字ずつ直立させたまま縦に積む見た目になる。",
   "useCase": "縦書きの見出しでロゴやブランド名のアルファベットだけ横倒しにしたくない場合、縦組みの表の見出しラベルを直立のまま並べたい場合。",
   "code": ".wj-mixed{ text-orientation: mixed; }   /* 英字は横倒し */\n.wj-upright{ text-orientation: upright; } /* 英字も直立 */",
   "tags": [
    "CSS",
    "縦書き",
    "日本語",
    "レイアウト"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"縦書き中の英数字を直立させるデモ\"><style>.wj-tor-a{animation:wj-tor-rot 4.5s ease-in-out infinite;transform-origin:120px 96px}@keyframes wj-tor-rot{0%,40%{transform:rotate(90deg)}60%,100%{transform:rotate(0deg)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"104\" y=\"24\" width=\"32\" height=\"30\" rx=\"5\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".45\"/><rect x=\"104\" y=\"58\" width=\"32\" height=\"30\" rx=\"5\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".45\"/><rect x=\"105\" y=\"81\" width=\"30\" height=\"30\" rx=\"5\" fill=\"var(--w-amber,#ffc857)\" class=\"wj-tor-a\"/><text x=\"120\" y=\"101\" font-size=\"16\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\" font-weight=\"700\">A</text><rect x=\"104\" y=\"116\" width=\"32\" height=\"30\" rx=\"5\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".45\"/></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "vertical-embed-override",
    "logical-properties-vertical",
    "text-combine-upright",
    "font-feature-vert-vkrn"
   ]
  },
  {
   "id": "font-feature-vert-vkrn",
   "num": "W-253",
   "name": "Vertical Glyph Substitution & Kerning",
   "nameJa": "縦書き専用のグリフ差し替えとカーニング（vert / vkrn）",
   "category": "text",
   "description": "font-feature-settingsの'vert'は、括弧や小書き仮名など縦書き専用に用意された字形へ自動で差し替えるOpenType機能。'vkrn'は縦方向に並んだ字間の詰まり過ぎ・空き過ぎを補正するカーニング。writing-mode: vertical-rlと組み合わせて使う。",
   "useCase": "縦書きの本文で丸括弧やかぎ括弧が横向きのまま表示されてしまう、字間が不揃いに見えるのを、対応フォントの力を借りて自動補正したいとき。",
   "code": ".wj-vert-body{\n  writing-mode: vertical-rl;\n  font-feature-settings: \"vert\" 1, \"vkrn\" 1;\n}\n/* 実際に効果が出るかはフォント側の対応次第 */",
   "tags": [
    "CSS",
    "縦書き",
    "OpenType",
    "日本語",
    "フォント"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"縦書き専用のグリフ差し替えとカーニングのデモ\"><style>.wj-vkn-mv{animation:wj-vkn-close 4.5s ease-in-out infinite}@keyframes wj-vkn-close{0%,40%{transform:translateY(0)}70%,100%{transform:translateY(-10px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"104\" y=\"26\" width=\"32\" height=\"30\" rx=\"5\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".9\"/><text x=\"120\" y=\"47\" font-size=\"16\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\" font-weight=\"700\">「</text><g class=\"wj-vkn-mv\"><rect x=\"104\" y=\"62\" width=\"32\" height=\"30\" rx=\"5\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".9\"/><text x=\"120\" y=\"83\" font-size=\"16\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\" font-weight=\"700\">字</text></g><g class=\"wj-vkn-mv\" style=\"animation-delay:.15s\"><rect x=\"104\" y=\"98\" width=\"32\" height=\"30\" rx=\"5\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".9\"/><text x=\"120\" y=\"119\" font-size=\"16\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\" font-weight=\"700\">」</text></g></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "text-orientation-upright",
    "vertical-embed-override",
    "text-combine-upright",
    "font-feature-pwid"
   ]
  },
  {
   "id": "font-feature-pwid",
   "num": "W-254",
   "name": "Proportional Widths for Numerals & Kana",
   "nameJa": "数字・かなをプロポーショナル幅にする（pwid）",
   "category": "text",
   "description": "和文フォントの数字やかなは既定で全角の等幅グリッドに収まっているため、「1」と「8」のように線の量が違う文字でも同じ幅になり、間延びして見えることがある。font-feature-settings: \"pwid\"は文字ごとの自然な太さに応じたプロポーショナル幅の字形に差し替える。",
   "useCase": "見出しや価格表示で数字の並びを引き締めたいとき、かな交じりの文章を等幅の堅い印象から解放したいとき。",
   "code": ".wj-pwid{\n  font-feature-settings: \"pwid\" 1;\n}",
   "tags": [
    "CSS",
    "OpenType",
    "日本語",
    "数字",
    "すっきり"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"数字をプロポーショナル幅にするデモ\"><style>.wj-pwd-a{animation:wj-pwd-shrink 4.5s ease-in-out infinite}@keyframes wj-pwd-shrink{0%,40%{transform:scaleX(1)}70%,100%{transform:scaleX(.55)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g><rect x=\"30\" y=\"60\" width=\"38\" height=\"46\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><rect x=\"76\" y=\"60\" width=\"38\" height=\"46\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><rect x=\"122\" y=\"60\" width=\"38\" height=\"46\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><rect x=\"168\" y=\"60\" width=\"38\" height=\"46\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><rect x=\"30\" y=\"60\" width=\"38\" height=\"46\" rx=\"6\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".9\" style=\"transform-origin:49px 83px\" class=\"wj-pwd-a\"/><text x=\"49\" y=\"90\" font-size=\"20\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\" font-weight=\"700\">1</text><rect x=\"76\" y=\"60\" width=\"38\" height=\"46\" rx=\"6\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".9\"/><text x=\"95\" y=\"90\" font-size=\"20\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\" font-weight=\"700\">8</text></g></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "text-combine-upright",
    "text-spacing-trim",
    "font-feature-vert-vkrn",
    "font-variant-east-asian"
   ]
  },
  {
   "id": "font-variant-east-asian",
   "num": "W-255",
   "name": "East Asian Glyph Variants",
   "nameJa": "旧字体・ルビ用字形の切り替え（font-variant-east-asian）",
   "category": "text",
   "description": "font-variant-east-asianは、同じ文字でもJIS規格の版によって異なる字形（jis78の旧字体やjis04の新字体など）や、ルビ表示に最適化した小さめで少し太いruby用字形へ切り替える。フォントがその字形バリエーションを収録している場合に有効になる。",
   "useCase": "屋号や固有名詞で意図的に旧字体の風合いを出したいとき、ルビの視認性を上げる専用グリフを使いたいとき。",
   "code": ".wj-old-style{\n  font-variant-east-asian: jis78;\n}\n.wj-ruby-text{\n  font-variant-east-asian: ruby;\n}",
   "tags": [
    "CSS",
    "OpenType",
    "日本語",
    "旧字体",
    "和風"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"旧字体・ルビ用字形の切り替えのデモ\"><style>.wj-fea-old{animation:wj-fea-cross 4.5s ease-in-out infinite}.wj-fea-new{animation:wj-fea-cross2 4.5s ease-in-out infinite}@keyframes wj-fea-cross{0%,45%{opacity:1}55%,100%{opacity:0}}@keyframes wj-fea-cross2{0%,45%{opacity:0}55%,100%{opacity:1}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"80\" y=\"46\" width=\"80\" height=\"66\" rx=\"8\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".9\"/><text class=\"wj-fea-old\" x=\"120\" y=\"93\" font-size=\"30\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\" font-weight=\"700\">桧</text><text class=\"wj-fea-new\" x=\"120\" y=\"93\" font-size=\"30\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\" font-weight=\"700\">檜</text><text x=\"120\" y=\"132\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\" text-anchor=\"middle\">jis78 ⇄ jis04</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "text-combine-upright",
    "font-feature-vert-vkrn",
    "font-feature-pwid",
    "vertical-writing"
   ]
  },
  {
   "id": "unicode-range-subset",
   "num": "W-256",
   "name": "Japanese Font Subsetting via unicode-range",
   "nameJa": "和文Webフォントの部分読み込み（unicode-rangeサブセット）",
   "category": "text",
   "description": "和文フォントは数千〜1万字を超えるグリフを持ち丸ごと読み込むと重い。同じfont-familyに対してunicode-rangeの異なる@font-faceを複数用意しておくと、ブラウザはページ内に実際に登場する文字を含む範囲のファイルだけを選んで読み込む。",
   "useCase": "ひらがな・カタカナ・常用漢字だけのサイトで、収録字数の多い明朝体やゴシック体を軽量に配信したいとき。",
   "code": "@font-face{\n  font-family:\"WJFont\";\n  src:url(\"wjfont-kana.woff2\") format(\"woff2\");\n  unicode-range:U+3040-30FF; /* かな */\n}\n@font-face{\n  font-family:\"WJFont\";\n  src:url(\"wjfont-kanji.woff2\") format(\"woff2\");\n  unicode-range:U+4E00-9FFF; /* 漢字 */\n}",
   "tags": [
    "CSS",
    "Webフォント",
    "日本語",
    "パフォーマンス"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"和文Webフォントの部分読み込みのデモ\"><style>.wj-unr-hit{animation:wj-unr-glow 4.5s ease-in-out infinite}@keyframes wj-unr-glow{0%,30%{opacity:.3}45%,100%{opacity:1}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"24\" y=\"30\" width=\"60\" height=\"90\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".25\"/><text x=\"54\" y=\"80\" font-size=\"10\" fill=\"var(--w-ink,#e8eef9)\" text-anchor=\"middle\">かな</text><rect class=\"wj-unr-hit\" x=\"90\" y=\"30\" width=\"60\" height=\"90\" rx=\"6\" fill=\"var(--w-accent,#63d9e8)\"/><text x=\"120\" y=\"80\" font-size=\"10\" fill=\"var(--w-bg,#101830)\" text-anchor=\"middle\" font-weight=\"700\">漢字</text><rect x=\"156\" y=\"30\" width=\"60\" height=\"90\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".25\"/><text x=\"186\" y=\"80\" font-size=\"10\" fill=\"var(--w-ink,#e8eef9)\" text-anchor=\"middle\">記号</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "font-metric-override",
    "ruby-overhang",
    "text-orientation-upright",
    "content-visibility"
   ]
  },
  {
   "id": "font-metric-override",
   "num": "W-257",
   "name": "Font Metric Overrides for Fallback Matching",
   "nameJa": "フォールバックとのズレ吸収（size-adjust / ascent-override）",
   "category": "text",
   "description": "和文Webフォントの読み込み中はローカルのフォールバック書体で表示され、読み込み後に置き換わると行の高さや文字サイズがずれてガクッとレイアウトが動く。size-adjustでフォールバック側の文字サイズ比率を、ascent-overrideで上端の基準線をWebフォント側に近づけると、置き換わり時のズレを抑えられる。size-adjustは主要ブラウザに広く定着済みだが、ascent-overrideはSafari未対応のため@supportsで分けるのが安全。",
   "useCase": "読み込みに時間のかかる和文Webフォントを使うページで、表示中のガタつき（レイアウトシフト）を減らしたいとき。",
   "code": "@font-face{\n  font-family:\"wj-fallback\";\n  src:local(\"Hiragino Sans\");\n  size-adjust: 92%;\n}\n@supports font-face(ascent-override:90%){\n  @font-face{\n    font-family:\"wj-fallback\";\n    src:local(\"Hiragino Sans\");\n    ascent-override: 90%;\n  }\n}",
   "tags": [
    "CSS",
    "Webフォント",
    "日本語",
    "パフォーマンス",
    "レイアウトシフト"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"フォールバックとのズレ吸収のデモ\"><style>.wj-fmo-fb{animation:wj-fmo-snap 4.5s ease-in-out infinite}@keyframes wj-fmo-snap{0%,35%{transform:translateY(-10px);opacity:.5}55%,100%{transform:translateY(0);opacity:1}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><line x1=\"30\" y1=\"100\" x2=\"210\" y2=\"100\" stroke=\"var(--w-ink,#e8eef9)\" opacity=\".2\" stroke-dasharray=\"3 3\"/><rect x=\"30\" y=\"60\" width=\"80\" height=\"40\" rx=\"6\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".9\"/><rect class=\"wj-fmo-fb\" x=\"130\" y=\"60\" width=\"80\" height=\"40\" rx=\"6\" fill=\"var(--w-amber,#ffc857)\" opacity=\".9\"/></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "unicode-range-subset",
    "ruby-overhang",
    "text-orientation-upright",
    "text-emphasis-dots"
   ]
  },
  {
   "id": "ruby-heading-reveal",
   "num": "W-258",
   "name": "Animated Ruby Heading Reveal",
   "nameJa": "ルビ付き見出しのアニメーション演出",
   "category": "text",
   "description": "<ruby>のrt要素だけをCSSアニメーションの対象にして、見出しの本体が先に立ち上がり、ふりがなが一拍遅れてふわっと追いかけるように出現させる演出。ルビと本体を別レイヤーとして動かせるHTML標準のマークアップだからこそ可能な組み合わせ。",
   "useCase": "動画のオープニングテロップやLPのファーストビュー見出しで、難読な商品名・屋号にルビを添えつつ印象的に登場させたいとき。",
   "code": "@keyframes wj-rt-in{ from{opacity:0; transform:translateY(6px)} to{opacity:1; transform:translateY(0)} }\nruby rt{ animation: wj-rt-in .5s .4s both; }",
   "tags": [
    "CSS",
    "アニメーション",
    "ふりがな",
    "見出し",
    "印象的"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"ルビ付き見出しのアニメーションのデモ\"><style>.wj-rha-base{animation:wj-rha-rise 4.5s ease-out infinite}.wj-rha-rt{animation:wj-rha-rise2 4.5s ease-out infinite}@keyframes wj-rha-rise{0%,10%{opacity:0;transform:translateY(14px)}30%,100%{opacity:1;transform:translateY(0)}}@keyframes wj-rha-rise2{0%,30%{opacity:0;transform:translateY(8px)}50%,100%{opacity:1;transform:translateY(0)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g class=\"wj-rha-base\"><rect x=\"42\" y=\"66\" width=\"60\" height=\"54\" rx=\"7\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".9\"/><rect x=\"112\" y=\"66\" width=\"60\" height=\"54\" rx=\"7\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".9\"/></g><g class=\"wj-rha-rt\"><rect x=\"48\" y=\"42\" width=\"48\" height=\"15\" rx=\"5\" fill=\"var(--w-amber,#ffc857)\"/><rect x=\"118\" y=\"42\" width=\"48\" height=\"15\" rx=\"5\" fill=\"var(--w-amber,#ffc857)\"/></g></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "typewriter",
    "ruby-overhang",
    "gradient-text",
    "blur-reveal-text"
   ]
  },
  {
   "id": "canvas-measuretext",
   "num": "W-259",
   "name": "Canvas measureText / TextMetrics",
   "nameJa": "文字幅を測るmeasureText",
   "category": "text",
   "description": "ctx.measureText(text)は実際に描かずにその文字列の描画幅などをTextMetricsオブジェクトとして返す。widthのほか、actualBoundingBoxAscent/Descentで文字の実際の高さも取れるため、canvas上でテキストを中央揃えしたり、枠内に収まるようフォントサイズを自動調整したりする計算に使う。",
   "useCase": "canvas生成のOGP画像やバッジで、文字列の長さに応じて背景枠の幅を自動で合わせたいときに使う。",
   "code": "ctx.font = '24px sans-serif';\nconst m = ctx.measureText('WazaScout');\nconst w = m.width;\nconst h = m.actualBoundingBoxAscent + m.actualBoundingBoxDescent;\nctx.fillRect(100 - w/2 - 8, 60 - h/2 - 4, w + 16, h + 8);\nctx.fillText('WazaScout', 100 - w/2, 60 + h/2);",
   "tags": [
    "Canvas",
    "JavaScript",
    "テキスト",
    "文字幅",
    "測定"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"measureTextで文字幅を測るデモ\"><style>.cvmtx-br{animation:cvmtx-ex 4s ease-in-out infinite}@keyframes cvmtx-ex{0%,20%{stroke-dasharray:0 200}50%,80%{stroke-dasharray:200 200}100%{stroke-dasharray:0 200}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><text x=\"120\" y=\"80\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"22\" fill=\"var(--w-ink,#e8eef9)\">Waza</text><path class=\"cvmtx-br\" d=\"M52 92h136\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"2\" stroke-linecap=\"round\"/><path d=\"M52 86v12M188 86v12\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"2\" stroke-linecap=\"round\"/><text x=\"120\" y=\"112\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">metrics.width</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "canvas-ctx-filter",
    "canvas-getimagedata",
    "canvas-path2d",
    "offscreen-canvas-worker"
   ]
  },
  {
   "id": "vertical-embed-override",
   "num": "W-260",
   "name": "Horizontal Islands in Vertical Text",
   "nameJa": "縦書き文書内の表・画像を横書きに戻す",
   "category": "layout",
   "description": "縦書きの記事内に表や画像・コードブロックを差し込むときは、その要素だけwriting-mode: horizontal-tbを指定して横書きに戻す。周囲は縦の流れのまま、埋め込んだ要素の中だけ通常の横組みで読める。",
   "useCase": "縦書きのエッセイ記事に、数値の表や図版キャプション、埋め込みツイートなど横書きのほうが読みやすい要素を挟みたいとき。",
   "code": ".wj-vert-article{\n  writing-mode: vertical-rl;\n}\n.wj-vert-article table,\n.wj-vert-article img,\n.wj-vert-article pre{\n  writing-mode: horizontal-tb;\n}",
   "tags": [
    "CSS",
    "縦書き",
    "レイアウト",
    "日本語"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"縦書き文書内の表を横書きに戻すデモ\"><style>.wj-veo-tb{animation:wj-veo-pop 4.5s ease-in-out infinite}@keyframes wj-veo-pop{0%,100%{opacity:.9}50%{opacity:1;filter:brightness(1.12)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g opacity=\".4\"><rect x=\"20\" y=\"20\" width=\"7\" height=\"44\" rx=\"3\" fill=\"var(--w-sub,#a7b4cd)\"/><rect x=\"20\" y=\"74\" width=\"7\" height=\"44\" rx=\"3\" fill=\"var(--w-sub,#a7b4cd)\"/><rect x=\"30\" y=\"20\" width=\"7\" height=\"44\" rx=\"3\" fill=\"var(--w-sub,#a7b4cd)\"/><rect x=\"30\" y=\"74\" width=\"7\" height=\"44\" rx=\"3\" fill=\"var(--w-sub,#a7b4cd)\"/><rect x=\"40\" y=\"20\" width=\"7\" height=\"44\" rx=\"3\" fill=\"var(--w-sub,#a7b4cd)\"/><rect x=\"40\" y=\"74\" width=\"7\" height=\"44\" rx=\"3\" fill=\"var(--w-sub,#a7b4cd)\"/><rect x=\"50\" y=\"20\" width=\"7\" height=\"44\" rx=\"3\" fill=\"var(--w-sub,#a7b4cd)\"/><rect x=\"50\" y=\"74\" width=\"7\" height=\"44\" rx=\"3\" fill=\"var(--w-sub,#a7b4cd)\"/><rect x=\"60\" y=\"20\" width=\"7\" height=\"44\" rx=\"3\" fill=\"var(--w-sub,#a7b4cd)\"/><rect x=\"60\" y=\"74\" width=\"7\" height=\"44\" rx=\"3\" fill=\"var(--w-sub,#a7b4cd)\"/></g><rect x=\"90\" y=\"48\" width=\"120\" height=\"54\" rx=\"6\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".18\" stroke=\"var(--w-accent,#63d9e8)\" stroke-dasharray=\"3 3\"/><rect class=\"wj-veo-tb\" x=\"102\" y=\"58\" width=\"46\" height=\"14\" rx=\"3\" fill=\"var(--w-amber,#ffc857)\"/><rect class=\"wj-veo-tb\" x=\"102\" y=\"78\" width=\"80\" height=\"14\" rx=\"3\" fill=\"var(--w-amber,#ffc857)\" opacity=\".7\"/></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "text-orientation-upright",
    "logical-properties-vertical",
    "text-combine-upright",
    "font-feature-vert-vkrn"
   ]
  },
  {
   "id": "logical-properties-vertical",
   "num": "W-261",
   "name": "Logical Properties for Vertical Writing",
   "nameJa": "縦書き対応のレイアウト設計（論理プロパティ）",
   "category": "layout",
   "description": "margin-inline-startやblock-sizeなどの論理プロパティは、writing-modeに応じて物理方向を自動で読み替える。縦書き（vertical-rl）ではinline軸が上下、block軸が左右に入れ替わるため、marginやwidthを物理方向（top/leftなど）で書き直さずに済む。",
   "useCase": "横書き用に組んだカードやボタンのCSSを、縦書きページでも margin-left や width の書き直しなしに使い回したいとき。",
   "code": ".wj-card{\n  inline-size: 240px;      /* 横書きではwidth、縦書きではheightに相当 */\n  margin-block-start: 16px; /* 縦書きでは左マージンに相当 */\n}",
   "tags": [
    "CSS",
    "縦書き",
    "レイアウト",
    "国際化"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"論理プロパティのデモ\"><style>.wj-lgp-arr{animation:wj-lgp-slide 4.5s ease-in-out infinite}@keyframes wj-lgp-slide{0%,100%{opacity:.85}50%{opacity:1;transform:translateX(4px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"120\" y=\"30\" width=\"90\" height=\"90\" rx=\"8\" fill=\"var(--w-accent,#63d9e8)\" opacity=\".16\" stroke=\"var(--w-accent,#63d9e8)\"/><line class=\"wj-lgp-arr\" x1=\"120\" y1=\"16\" x2=\"120\" y2=\"28\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"3\"/><text x=\"120\" y=\"12\" font-size=\"10\" fill=\"var(--w-amber,#ffc857)\" text-anchor=\"middle\">block-start</text><line class=\"wj-lgp-arr\" x1=\"106\" y1=\"75\" x2=\"118\" y2=\"75\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"3\"/><text x=\"60\" y=\"79\" font-size=\"10\" fill=\"var(--w-amber,#ffc857)\" text-anchor=\"middle\">inline-start</text><text x=\"165\" y=\"79\" font-size=\"11\" fill=\"var(--w-ink,#e8eef9)\" text-anchor=\"middle\">縦書き時</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "vertical-embed-override",
    "text-orientation-upright",
    "vertical-scroll-snap",
    "text-combine-upright"
   ]
  },
  {
   "id": "houdini-layout-animation-worklet",
   "num": "W-262",
   "name": "Layout Worklet / Animation Worklet Status",
   "nameJa": "Layout WorkletとAnimation Workletの現状",
   "category": "layout",
   "description": "CSS Houdiniにはこの2つも構想されている。Layout Worklet（registerLayout）はdisplay: layout(name)のように独自のレイアウトアルゴリズムをJSで定義できる仕組み、Animation Worklet（registerAnimator）はscrollTimelineなどメインスレッドと切り離した高性能なアニメーションを書ける仕組み。どちらもW3C Houdini Draftの段階で、Layout WorkletはMDNにも独立ページが無いほど実装が薄く、Chromeの実験的機能フラグを有効にしないと動かない。",
   "useCase": "現時点で本番のプロダクトに組み込む用途ではなく、「将来こうなる」を把握したうえでmasonryなどの独自レイアウトは今はCSS Grid Level 3のmasonry値やJSライブラリで代替する判断材料として使う。",
   "code": "// 有効化にはChromeの実験的フラグが必要（本番非推奨）\n// registerLayout('masonry-like', class { ... });\n// CSS: display: layout(masonry-like);\n\n// registerAnimator('scrollFade', class { ... });\n// CSS Animation Worklet も同様にドラフト段階",
   "tags": [
    "CSS Houdini",
    "Layout Worklet",
    "Animation Worklet",
    "実験的"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"Layout WorkletとAnimation Workletの現状のデモ\"><style>.hlaw-fl{animation:hlaw-blink 3.2s steps(1) infinite}@keyframes hlaw-blink{0%,60%{opacity:1}70%,100%{opacity:.3}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"34\" y=\"30\" width=\"70\" height=\"34\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><rect x=\"34\" y=\"70\" width=\"46\" height=\"50\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><rect x=\"86\" y=\"70\" width=\"70\" height=\"24\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><rect x=\"112\" y=\"30\" width=\"44\" height=\"34\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><rect x=\"86\" y=\"100\" width=\"70\" height=\"20\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><g class=\"hlaw-fl\"><rect x=\"166\" y=\"30\" width=\"46\" height=\"90\" rx=\"8\" fill=\"none\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"2\" stroke-dasharray=\"5 4\"/><text x=\"189\" y=\"80\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"9\" fill=\"var(--w-amber,#ffc857)\">flag</text></g><text x=\"120\" y=\"136\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">registerLayout / registerAnimator</text></svg>",
   "useFor": [
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "houdini-paint-worklet",
    "css-registerproperty-js",
    "css-typed-om"
   ]
  },
  {
   "id": "coordinate-grid-snap",
   "num": "W-263",
   "name": "Snap Coordinates to a Grid",
   "nameJa": "座標のグリッド吸着",
   "category": "layout",
   "description": "自由な位置の座標を、一定間隔(グリッド単位)の最も近い倍数に丸める処理。Math.round(値/単位)*単位という1行の式で、ノードの位置やサイズを見えない格子に揃えられる。図解では座標がバラバラだと余白が不揃いに見えるため、生成時点でこの処理を通しておくと整った印象になる。",
   "useCase": "図解やダイアグラムのノード配置、アイコンの整列など、複数の要素の位置を機械的に揃えて「そろっている」印象を作りたいときに使う。",
   "code": "function snap(value, unit = 20) {\n  return Math.round(value / unit) * unit;\n}\n// snap(73, 20) -> 80\n// snap(58, 20) -> 60",
   "tags": [
    "レイアウト",
    "図解",
    "グリッド",
    "座標計算",
    "そろう快感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"座標をグリッドに吸着させるデモ\"><style>.cgs-mover{animation:cgs-snap 3s cubic-bezier(.34,1.56,.64,1) infinite}@keyframes cgs-snap{0%,40%{transform:translate(0,0)}55%,100%{transform:translate(7px,2px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><circle cx=\"20\" cy=\"20\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"20\" cy=\"40\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"20\" cy=\"60\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"20\" cy=\"80\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"20\" cy=\"100\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"20\" cy=\"120\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"40\" cy=\"20\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"40\" cy=\"40\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"40\" cy=\"60\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"40\" cy=\"80\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"40\" cy=\"100\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"40\" cy=\"120\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"60\" cy=\"20\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"60\" cy=\"40\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"60\" cy=\"60\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"60\" cy=\"80\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"60\" cy=\"100\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"60\" cy=\"120\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"80\" cy=\"20\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"80\" cy=\"40\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"80\" cy=\"60\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"80\" cy=\"80\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"80\" cy=\"100\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"80\" cy=\"120\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"100\" cy=\"20\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"100\" cy=\"40\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"100\" cy=\"60\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"100\" cy=\"80\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"100\" cy=\"100\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"100\" cy=\"120\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"120\" cy=\"20\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"120\" cy=\"40\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"120\" cy=\"60\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"120\" cy=\"80\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"120\" cy=\"100\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"120\" cy=\"120\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"140\" cy=\"20\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"140\" cy=\"40\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"140\" cy=\"60\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"140\" cy=\"80\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"140\" cy=\"100\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"140\" cy=\"120\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"160\" cy=\"20\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"160\" cy=\"40\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"160\" cy=\"60\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"160\" cy=\"80\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"160\" cy=\"100\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"160\" cy=\"120\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"180\" cy=\"20\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"180\" cy=\"40\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"180\" cy=\"60\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"180\" cy=\"80\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"180\" cy=\"100\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"180\" cy=\"120\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"200\" cy=\"20\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"200\" cy=\"40\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"200\" cy=\"60\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"200\" cy=\"80\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"200\" cy=\"100\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"200\" cy=\"120\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"220\" cy=\"20\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"220\" cy=\"40\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"220\" cy=\"60\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"220\" cy=\"80\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"220\" cy=\"100\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><circle cx=\"220\" cy=\"120\" r=\"1.2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\"/><rect x=\"73\" y=\"58\" width=\"30\" height=\"22\" rx=\"4\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\" stroke-dasharray=\"3 3\"/><g class=\"cgs-mover\"><rect x=\"80\" y=\"60\" width=\"30\" height=\"20\" rx=\"4\" fill=\"var(--w-accent,#5ad2d9)\" opacity=\".8\"/></g><text x=\"88\" y=\"45\" font-family=\"ui-monospace,monospace\" font-size=\"9\" fill=\"var(--w-sub,#a7b4cd)\">73,58</text><text x=\"120\" y=\"100\" font-family=\"ui-monospace,monospace\" font-size=\"9\" fill=\"var(--w-accent,#5ad2d9)\">80,60</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "layered-hierarchy-layout",
    "polar-to-cartesian-layout",
    "aabb-overlap-detection",
    "grid-template-areas"
   ]
  },
  {
   "id": "layered-hierarchy-layout",
   "num": "W-264",
   "name": "Layered Hierarchy Layout",
   "nameJa": "階層レイアウト（層ごとの配置）",
   "category": "layout",
   "description": "親子関係のあるノードを、上から下へ層(レイヤー)ごとにy座標を固定して並べる配置法。同じ層のノードは左端と右端を決め、その間をノード数で等分してx座標を求める。層をまたぐ辺はすべて上の層から下の層へ向かうという制約を守ると、線が絡み合わず読みやすい木構造やフローになる。",
   "useCase": "組織図、依存関係図、意思決定フローなど「誰が誰の下にいるか」がはっきりしている構造を、層ごとにきれいに整列させて描きたいときに使う。",
   "code": "// 層内でN個のノードを左端leftから右端rightまで等間隔に配置\nfunction layerX(i, n, left = 30, right = 210) {\n  return n === 1 ? (left + right) / 2 : left + (i * (right - left)) / (n - 1);\n}\n// layerX(0, 3) -> 30, layerX(1, 3) -> 120, layerX(2, 3) -> 210\n// y座標は層ごとに固定値(topMargin + layerIndex * layerGap)を使う",
   "tags": [
    "レイアウト",
    "図解",
    "組織図",
    "階層",
    "座標計算"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"層ごとにy座標をそろえる階層レイアウトのデモ\"><style>.lhl-0{animation:lhl-p 4.5s infinite}.lhl-1{animation:lhl-p 4.5s infinite;animation-delay:.5s}.lhl-2{animation:lhl-p 4.5s infinite;animation-delay:1s}@keyframes lhl-p{0%,10%,100%{opacity:.55}3%{opacity:1}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><line x1=\"120\" y1=\"25\" x2=\"30\" y2=\"70\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\"/><line x1=\"120\" y1=\"25\" x2=\"120\" y2=\"70\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\"/><line x1=\"120\" y1=\"25\" x2=\"210\" y2=\"70\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\"/><line x1=\"30\" y1=\"70\" x2=\"20\" y2=\"120\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\"/><line x1=\"120\" y1=\"70\" x2=\"70\" y2=\"120\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\"/><line x1=\"120\" y1=\"70\" x2=\"120\" y2=\"120\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\"/><line x1=\"120\" y1=\"70\" x2=\"170\" y2=\"120\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\"/><line x1=\"210\" y1=\"70\" x2=\"220\" y2=\"120\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\"/><circle class=\"lhl-0\" cx=\"120\" cy=\"25\" r=\"9\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"lhl-1\" cx=\"30\" cy=\"70\" r=\"7\" fill=\"var(--w-sub,#a7b4cd)\"/><circle class=\"lhl-1\" cx=\"120\" cy=\"70\" r=\"7\" fill=\"var(--w-sub,#a7b4cd)\"/><circle class=\"lhl-1\" cx=\"210\" cy=\"70\" r=\"7\" fill=\"var(--w-sub,#a7b4cd)\"/><circle class=\"lhl-2\" cx=\"20\" cy=\"120\" r=\"5\" fill=\"var(--w-sub,#a7b4cd)\"/><circle class=\"lhl-2\" cx=\"70\" cy=\"120\" r=\"5\" fill=\"var(--w-sub,#a7b4cd)\"/><circle class=\"lhl-2\" cx=\"120\" cy=\"120\" r=\"5\" fill=\"var(--w-sub,#a7b4cd)\"/><circle class=\"lhl-2\" cx=\"170\" cy=\"120\" r=\"5\" fill=\"var(--w-sub,#a7b4cd)\"/><circle class=\"lhl-2\" cx=\"220\" cy=\"120\" r=\"5\" fill=\"var(--w-sub,#a7b4cd)\"/></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "coordinate-grid-snap",
    "polar-to-cartesian-layout",
    "aabb-overlap-detection",
    "vertical-embed-override"
   ]
  },
  {
   "id": "polar-to-cartesian-layout",
   "num": "W-265",
   "name": "Polar-to-Cartesian Radial Layout",
   "nameJa": "放射配置（極座標→直交座標）",
   "category": "layout",
   "description": "中心の周りにN個のノードを均等な角度で配置する方法。角度をangle=-90°+i・360°/N(上を基準に時計回り)で求め、x=cx+r・cos(angle)、y=cy+r・sin(angle)で直交座標に変換する。極座標(角度と半径)で考えてから座標へ落とし込むことで、ノード数が変わっても同じ式で再配置できる。",
   "useCase": "中心ハブから複数の要素へ放射状に広がるダイアグラム、円環状のメニューやループ図で、ノードを等間隔に並べたいときに使う。",
   "code": "function polarNode(i, n, cx = 120, cy = 75, r = 55) {\n  const angle = -Math.PI / 2 + i * ((2 * Math.PI) / n);\n  return [cx + r * Math.cos(angle), cy + r * Math.sin(angle)];\n}\n// polarNode(0, 6) -> [120, 20]\n// polarNode(1, 6) -> [167.6, 47.5]",
   "tags": [
    "レイアウト",
    "図解",
    "放射状",
    "ハブ&スポーク",
    "座標計算"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"極座標から直交座標へ変換して放射配置するデモ\"><style>.ptc-s0{animation:ptc-p 4.8s infinite;animation-delay:0s}.ptc-s1{animation:ptc-p 4.8s infinite;animation-delay:0.5s}.ptc-s2{animation:ptc-p 4.8s infinite;animation-delay:1s}.ptc-s3{animation:ptc-p 4.8s infinite;animation-delay:1.5s}.ptc-s4{animation:ptc-p 4.8s infinite;animation-delay:2s}.ptc-s5{animation:ptc-p 4.8s infinite;animation-delay:2.5s}@keyframes ptc-p{0%,12%,100%{opacity:.5}4%{opacity:1}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><line class=\"ptc-s0\" x1=\"120\" y1=\"75\" x2=\"120\" y2=\"20\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\"/><line class=\"ptc-s1\" x1=\"120\" y1=\"75\" x2=\"167.6\" y2=\"47.5\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\"/><line class=\"ptc-s2\" x1=\"120\" y1=\"75\" x2=\"167.6\" y2=\"102.5\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\"/><line class=\"ptc-s3\" x1=\"120\" y1=\"75\" x2=\"120\" y2=\"130\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\"/><line class=\"ptc-s4\" x1=\"120\" y1=\"75\" x2=\"72.4\" y2=\"102.5\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\"/><line class=\"ptc-s5\" x1=\"120\" y1=\"75\" x2=\"72.4\" y2=\"47.5\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\"/><circle class=\"ptc-s0\" cx=\"120\" cy=\"20\" r=\"10\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".28\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.2\"/><circle class=\"ptc-s1\" cx=\"167.6\" cy=\"47.5\" r=\"10\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".28\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.2\"/><circle class=\"ptc-s2\" cx=\"167.6\" cy=\"102.5\" r=\"10\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".28\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.2\"/><circle class=\"ptc-s3\" cx=\"120\" cy=\"130\" r=\"10\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".28\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.2\"/><circle class=\"ptc-s4\" cx=\"72.4\" cy=\"102.5\" r=\"10\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".28\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.2\"/><circle class=\"ptc-s5\" cx=\"72.4\" cy=\"47.5\" r=\"10\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".28\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.2\"/><circle cx=\"120\" cy=\"75\" r=\"14\" fill=\"var(--w-accent,#5ad2d9)\"/></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "coordinate-grid-snap",
    "layered-hierarchy-layout",
    "aabb-overlap-detection",
    "connector-fan-attach"
   ]
  },
  {
   "id": "aabb-overlap-detection",
   "num": "W-266",
   "name": "AABB Overlap Detection",
   "nameJa": "矩形の重なり判定",
   "category": "layout",
   "description": "回転していない矩形どうしが重なっているかを判定する最も基本的な方法。片方の左端が相手の右端より左、かつ右端が相手の左端より右、という条件をxとy両方の軸で確認し、4つの条件がすべて真なら重なっていると判定できる。座標を自動計算で決める図解で、ラベルや箱が意図せず重ならないかを事前にチェックするのに使える。",
   "useCase": "自動レイアウトで配置したノードやラベルどうしが重なっていないかを検証し、重なっていたら位置をずらす、といった自動配置ロジックの当たり判定に使う。",
   "code": "function isOverlapping(a, b) {\n  return (\n    a.x < b.x + b.width &&\n    a.x + a.width > b.x &&\n    a.y < b.y + b.height &&\n    a.y + a.height > b.y\n  );\n}\n// isOverlapping({x:150,y:30,width:50,height:40}, {x:175,y:50,width:50,height:40}) -> true",
   "tags": [
    "レイアウト",
    "図解",
    "衝突判定",
    "自動配置"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"矩形どうしのAABB衝突判定のデモ\"><style>.aod-pulse{animation:aod-p 3s ease-in-out infinite}@keyframes aod-p{0%,100%{opacity:.55}50%{opacity:1}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"20\" y=\"30\" width=\"50\" height=\"40\" rx=\"4\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"2\"/><rect x=\"90\" y=\"30\" width=\"50\" height=\"40\" rx=\"4\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"2\"/><circle class=\"aod-pulse\" cx=\"80\" cy=\"90\" r=\"5\" fill=\"var(--w-accent,#5ad2d9)\"/><text x=\"80\" y=\"94\" text-anchor=\"middle\" font-size=\"7\" fill=\"var(--w-bg,#101830)\" font-family=\"ui-sans-serif,system-ui,sans-serif\">OK</text><rect x=\"150\" y=\"30\" width=\"50\" height=\"40\" rx=\"4\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"2\"/><rect x=\"175\" y=\"50\" width=\"50\" height=\"40\" rx=\"4\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"2\"/><rect class=\"aod-pulse\" x=\"175\" y=\"50\" width=\"25\" height=\"20\" fill=\"var(--w-amber,#ffc857)\" opacity=\".45\"/><circle class=\"aod-pulse\" cx=\"187\" cy=\"100\" r=\"5\" fill=\"var(--w-amber,#ffc857)\"/><text x=\"187\" y=\"103\" text-anchor=\"middle\" font-size=\"8\" fill=\"var(--w-bg,#101830)\" font-family=\"ui-sans-serif,system-ui,sans-serif\">!</text><text x=\"80\" y=\"118\" text-anchor=\"middle\" font-size=\"9\" fill=\"var(--w-sub,#a7b4cd)\">重なりなし</text><text x=\"190\" y=\"118\" text-anchor=\"middle\" font-size=\"9\" fill=\"var(--w-sub,#a7b4cd)\">重なりあり</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "coordinate-grid-snap",
    "layered-hierarchy-layout",
    "polar-to-cartesian-layout",
    "vertical-embed-override"
   ]
  },
  {
   "id": "canvas-path2d",
   "num": "W-267",
   "name": "Canvas Path2D",
   "nameJa": "再利用できるパス（Path2D）",
   "category": "shape",
   "description": "Path2Dは複雑な線や図形の輪郭を一度だけ組み立てて使い回せるオブジェクト。同じ形を何度も毎フレーム座標指定し直して描く代わりに、Path2Dを1個作っておきctx.fill(path)やctx.stroke(path)で使い回せるので、コードが整理され描画も軽くなる。SVGのpath dと同じ記法をnew Path2D('M...')で読み込むこともできる。",
   "useCase": "アイコンや星形など決まった形を画面内で何度も描画したいとき、同じ座標計算を繰り返さずに済ませたい場面で使う。",
   "code": "const star = new Path2D(\n  'M50 5 L61 38 L97 38 L68 59 L79 92 L50 71 L21 92 L32 59 L3 38 L39 38 Z'\n);\nctx.fillStyle = '#ffc857';\nctx.fill(star);\nctx.translate(120, 0);\nctx.fill(star);",
   "tags": [
    "Canvas",
    "JavaScript",
    "Path2D",
    "図形",
    "再利用"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"Path2Dで形を再利用するデモ\"><style>.cvp2d-s2{animation:cvp2d-pop 4s ease-in-out infinite}@keyframes cvp2d-pop{0%,20%{opacity:.25;transform:scale(.8)}45%,80%{opacity:1;transform:scale(1)}100%{opacity:.25;transform:scale(.8)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><path d=\"M70 45L76 62L94 62L79 73L85 90L70 79L55 90L61 73L46 62L64 62Z\" fill=\"var(--w-accent,#8fe3d0)\"/><g class=\"cvp2d-s2\" style=\"transform-origin:170px 67px\"><path d=\"M170 45L176 62L194 62L179 73L185 90L170 79L155 90L161 73L146 62L164 62Z\" fill=\"var(--w-amber,#ffc857)\"/></g><text x=\"120\" y=\"128\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">1つのPath2Dを2回fill</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "canvas-ctx-filter",
    "canvas-getimagedata",
    "canvas-measuretext",
    "offscreen-canvas-worker"
   ]
  },
  {
   "id": "canvas-svg-dom-tradeoff",
   "num": "W-268",
   "name": "Canvas vs SVG vs DOM",
   "nameJa": "Canvas・SVG・DOMの使い分けの判断軸",
   "category": "shape",
   "description": "3つとも画面に絵を出せるが性質が違う。DOM/SVGは1要素＝1オブジェクトとして残るため、個別にクリック判定やCSSアニメを当てやすく、画面拡大しても輪郭が滲まない（ベクター）が、要素数が数千に増えると描画・レイアウト計算が重くなる。Canvasは「絵の具で塗った跡」だけが残るビットマップで、要素という概念がないため大量描画に強い代わりに、1つ1つの図形にホバーやフォーカスを当てるには自分で当たり判定を書く必要がある。",
   "useCase": "数十個までの図形でクリックやアクセシビリティが要るならSVG／DOM、数百〜数万個の粒子やゲーム的な描画で個別操作が不要ならCanvasを選ぶ、という判断基準として使う。",
   "code": "// 目安\n// 図形が少なく、個別にクリック・aria属性が要る → SVG / DOM\n// 図形が多い、ピクセル単位の自由な描画が要る    → Canvas\n// GPUで大量描画・シェーダー効果が要る           → WebGL / WebGPU",
   "tags": [
    "Canvas",
    "SVG",
    "DOM",
    "設計判断"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"Canvas・SVG・DOMの使い分けのデモ\"><style>.cvsd-mk{animation:cvsd-hi 4.5s steps(1) infinite}.cvsd-mk1{animation-delay:0s}.cvsd-mk2{animation-delay:1.5s}.cvsd-mk3{animation-delay:3s}@keyframes cvsd-hi{0%,25%{opacity:1}30%,100%{opacity:.3}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g><rect x=\"20\" y=\"34\" width=\"64\" height=\"82\" rx=\"8\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".14\"/><text x=\"52\" y=\"26\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8\" fill=\"var(--w-sub,#a7b4cd)\">DOM</text><rect class=\"cvsd-mk cvsd-mk1\" x=\"34\" y=\"60\" width=\"36\" height=\"26\" rx=\"4\" fill=\"var(--w-accent,#8fe3d0)\"/></g><g><rect x=\"88\" y=\"34\" width=\"64\" height=\"82\" rx=\"8\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".14\"/><text x=\"120\" y=\"26\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8\" fill=\"var(--w-sub,#a7b4cd)\">SVG</text><path class=\"cvsd-mk cvsd-mk2\" d=\"M104 90l16-32 16 32Z\" fill=\"var(--w-amber,#ffc857)\"/></g><g><rect x=\"156\" y=\"34\" width=\"64\" height=\"82\" rx=\"8\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".14\"/><text x=\"188\" y=\"26\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8\" fill=\"var(--w-sub,#a7b4cd)\">Canvas</text><g class=\"cvsd-mk cvsd-mk3\" fill=\"var(--w-ink,#e8eef9)\"><circle cx=\"168\" cy=\"60\" r=\"2\"/><circle cx=\"180\" cy=\"60\" r=\"2\"/><circle cx=\"192\" cy=\"60\" r=\"2\"/><circle cx=\"204\" cy=\"60\" r=\"2\"/><circle cx=\"168\" cy=\"70\" r=\"2\"/><circle cx=\"180\" cy=\"70\" r=\"2\"/><circle cx=\"192\" cy=\"70\" r=\"2\"/><circle cx=\"204\" cy=\"70\" r=\"2\"/><circle cx=\"168\" cy=\"80\" r=\"2\"/><circle cx=\"180\" cy=\"80\" r=\"2\"/><circle cx=\"192\" cy=\"80\" r=\"2\"/><circle cx=\"204\" cy=\"80\" r=\"2\"/><circle cx=\"168\" cy=\"90\" r=\"2\"/><circle cx=\"180\" cy=\"90\" r=\"2\"/><circle cx=\"192\" cy=\"90\" r=\"2\"/><circle cx=\"204\" cy=\"90\" r=\"2\"/></g></g></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "canvas-path2d",
    "canvas-ctx-filter",
    "svg-line-area-chart",
    "bar-chart-grid-vs-svg"
   ]
  },
  {
   "id": "css-registerproperty-js",
   "num": "W-269",
   "name": "CSS.registerProperty()",
   "nameJa": "JSから動的に登録するカスタムプロパティ",
   "category": "motion",
   "description": "既存項目の「@propertyでカスタムプロパティをアニメ」がCSSファイルに書く静的な at-rule なのに対し、CSS.registerProperty()はJavaScriptから同じ登録を行う関数版。実行時の条件分岐で型（syntax）を変えたい場合や、コンポーネントのJS側で完結させたい場合に選ぶ。型付きで登録した変数はブラウザが数値やcolorとして補間できるようになり、無登録のカスタムプロパティでは不可能だった滑らかなトランジションが効くようになる。",
   "useCase": "JSで動的生成するコンポーネント（Web Componentsなど）の内部で、CSS変数のアニメーションを保証したいときに@propertyの代わりに使う。",
   "code": "CSS.registerProperty({\n  name: '--angle',\n  syntax: '<angle>',\n  inherits: false,\n  initialValue: '0deg'\n});\nel.style.setProperty('--angle', '0deg');\nel.style.transition = '--angle 1s ease';\nrequestAnimationFrame(() => el.style.setProperty('--angle', '360deg'));\n/* CSS: background: conic-gradient(from var(--angle), #8fe3d0, #ffc857); */",
   "tags": [
    "CSS Houdini",
    "JavaScript",
    "カスタムプロパティ",
    "アニメーション"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"CSS.registerPropertyで角度を補間するデモ\"><style>.hrpj-ring{animation:hrpj-spin 4s linear infinite;transform-origin:120px 75px}@keyframes hrpj-spin{to{transform:rotate(360deg)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g class=\"hrpj-ring\"><circle cx=\"120\" cy=\"75\" r=\"38\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"10\" opacity=\".25\"/><circle cx=\"120\" cy=\"75\" r=\"38\" fill=\"none\" stroke=\"var(--w-accent,#8fe3d0)\" stroke-width=\"10\" stroke-dasharray=\"60 179\" stroke-linecap=\"round\"/><circle cx=\"120\" cy=\"37\" r=\"5\" fill=\"var(--w-amber,#ffc857)\"/></g><text x=\"120\" y=\"132\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">--angle: 0deg → 360deg</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "css-typed-om",
    "element-scoped-view-transition",
    "scroll-into-view-container",
    "houdini-layout-animation-worklet"
   ]
  },
  {
   "id": "offscreen-canvas-worker",
   "num": "W-270",
   "name": "OffscreenCanvas + Worker",
   "nameJa": "ワーカーへ逃がすOffscreenCanvas",
   "category": "interact",
   "description": "canvas.transferControlToOffscreen()でcanvasの描画権をWeb Worker（メインスレッドとは別のJSスレッド）へ譲渡し、重い描画計算をUIスレッドの外で行う仕組み。メインスレッドはクリックやスクロールの処理に専念できるため、大量パーティクルや複雑なシェーダー処理をしても操作のカクつきが起きにくい。",
   "useCase": "背景アニメが重くてスクロールやボタン操作が一瞬固まる、というときに描画をワーカーへ逃がして体感速度を守りたい場面で使う。",
   "code": "// main.js\nconst offscreen = canvas.transferControlToOffscreen();\nconst worker = new Worker('render.js');\nworker.postMessage({ canvas: offscreen }, [offscreen]);\n\n// render.js (worker)\nonmessage = (e) => {\n  const ctx = e.data.canvas.getContext('2d');\n  (function tick(){\n    ctx.clearRect(0,0,300,150);\n    requestAnimationFrame(tick);\n  })();\n};",
   "tags": [
    "Canvas",
    "Worker",
    "JavaScript",
    "パフォーマンス",
    "スムーズ"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"OffscreenCanvasでワーカーへ逃がすデモ\"><style>.cvosw-cursor{animation:cvosw-tap 4s ease-in-out infinite}.cvosw-spin{animation:cvosw-rot 3s linear infinite;transform-origin:178px 100px}@keyframes cvosw-tap{0%,100%{transform:translateY(0)}20%{transform:translateY(6px)}40%{transform:translateY(0)}}@keyframes cvosw-rot{to{transform:rotate(360deg)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"16\" y=\"20\" width=\"100\" height=\"110\" rx=\"8\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".12\"/><rect x=\"124\" y=\"20\" width=\"100\" height=\"110\" rx=\"8\" fill=\"var(--w-accent,#8fe3d0)\" opacity=\".12\"/><text x=\"66\" y=\"35\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8\" fill=\"var(--w-sub,#a7b4cd)\">main</text><text x=\"174\" y=\"35\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8\" fill=\"var(--w-accent,#8fe3d0)\">worker</text><g class=\"cvosw-cursor\"><circle cx=\"62\" cy=\"80\" r=\"8\" fill=\"var(--w-ink,#e8eef9)\"/></g><g class=\"cvosw-spin\"><rect x=\"168\" y=\"90\" width=\"20\" height=\"20\" rx=\"4\" fill=\"var(--w-accent,#8fe3d0)\"/></g><path d=\"M116 100h8\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"2\" marker-end=\"url(#cvosw-ar)\"/><defs><marker id=\"cvosw-ar\" markerWidth=\"6\" markerHeight=\"6\" refX=\"4\" refY=\"3\" orient=\"auto\"><path d=\"M0 0L5 3L0 6Z\" fill=\"var(--w-amber,#ffc857)\"/></marker></defs></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "css-typed-om",
    "canvas-ctx-filter",
    "canvas-getimagedata",
    "canvas-measuretext"
   ]
  },
  {
   "id": "css-typed-om",
   "num": "W-271",
   "name": "CSS Typed OM",
   "nameJa": "文字列を介さずCSS値を扱うTyped OM",
   "category": "interact",
   "description": "従来のel.style.width = '120px'のようなCSSOM操作は値が常に文字列で、毎回パースと単位変換のコストがかかっていた。CSS Typed OM（Typed Object Model）はel.attributeStyleMap.set('width', CSS.px(120))のように数値と単位を型付きオブジェクトとして扱い、加算・単位変換を文字列連結なしで行える。Firefoxの実装が一部インターフェースで未完成なため、現時点ではChromium系が主戦場。",
   "useCase": "canvasやWebGLと連携して毎フレームstyleを書き換えるような高頻度アニメーションで、文字列パースのオーバーヘッドを削りたいときに使う。",
   "code": "// 従来: 文字列の組み立てとパースが発生\nel.style.width = (el.style.width.replace('px','') * 1 + 10) + 'px';\n\n// Typed OM: 型付きの値を直接演算\nconst w = el.attributeStyleMap.get('width'); // CSSUnitValue\nel.attributeStyleMap.set('width', w.add(CSS.px(10)));",
   "tags": [
    "CSS Houdini",
    "Typed OM",
    "JavaScript",
    "パフォーマンス"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"CSS Typed OMのデモ\"><style>.htom-str{animation:htom-fade 4s ease-in-out infinite}.htom-obj{animation:htom-fade2 4s ease-in-out infinite}@keyframes htom-fade{0%,20%{opacity:1}45%,100%{opacity:.15}}@keyframes htom-fade2{0%,20%{opacity:.15}45%,100%{opacity:1}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g class=\"htom-str\"><rect x=\"30\" y=\"55\" width=\"80\" height=\"34\" rx=\"17\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".25\"/><text x=\"70\" y=\"76\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"11\" fill=\"var(--w-sub,#a7b4cd)\">\"120px\"</text></g><path d=\"M118 72h20\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"2\" marker-end=\"url(#htom-ar)\"/><defs><marker id=\"htom-ar\" markerWidth=\"6\" markerHeight=\"6\" refX=\"4\" refY=\"3\" orient=\"auto\"><path d=\"M0 0L5 3L0 6Z\" fill=\"var(--w-amber,#ffc857)\"/></marker></defs><g class=\"htom-obj\"><rect x=\"146\" y=\"52\" width=\"66\" height=\"40\" rx=\"8\" fill=\"var(--w-accent,#8fe3d0)\"/><text x=\"179\" y=\"70\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"10\" fill=\"var(--w-bg,#101830)\">120</text><text x=\"179\" y=\"84\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8\" fill=\"var(--w-bg,#101830)\">px</text></g></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "css-registerproperty-js",
    "offscreen-canvas-worker",
    "youtube-facade",
    "navigation-api"
   ]
  },
  {
   "id": "webgpu-status",
   "num": "W-272",
   "name": "WebGPU Status",
   "nameJa": "WebGPUの現状",
   "category": "depth",
   "description": "WebGPUはWebGLの後継として設計された低レベルGPU APIで、Direct3D 12・Metal・Vulkanなど現代のネイティブGPU APIに近い形でアクセスできる。描画だけでなく汎用計算（GPGPU）にも使え、navigator.gpu.requestAdapter()→requestDevice()という手順でGPUを取得する。2025年後半にChrome・Edge・Firefox・Safari全てで既定有効となり出そろったばかりの技術で、HTTPS必須（secure context限定）という制約もある。",
   "useCase": "WebGLでは重すぎる大量パーティクルや機械学習推論をブラウザ内で動かしたいとき。ただし対応が出そろってから日が浅いため、本番投入時はWebGLへのフォールバックを用意するのが安全。",
   "code": "if (!navigator.gpu) {\n  // WebGLなど代替手段にフォールバック\n} else {\n  const adapter = await navigator.gpu.requestAdapter();\n  const device = await adapter.requestDevice();\n  const ctx = canvas.getContext('webgpu');\n  ctx.configure({ device, format: navigator.gpu.getPreferredCanvasFormat() });\n}",
   "tags": [
    "WebGPU",
    "GPU",
    "GLSL",
    "先端"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"WebGPUの現状のデモ\"><style>.wgpu-b{animation:wgpu-on 4.8s steps(1) infinite}.wgpu-b1{animation-delay:0s}.wgpu-b2{animation-delay:.4s}.wgpu-b3{animation-delay:.8s}.wgpu-b4{animation-delay:1.2s}@keyframes wgpu-on{0%{fill:var(--w-sub,#a7b4cd);opacity:.3}8%,100%{fill:var(--w-accent,#8fe3d0);opacity:1}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g><g><rect class=\"wgpu-b wgpu-b1\" x=\"34\" y=\"55\" width=\"34\" height=\"34\" rx=\"7\" fill=\"var(--w-sub,#a7b4cd)\"/><text x=\"51\" y=\"104\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"7.5\" fill=\"var(--w-sub,#a7b4cd)\">Chrome</text></g><g><rect class=\"wgpu-b wgpu-b2\" x=\"80\" y=\"55\" width=\"34\" height=\"34\" rx=\"7\" fill=\"var(--w-sub,#a7b4cd)\"/><text x=\"97\" y=\"104\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"7.5\" fill=\"var(--w-sub,#a7b4cd)\">Edge</text></g><g><rect class=\"wgpu-b wgpu-b3\" x=\"126\" y=\"55\" width=\"34\" height=\"34\" rx=\"7\" fill=\"var(--w-sub,#a7b4cd)\"/><text x=\"143\" y=\"104\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"7.5\" fill=\"var(--w-sub,#a7b4cd)\">Firefox</text></g><g><rect class=\"wgpu-b wgpu-b4\" x=\"172\" y=\"55\" width=\"34\" height=\"34\" rx=\"7\" fill=\"var(--w-sub,#a7b4cd)\"/><text x=\"189\" y=\"104\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"7.5\" fill=\"var(--w-sub,#a7b4cd)\">Safari</text></g></g><text x=\"120\" y=\"130\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-amber,#ffc857)\">2025後半に既定有効が出そろい</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "webgl-fullscreen-shader",
    "ruby-overhang",
    "word-break-auto-phrase",
    "webgl-shader-noise-distortion"
   ]
  },
  {
   "id": "lightweight-3d-modelviewer",
   "num": "W-273",
   "name": "Lightweight 3D with <model-viewer>",
   "nameJa": "軽量3D表示（<model-viewer>）",
   "category": "depth",
   "description": "Googleが公開しているWeb Componentsライブラリで、<model-viewer src=\"model.glb\">と書くだけでglTF/GLBの3Dモデルを回転・ズーム操作つきで表示できる。内部ではThree.jsを使ってWebGLで描画し、camera-controlsやarで即AR表示にも対応する。フルスクラッチでthree.jsのシーン・カメラ・ライトを組むより、単発の商品ビューアなら圧倒的に少ないコードで済む。",
   "useCase": "ECサイトの商品を360度回転して見せたい、簡単な3Dビューアをフルスクラッチのthree.jsコードなしで埋め込みたいときに使う。",
   "code": "<!-- model-viewer（Web Components）を読み込み済みの前提 -->\n<model-viewer\n  src=\"chair.glb\"\n  camera-controls\n  auto-rotate\n  style=\"width:100%;height:320px\">\n</model-viewer>",
   "tags": [
    "Web Components",
    "3D",
    "glTF",
    "WebGL",
    "軽量"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"model-viewerでの軽量3D表示のデモ\"><style>.lw3d-cube{animation:lw3d-spin 5s linear infinite;transform-origin:120px 75px}@keyframes lw3d-spin{to{transform:rotateY(360deg)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g class=\"lw3d-cube\"><path d=\"M120 34L166 56L166 100L120 122L74 100L74 56Z\" fill=\"var(--w-accent,#8fe3d0)\" opacity=\".85\"/><path d=\"M120 34L166 56L120 78L74 56Z\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".5\"/><path d=\"M120 78L166 56L166 100L120 122Z\" fill=\"var(--w-amber,#ffc857)\" opacity=\".55\"/></g><text x=\"120\" y=\"140\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">&lt;model-viewer src=\"model.glb\"&gt;</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "custom-elements-define",
    "shadow-dom-style-isolation",
    "slot-content-projection",
    "declarative-shadow-dom"
   ]
  },
  {
   "id": "canvas-raf-loop",
   "num": "W-274",
   "name": "Canvas 2D Render Loop",
   "nameJa": "Canvasの描画ループ",
   "category": "background",
   "description": "canvasは1回描いたら終わりで、アニメさせるには「毎フレーム全部消して描き直す」のが基本形。requestAnimationFrame（略してrAF、ブラウザの描画タイミングに合わせて次フレームの処理を予約する仕組み）で自分自身を呼び直すループを作り、ループの先頭でclearRect（矩形範囲の塗りを消す命令）してから図形を描く。",
   "useCase": "パーティクルや波形などcanvasで動く背景・装飾を自作するときの土台になる。tabが非表示の間は自動で間引かれるため、CSSアニメより電力面で扱いやすい場合がある。",
   "code": "const c = document.querySelector('canvas');\nconst ctx = c.getContext('2d');\nlet x = 0;\nfunction tick(){\n  ctx.clearRect(0, 0, c.width, c.height);\n  x = (x + 2) % c.width;\n  ctx.beginPath();\n  ctx.arc(x, c.height/2, 10, 0, Math.PI*2);\n  ctx.fill();\n  requestAnimationFrame(tick);\n}\nrequestAnimationFrame(tick);",
   "tags": [
    "Canvas",
    "JavaScript",
    "requestAnimationFrame",
    "背景",
    "ループ"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"Canvasの描画ループのデモ\"><style>.cvraf-ball{animation:cvraf-move 4s linear infinite}.cvraf-arrow{animation:cvraf-spin 4s linear infinite;transform-origin:212px 30px}@keyframes cvraf-move{0%{transform:translateX(0)}100%{transform:translateX(176px)}}@keyframes cvraf-spin{to{transform:rotate(360deg)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"24\" y=\"26\" width=\"192\" height=\"98\" rx=\"6\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\" opacity=\".5\"/><g class=\"cvraf-arrow\" opacity=\".8\"><path d=\"M212 22a8 8 0 1 1 -6 3\" fill=\"none\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"2.4\" stroke-linecap=\"round\"/><path d=\"M204 23l2 6 6-2z\" fill=\"var(--w-amber,#ffc857)\"/></g><g class=\"cvraf-ball\"><circle cx=\"32\" cy=\"75\" r=\"11\" fill=\"var(--w-accent,#8fe3d0)\"/></g><text x=\"120\" y=\"140\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">clearRect → draw → rAF</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "particle-background",
    "canvas-ctx-filter",
    "canvas-dpr-scaling",
    "canvas-composite-blend"
   ]
  },
  {
   "id": "canvas-dpr-scaling",
   "num": "W-275",
   "name": "Canvas High-DPI Scaling",
   "nameJa": "Canvasの高解像度(DPR)対応",
   "category": "background",
   "description": "canvasはwidth/height属性で決めたピクセル数をそのままCSSサイズに引き伸ばすため、何もしないとRetinaディスプレイでにじむ。window.devicePixelRatio（1論理pxに対する実ピクセル数）の分だけ内部解像度を大きく確保し、ctx.scale()で座標系を元に戻すことで、見た目のサイズは変えずに描画だけを高精細にする。",
   "useCase": "ロゴ・アイコン・グラフなど輪郭の鮮明さが重要なcanvas描画を、高DPI端末でもにじませずに出したいときに使う。",
   "code": "const dpr = window.devicePixelRatio || 1;\nconst rect = canvas.getBoundingClientRect();\ncanvas.width = rect.width * dpr;\ncanvas.height = rect.height * dpr;\ncanvas.style.width = rect.width + 'px';\ncanvas.style.height = rect.height + 'px';\nctx.scale(dpr, dpr);",
   "tags": [
    "Canvas",
    "JavaScript",
    "devicePixelRatio",
    "高解像度",
    "くっきり"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"Canvasの高解像度対応のデモ\"><style>.cvdpr-fuzzy{animation:cvdpr-blur 4s ease-in-out infinite}@keyframes cvdpr-blur{0%,100%{opacity:.9}50%{opacity:.35}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><line x1=\"120\" y1=\"20\" x2=\"120\" y2=\"130\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1\" opacity=\".4\"/><g class=\"cvdpr-fuzzy\" filter=\"url(#cvdpr-b)\"><circle cx=\"62\" cy=\"75\" r=\"26\" fill=\"var(--w-sub,#a7b4cd)\"/></g><circle cx=\"178\" cy=\"75\" r=\"26\" fill=\"var(--w-accent,#8fe3d0)\"/><defs><filter id=\"cvdpr-b\" x=\"-60%\" y=\"-60%\" width=\"220%\" height=\"220%\"><feGaussianBlur stdDeviation=\"3.2\"/></filter></defs><text x=\"62\" y=\"118\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"9\" fill=\"var(--w-sub,#a7b4cd)\">1x</text><text x=\"178\" y=\"118\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"9\" fill=\"var(--w-accent,#8fe3d0)\">2x</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "canvas-ctx-filter",
    "canvas-raf-loop",
    "canvas-composite-blend",
    "canvas-getimagedata"
   ]
  },
  {
   "id": "canvas-composite-blend",
   "num": "W-276",
   "name": "Canvas globalCompositeOperation",
   "nameJa": "Canvasの合成モード（globalCompositeOperation）",
   "category": "background",
   "description": "新しく描く図形を、すでに描かれている内容とどう混ぜ合わせるかを指定するプロパティ。source-over（上書き、既定）のほかmultiply（乗算で暗く重ねる）やscreen（加算的に明るく重ねる）、destination-out（重なった部分をくり抜く）などがあり、CSSのmix-blend-modeと同じ語彙を共有する。",
   "useCase": "光の粒が重なるほど明るくなるパーティクル演出や、円をくり抜いてスポットライト状の穴を開ける表現をcanvas側だけで完結させたいときに使う。",
   "code": "ctx.fillStyle = '#8fe3d0';\nctx.beginPath(); ctx.arc(90, 75, 40, 0, Math.PI*2); ctx.fill();\n\nctx.globalCompositeOperation = 'screen';\nctx.fillStyle = '#ffc857';\nctx.beginPath(); ctx.arc(130, 75, 40, 0, Math.PI*2); ctx.fill();\nctx.globalCompositeOperation = 'source-over';",
   "tags": [
    "Canvas",
    "JavaScript",
    "合成",
    "ブレンド",
    "光"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"Canvasの合成モードのデモ\"><style>.cvcmp-b{animation:cvcmp-mv 4.5s ease-in-out infinite}@keyframes cvcmp-mv{0%,100%{transform:translateX(0)}50%{transform:translateX(-22px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><circle cx=\"102\" cy=\"75\" r=\"34\" fill=\"var(--w-accent,#8fe3d0)\" opacity=\".85\"/><g class=\"cvcmp-b\"><circle cx=\"150\" cy=\"75\" r=\"34\" fill=\"var(--w-amber,#ffc857)\" opacity=\".85\" style=\"mix-blend-mode:screen\"/></g><text x=\"120\" y=\"132\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">globalCompositeOperation = \"screen\"</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "canvas-ctx-filter",
    "canvas-raf-loop",
    "canvas-dpr-scaling",
    "canvas-getimagedata"
   ]
  },
  {
   "id": "canvas-ctx-filter",
   "num": "W-277",
   "name": "Canvas 2D Context Filter",
   "nameJa": "Canvasのフィルター効果（ctx.filter）",
   "category": "background",
   "description": "ctx.filterはCSSのfilterプロパティと同じ構文（blur()やdrop-shadow()、sepia()など）をcanvasの描画にそのまま適用できるプロパティ。図形を描く前に指定しておくと、以後の描画にフィルターがかかった状態で焼き込まれる。ただしSafariは長らく未実装で、2026年時点でも主要3エンジンのうち1つが対応していない状態が続く。",
   "useCase": "canvasで描いた図形やテキストにぼかしや影をその場でかけたいとき。Safariを含めて確実に効かせたい場合はCSS filterや自前のfeGaussianBlur合成に切り替える必要がある。",
   "code": "ctx.filter = 'blur(4px)';\nctx.fillStyle = '#8fe3d0';\nctx.fillRect(60, 40, 80, 60);\n\nctx.filter = 'none';\nctx.fillStyle = '#ffc857';\nctx.fillRect(160, 40, 40, 60);",
   "tags": [
    "Canvas",
    "JavaScript",
    "フィルター",
    "ぼかし"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"Canvasのフィルター効果のデモ\"><style>.cvflt-blur{animation:cvflt-tog 4s ease-in-out infinite}@keyframes cvflt-tog{0%,15%{filter:blur(0px)}45%,70%{filter:blur(3.5px)}100%{filter:blur(0px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect class=\"cvflt-blur\" x=\"46\" y=\"42\" width=\"80\" height=\"66\" rx=\"8\" fill=\"var(--w-accent,#8fe3d0)\"/><rect x=\"146\" y=\"42\" width=\"60\" height=\"66\" rx=\"8\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".5\"/><text x=\"86\" y=\"128\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8\" fill=\"var(--w-sub,#a7b4cd)\">Chrome/Firefox</text><text x=\"176\" y=\"128\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8\" fill=\"var(--w-sub,#a7b4cd)\">Safari 非対応</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "canvas-getimagedata",
    "canvas-raf-loop",
    "canvas-dpr-scaling",
    "canvas-composite-blend"
   ]
  },
  {
   "id": "webgl-fullscreen-shader",
   "num": "W-278",
   "name": "WebGL Fullscreen Shader Background",
   "nameJa": "フルスクリーンのシェーダー背景",
   "category": "background",
   "description": "画面いっぱいの四角形（三角形2枚）だけをジオメトリとして用意し、色や模様はすべてフラグメントシェーダー（画面の1ピクセルごとに実行される色計算プログラム）側で生成する手法。頂点シェーダーは座標をそのまま渡すだけの最小構成にし、時間経過を表すuniform（JS側からシェーダーへ渡す変数）を毎フレーム更新して模様を動かす。",
   "useCase": "パーティクルやDOM要素を1つも使わず、GPU計算だけで滑らかに変化するヒーローセクションの背景を作りたいときに使う。",
   "code": "// 頂点シェーダー：全画面を覆う1枚の三角形を渡すだけ\nattribute vec2 position;\nvoid main(){ gl_Position = vec4(position, 0.0, 1.0); }\n\n// フラグメントシェーダー：ピクセルごとに色を計算\nprecision mediump float;\nuniform vec2 uResolution;\nuniform float uTime;\nvoid main(){\n  vec2 uv = gl_FragCoord.xy / uResolution;\n  vec3 col = 0.5 + 0.5*cos(uTime + uv.xyx*6.0 + vec3(0,2,4));\n  gl_FragColor = vec4(col, 1.0);\n}",
   "tags": [
    "WebGL",
    "GLSL",
    "シェーダー",
    "背景",
    "GPU"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"フルスクリーンのシェーダー背景のデモ\"><defs><linearGradient id=\"wglbg-g\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\"><stop class=\"wglbg-s1\" offset=\"0%\" stop-color=\"var(--w-accent,#8fe3d0)\"/><stop class=\"wglbg-s2\" offset=\"50%\" stop-color=\"var(--w-amber,#ffc857)\"/><stop class=\"wglbg-s3\" offset=\"100%\" stop-color=\"var(--w-accent,#8fe3d0)\"/><animateTransform attributeName=\"gradientTransform\" type=\"rotate\" from=\"0 .5 .5\" to=\"360 .5 .5\" dur=\"6s\" repeatCount=\"indefinite\"/></linearGradient></defs><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"url(#wglbg-g)\"/><rect x=\"10\" y=\"10\" width=\"220\" height=\"130\" rx=\"6\" fill=\"none\" stroke=\"var(--w-bg,#101830)\" stroke-width=\"1\" opacity=\".25\"/><text x=\"120\" y=\"80\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"10\" fill=\"var(--w-bg,#101830)\" opacity=\".85\">gl_FragColor(uv, uTime)</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "webgl-shader-noise-distortion",
    "webgpu-status",
    "houdini-paint-worklet",
    "canvas-raf-loop"
   ]
  },
  {
   "id": "webgl-shader-noise-distortion",
   "num": "W-279",
   "name": "Shader Noise & Distortion",
   "nameJa": "シェーダーによるノイズ・歪み表現",
   "category": "background",
   "description": "フラグメントシェーダーの中でsin/cosを組み合わせた擬似ノイズ関数を書き、UV座標（0〜1に正規化したピクセル位置）自体を時間で揺らしてからテクスチャや色を参照すると、水面や熱ゆらぎのような歪みになる。CSSのfeTurbulenceがピクセル単位のノイズ画像を事前生成するのに対し、こちらは毎フレームGPUで数式から直接計算する点が違う。",
   "useCase": "流体風の背景や、画像・映像に熱ゆらぎ／グリッチ的な歪みを重ねたいときに使う。粒子数を増やしても負荷が一定なのが強み。",
   "code": "precision mediump float;\nuniform float uTime;\nuniform vec2 uResolution;\nvoid main(){\n  vec2 uv = gl_FragCoord.xy / uResolution;\n  uv.x += sin(uv.y * 10.0 + uTime) * 0.02;\n  uv.y += cos(uv.x * 10.0 + uTime) * 0.02;\n  float n = fract(sin(dot(uv, vec2(12.9898,78.233))) * 43758.5453);\n  gl_FragColor = vec4(vec3(n), 1.0);\n}",
   "tags": [
    "WebGL",
    "GLSL",
    "ノイズ",
    "歪み",
    "流体風"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"シェーダーによるノイズ・歪み表現のデモ\"><filter id=\"wgldn-f\" x=\"-20%\" y=\"-20%\" width=\"140%\" height=\"140%\"><feTurbulence type=\"fractalNoise\" baseFrequency=\"0.012 0.05\" numOctaves=\"2\" seed=\"4\" result=\"wgldn-n\"><animate attributeName=\"baseFrequency\" values=\"0.012 0.05;0.03 0.08;0.012 0.05\" dur=\"5s\" repeatCount=\"indefinite\"/></feTurbulence><feColorMatrix in=\"wgldn-n\" type=\"matrix\" values=\"0 0 0 0 0.56  0 0 0 0 0.89  0 0 0 0 0.82  0 0 0 1 0\"/></filter><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"0\" y=\"0\" width=\"240\" height=\"150\" rx=\"10\" filter=\"url(#wgldn-f)\" opacity=\".8\"/><text x=\"120\" y=\"138\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-ink,#e8eef9)\">uv += sin/cos(uTime)</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "webgl-fullscreen-shader",
    "webgpu-status",
    "lightweight-3d-modelviewer",
    "turbulence-wobble"
   ]
  },
  {
   "id": "houdini-paint-worklet",
   "num": "W-280",
   "name": "CSS Paint API (Paint Worklet)",
   "nameJa": "CSS Paint APIで背景を自前生成する",
   "category": "background",
   "description": "CSS Houdini（CSSのレンダリング過程をJSに開放する仕様群）の一部。JSでregisterPaint()を使い、canvasの2D描画命令にそっくりなAPIでbackground-image用の画像をその場で生成する。paint()関数として呼び出すとCSS変数の変化にも自動で追従し、通常のbackground-imageより動的な模様が作れる。Chromium系のみの実装で、FirefoxとSafariは未対応。",
   "useCase": "枠線や背景に、CSS変数で色を差し替えられる独自パターン（チェックや斜線など）を画像ファイルなしで持たせたいときに使う。非対応ブラウザ向けには通常の背景色をフォールバックとして必ず用意する。",
   "code": "// paint-worklet.js\nregisterPaint('stripes', class {\n  static get inputProperties(){ return ['--stripe-color']; }\n  paint(ctx, size, props){\n    const c = props.get('--stripe-color').toString();\n    ctx.fillStyle = c;\n    for (let x = 0; x < size.width; x += 16) {\n      ctx.fillRect(x, 0, 8, size.height);\n    }\n  }\n});\n// main.js\nCSS.paintWorklet.addModule('paint-worklet.js');\n/* CSS: background-image: paint(stripes); */",
   "tags": [
    "CSS Houdini",
    "Paint Worklet",
    "背景",
    "実験的"
   ],
   "support": "限定対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"CSS Paint APIで背景を生成するデモ\"><style>.hpwk-str{animation:hpwk-slide 4s linear infinite}@keyframes hpwk-slide{to{transform:translateX(32px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><clipPath id=\"hpwk-c\"><rect x=\"40\" y=\"35\" width=\"160\" height=\"80\" rx=\"8\"/></clipPath><g clip-path=\"url(#hpwk-c)\"><g class=\"hpwk-str\"><rect x=\"20\" y=\"35\" width=\"8\" height=\"80\" fill=\"var(--w-accent,#8fe3d0)\" opacity=\".7\"/><rect x=\"36\" y=\"35\" width=\"8\" height=\"80\" fill=\"var(--w-accent,#8fe3d0)\" opacity=\".7\"/><rect x=\"52\" y=\"35\" width=\"8\" height=\"80\" fill=\"var(--w-accent,#8fe3d0)\" opacity=\".7\"/><rect x=\"68\" y=\"35\" width=\"8\" height=\"80\" fill=\"var(--w-accent,#8fe3d0)\" opacity=\".7\"/><rect x=\"84\" y=\"35\" width=\"8\" height=\"80\" fill=\"var(--w-accent,#8fe3d0)\" opacity=\".7\"/><rect x=\"100\" y=\"35\" width=\"8\" height=\"80\" fill=\"var(--w-accent,#8fe3d0)\" opacity=\".7\"/><rect x=\"116\" y=\"35\" width=\"8\" height=\"80\" fill=\"var(--w-accent,#8fe3d0)\" opacity=\".7\"/><rect x=\"132\" y=\"35\" width=\"8\" height=\"80\" fill=\"var(--w-accent,#8fe3d0)\" opacity=\".7\"/><rect x=\"148\" y=\"35\" width=\"8\" height=\"80\" fill=\"var(--w-accent,#8fe3d0)\" opacity=\".7\"/><rect x=\"164\" y=\"35\" width=\"8\" height=\"80\" fill=\"var(--w-accent,#8fe3d0)\" opacity=\".7\"/><rect x=\"180\" y=\"35\" width=\"8\" height=\"80\" fill=\"var(--w-accent,#8fe3d0)\" opacity=\".7\"/><rect x=\"196\" y=\"35\" width=\"8\" height=\"80\" fill=\"var(--w-accent,#8fe3d0)\" opacity=\".7\"/><rect x=\"212\" y=\"35\" width=\"8\" height=\"80\" fill=\"var(--w-accent,#8fe3d0)\" opacity=\".7\"/><rect x=\"228\" y=\"35\" width=\"8\" height=\"80\" fill=\"var(--w-accent,#8fe3d0)\" opacity=\".7\"/></g></g><rect x=\"40\" y=\"35\" width=\"160\" height=\"80\" rx=\"8\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\" opacity=\".5\"/><text x=\"120\" y=\"130\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">background-image: paint(stripes)</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "houdini-layout-animation-worklet",
    "canvas-raf-loop",
    "webgl-fullscreen-shader",
    "css-registerproperty-js"
   ]
  },
  {
   "id": "svg-sparkline",
   "num": "W-281",
   "name": "Hand-Coded Sparkline",
   "nameJa": "座標を手計算するミニ折れ線グラフ",
   "category": "component",
   "description": "スパークラインは軸も目盛りも持たない、文中や表のセルに収まる極小の折れ線グラフ。データの配列を「x: 等間隔に割り振る」「y: 値を反転して高さに変換する」という2つの計算だけでpolylineやpath用の座標列に変換できれば、ライブラリなしで自作できる。線の下を塗ればエリアチャート風に、終点にだけ丸を置けば「現在値」を強調できる。",
   "useCase": "ダッシュボードの数値カードやテーブルの1行に、直近の推移をひと目で添えたいときに使う。",
   "code": "// values=[70,90,65,105,85,120,100] を x:20-220, y:40-115 に変換\nconst pts = values.map((v,i) => {\n  const x = 20 + i * (200 / (values.length - 1));\n  const y = 115 - (v - min) / (max - min) * 75;\n  return `${x},${y}`;\n}).join(' ');\n// <polyline points={pts} fill=\"none\" stroke=\"teal\"/>",
   "tags": [
    "SVG",
    "スパークライン",
    "データ可視化",
    "ダッシュボード",
    "座標計算"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"座標計算だけで描くスパークラインのデモ\"><style>.sspk-line{stroke-dasharray:100;animation:sspk-draw 3s ease-in-out infinite}@keyframes sspk-draw{0%,100%{stroke-dashoffset:55}50%{stroke-dashoffset:0}}.sspk-dot{animation:sspk-pulse 2s ease-in-out infinite;transform-origin:220px 60px}@keyframes sspk-pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.35)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><path d=\"M20,90 L53,70 L87,95 L120,55 L153,75 L187,40 L220,60 L220,122 L20,122 Z\" fill=\"var(--w-accent,#5ad2d9)\" opacity=\".16\"/><path class=\"sspk-line\" pathLength=\"100\" d=\"M20,90 L53,70 L87,95 L120,55 L153,75 L187,40 L220,60\" fill=\"none\" stroke=\"var(--w-accent,#5ad2d9)\" stroke-width=\"3\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><circle class=\"sspk-dot\" cx=\"220\" cy=\"60\" r=\"5\" fill=\"var(--w-amber,#ffc857)\"/><text x=\"20\" y=\"136\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">直近7日間</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "svg-line-area-chart",
    "bar-chart-grid-vs-svg",
    "svg-gauge-meter",
    "circular-progress"
   ]
  },
  {
   "id": "custom-elements-define",
   "num": "W-282",
   "name": "customElements.define()",
   "nameJa": "独自タグを定義するcustomElements.define",
   "category": "component",
   "description": "HTMLElementを継承したクラスを書き、customElements.define('my-button', MyButton)のように登録すると、<my-button>という自作のHTMLタグがそのまま使えるようになる。connectedCallback（DOMに挿入された瞬間に呼ばれる）やattributeChangedCallback（監視対象の属性が変わった瞬間に呼ばれる）などのライフサイクルフックを使い、フレームワークなしで再利用可能な部品を作れる。",
   "useCase": "React/Vueなど特定フレームワークに縛られず、複数のプロジェクトやCMSへそのまま貼り付けて使えるUI部品（バッジ、カウントダウン、タブ等）を作りたいときに使う。",
   "code": "class HelloBadge extends HTMLElement {\n  connectedCallback(){\n    this.textContent = 'Hello, ' + (this.getAttribute('name') || 'world');\n  }\n}\ncustomElements.define('hello-badge', HelloBadge);\n// HTML: <hello-badge name=\"Waza\"></hello-badge>",
   "tags": [
    "Web Components",
    "JavaScript",
    "カスタム要素",
    "部品化"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"customElements.defineで独自タグを定義するデモ\"><style>.wcdef-tag{animation:wcdef-move 4s ease-in-out infinite}@keyframes wcdef-move{0%,20%{transform:translateX(0)}50%,80%{transform:translateX(90px)}100%{transform:translateX(0)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"24\" y=\"56\" width=\"70\" height=\"38\" rx=\"6\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\" stroke-dasharray=\"3 3\"/><text x=\"59\" y=\"79\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"9\" fill=\"var(--w-sub,#a7b4cd)\">class</text><g class=\"wcdef-tag\"><rect x=\"24\" y=\"56\" width=\"70\" height=\"38\" rx=\"19\" fill=\"var(--w-accent,#8fe3d0)\"/><text x=\"59\" y=\"80\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"10\" fill=\"var(--w-bg,#101830)\">&lt;my-tag&gt;</text></g><text x=\"120\" y=\"130\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8.5\" fill=\"var(--w-sub,#a7b4cd)\">customElements.define()</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "shadow-dom-style-isolation",
    "slot-content-projection",
    "declarative-shadow-dom",
    "adopted-stylesheets"
   ]
  },
  {
   "id": "shadow-dom-style-isolation",
   "num": "W-283",
   "name": "Shadow DOM Style Isolation",
   "nameJa": "Shadow DOMによるスタイルの隔離",
   "category": "component",
   "description": "element.attachShadow({mode:'open'})で作るshadow root（要素にぶら下がる独立したミニDOMツリー）の中に書いたCSSは外のページに漏れず、逆にページ側の汎用セレクタ（div{...}など）もshadow rootの中には届かない。mode: 'open'はJSのshadowRootプロパティから中身を覗けるが、'closed'にすると外部から一切参照できなくなる。",
   "useCase": "配布用ウィジェットや埋め込みスクリプトなど、設置先サイトの既存CSSと衝突させたくない部品を作るときに使う。",
   "code": "const host = document.createElement('div');\nconst root = host.attachShadow({ mode: 'open' });\nroot.innerHTML = `\n  <style>p { color: hotpink; }</style>\n  <p>ページ側のCSSの影響を受けない</p>\n`;\ndocument.body.appendChild(host);",
   "tags": [
    "Web Components",
    "Shadow DOM",
    "スタイル隔離",
    "コンポーネント"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"Shadow DOMでスタイルを隔離するデモ\"><style>.wcsdi-leak{animation:wcsdi-try 4.5s ease-in-out infinite}@keyframes wcsdi-try{0%,20%{transform:translateX(0);opacity:1}40%{transform:translateX(18px);opacity:.3}60%{transform:translateX(0);opacity:1}100%{transform:translateX(0);opacity:1}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"18\" y=\"24\" width=\"204\" height=\"100\" rx=\"8\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.2\" opacity=\".4\"/><text x=\"30\" y=\"40\" font-family=\"ui-monospace,monospace\" font-size=\"8\" fill=\"var(--w-sub,#a7b4cd)\">page CSS: p { color: red }</text><rect x=\"128\" y=\"52\" width=\"82\" height=\"56\" rx=\"8\" fill=\"var(--w-accent,#8fe3d0)\" opacity=\".14\" stroke=\"var(--w-accent,#8fe3d0)\" stroke-dasharray=\"4 3\"/><text x=\"169\" y=\"66\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"7.5\" fill=\"var(--w-accent,#8fe3d0)\">#shadow-root</text><circle class=\"wcsdi-leak\" cx=\"118\" cy=\"82\" r=\"5\" fill=\"var(--w-amber,#ffc857)\"/><text x=\"169\" y=\"94\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"9\" fill=\"var(--w-ink,#e8eef9)\">p</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "slot-content-projection",
    "declarative-shadow-dom",
    "adopted-stylesheets",
    "host-part-slotted-styling"
   ]
  },
  {
   "id": "slot-content-projection",
   "num": "W-284",
   "name": "<slot> Content Projection",
   "nameJa": "<slot>で外側のHTMLを差し込む",
   "category": "component",
   "description": "shadow root内に<slot></slot>を置いておくと、その場所にカスタム要素タグの内側（light DOMと呼ばれる、利用者が書いたHTML）がそのまま差し込まれる。name属性を付けた名前付きslotを使えば、見出し用・本文用のように複数箇所へ振り分けて配置することもできる。",
   "useCase": "見た目の骨組みはコンポーネント側で固定しつつ、中身のテキストや画像だけ使う側に自由に書かせたいカードやモーダルを作るときに使う。",
   "code": "// shadow root側\nroot.innerHTML = `\n  <div class=\"card\">\n    <slot name=\"title\"></slot>\n    <slot></slot>\n  </div>`;\n\n// 呼び出し側HTML\n// <my-card>\n//   <h3 slot=\"title\">見出し</h3>\n//   <p>ここが既定のslotに入る本文</p>\n// </my-card>",
   "tags": [
    "Web Components",
    "Shadow DOM",
    "slot",
    "コンポーネント"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"slotで外側のHTMLを差し込むデモ\"><style>.wcslt-c{animation:wcslt-in 4s ease-in-out infinite}@keyframes wcslt-in{0%,15%{transform:translateX(-58px);opacity:0}45%,80%{transform:translateX(0);opacity:1}100%{transform:translateX(-58px);opacity:0}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"24\" y=\"30\" width=\"46\" height=\"90\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".18\"/><text x=\"47\" y=\"80\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8\" fill=\"var(--w-sub,#a7b4cd)\">light DOM</text><rect x=\"104\" y=\"30\" width=\"112\" height=\"90\" rx=\"8\" fill=\"none\" stroke=\"var(--w-accent,#8fe3d0)\" stroke-width=\"1.5\" stroke-dasharray=\"4 3\"/><rect x=\"118\" y=\"42\" width=\"84\" height=\"18\" rx=\"4\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".2\"/><g class=\"wcslt-c\"><rect x=\"118\" y=\"68\" width=\"84\" height=\"34\" rx=\"6\" fill=\"var(--w-amber,#ffc857)\"/></g><text x=\"160\" y=\"122\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8\" fill=\"var(--w-accent,#8fe3d0)\">&lt;slot&gt;</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "shadow-dom-style-isolation",
    "declarative-shadow-dom",
    "adopted-stylesheets",
    "host-part-slotted-styling"
   ]
  },
  {
   "id": "declarative-shadow-dom",
   "num": "W-285",
   "name": "Declarative Shadow DOM",
   "nameJa": "宣言的Shadow DOM（サーバーサイド対応）",
   "category": "component",
   "description": "従来のShadow DOMはattachShadow()というJS呼び出しが必須で、JSが読み込まれるまで中身が表示されなかった。<template shadowrootmode=\"open\">を要素の子として書いておくと、HTMLパーサーがその場でshadow rootへ変換するため、JS実行前でもサーバーから届いたHTMLだけでコンポーネントの中身が表示される。2024年8月に主要3エンジンで足並みが揃ったばかりの比較的新しい機能。",
   "useCase": "Web ComponentsをSSR（サーバーサイドレンダリング）したいときや、JSが遅延読み込みされる環境でもレイアウトのガタつき（レイアウトシフト）なくコンポーネントを初期表示したいときに使う。",
   "code": "<div id=\"host\">\n  <template shadowrootmode=\"open\">\n    <style>p { color: var(--w-accent); }</style>\n    <p>JS実行前からこの中身が見えている</p>\n  </template>\n</div>",
   "tags": [
    "Web Components",
    "Shadow DOM",
    "SSR",
    "宣言的"
   ],
   "support": "新しく普及中",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"宣言的Shadow DOMのデモ\"><style>.wcdsd-js{animation:wcdsd-cross 4s steps(1) infinite}@keyframes wcdsd-cross{0%,40%{opacity:1}45%,100%{opacity:.25}}.wcdsd-html{animation:wcdsd-ok 4s ease-in-out infinite}@keyframes wcdsd-ok{0%,40%{opacity:.35}50%,100%{opacity:1}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"24\" y=\"50\" width=\"70\" height=\"42\" rx=\"8\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".18\"/><text x=\"59\" y=\"75\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">HTML</text><g class=\"wcdsd-js\"><path d=\"M104 55L146 87M146 55L104 87\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"3\" stroke-linecap=\"round\"/><text x=\"125\" y=\"104\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8\" fill=\"var(--w-amber,#ffc857)\">JS不要</text></g><g class=\"wcdsd-html\"><rect x=\"156\" y=\"50\" width=\"66\" height=\"42\" rx=\"8\" fill=\"var(--w-accent,#8fe3d0)\"/><text x=\"189\" y=\"75\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"9\" fill=\"var(--w-bg,#101830)\">render</text></g></svg>",
   "useFor": [
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "shadow-dom-style-isolation",
    "slot-content-projection",
    "adopted-stylesheets",
    "host-part-slotted-styling"
   ]
  },
  {
   "id": "host-part-slotted-styling",
   "num": "W-286",
   "name": ":host / ::part / ::slotted",
   "nameJa": ":host・::part・::slottedでの外側からのスタイリング",
   "category": "component",
   "description": "Shadow DOMの中と外を橋渡しする3つのセレクタ。:hostはshadow rootを持つ要素自身をshadow root内から指す。::part(name)はshadow root内でpart属性を付けた要素を、外側のCSSから直接狙って上書きできる公式な抜け穴。::slotted(selector)は<slot>に差し込まれたlight DOM側の要素を、shadow root内のCSSから選べるようにする。",
   "useCase": "配布コンポーネントの見た目を丸ごとカプセル化しつつ、利用者に「ここだけは自由に色を変えていい」という調整余地を安全に用意したいときに使う。",
   "code": "/* shadow root内のCSS */\n:host { display: inline-block; }\n::slotted(strong) { color: var(--w-amber); }\n\n/* ページ側のCSS */\nmy-widget::part(button) { border-radius: 999px; }\n/* shadow内: <button part=\"button\">...</button> */",
   "tags": [
    "Web Components",
    "Shadow DOM",
    "CSS",
    ":host",
    "::part"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\":host ::part ::slottedのデモ\"><style>.wchps-a{animation:wchps-cyc 4.5s steps(1) infinite}.wchps-b{animation:wchps-cyc 4.5s steps(1) infinite;animation-delay:1.5s}.wchps-c{animation:wchps-cyc 4.5s steps(1) infinite;animation-delay:3s}@keyframes wchps-cyc{0%,28%{stroke-width:5}30%,100%{stroke-width:1.5}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect class=\"wchps-a\" x=\"30\" y=\"40\" width=\"180\" height=\"80\" rx=\"12\" fill=\"none\" stroke=\"var(--w-accent,#8fe3d0)\"/><rect class=\"wchps-b\" x=\"54\" y=\"58\" width=\"72\" height=\"30\" rx=\"15\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".3\" stroke=\"var(--w-amber,#ffc857)\"/><text x=\"90\" y=\"78\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8\" fill=\"var(--w-ink,#e8eef9)\">::part</text><text class=\"wchps-c\" x=\"164\" y=\"78\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"9\" fill=\"var(--w-amber,#ffc857)\" stroke=\"var(--w-amber,#ffc857)\">::slotted</text><text x=\"120\" y=\"132\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8\" fill=\"var(--w-sub,#a7b4cd)\">:host / ::part / ::slotted</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "shadow-dom-style-isolation",
    "slot-content-projection",
    "declarative-shadow-dom",
    "adopted-stylesheets"
   ]
  },
  {
   "id": "adopted-stylesheets",
   "num": "W-287",
   "name": "adoptedStyleSheets",
   "nameJa": "スタイルシートを使い回すadoptedStyleSheets",
   "category": "component",
   "description": "new CSSStyleSheet()で作った「構築済みスタイルシート」は、document.adoptedStyleSheetsやshadowRoot.adoptedStyleSheetsへ配列として渡すだけで複数のドキュメント・複数のshadow rootに同時採用できる。1枚のシートをsheet.replaceSync()で書き換えると、それを採用している全箇所へ即座に反映されるため、Web Componentsを大量に並べても<style>タグを複製せずに済む。",
   "useCase": "同じデザインのカードやボタンをshadow DOMで何十個も並べるとき、共通CSSをコンポーネントごとに複製せず1枚のシートとして共有したい場面で使う。",
   "code": "const sheet = new CSSStyleSheet();\nsheet.replaceSync('.card{border-radius:12px;padding:1rem}');\n\ndocument.adoptedStyleSheets = [sheet];\nshadowRootA.adoptedStyleSheets = [sheet];\nshadowRootB.adoptedStyleSheets = [sheet];\n// sheetを書き換えると採用中の全箇所に反映される",
   "tags": [
    "Web Components",
    "Shadow DOM",
    "CSSStyleSheet",
    "共有"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"adoptedStyleSheetsで共有するデモ\"><style>.wcads-l{stroke-dasharray:6 4;animation:wcads-flow 3s linear infinite}@keyframes wcads-flow{to{stroke-dashoffset:-20}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"98\" y=\"20\" width=\"44\" height=\"30\" rx=\"6\" fill=\"var(--w-amber,#ffc857)\"/><text x=\"120\" y=\"40\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8\" fill=\"var(--w-bg,#101830)\">sheet</text><g stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.6\" fill=\"none\"><path class=\"wcads-l\" d=\"M110 50L44 92\"/><path class=\"wcads-l\" d=\"M120 50L120 92\"/><path class=\"wcads-l\" d=\"M130 50L196 92\"/></g><g fill=\"var(--w-accent,#8fe3d0)\" opacity=\".9\"><rect x=\"24\" y=\"92\" width=\"40\" height=\"28\" rx=\"6\"/><rect x=\"100\" y=\"92\" width=\"40\" height=\"28\" rx=\"6\"/><rect x=\"176\" y=\"92\" width=\"40\" height=\"28\" rx=\"6\"/></g></svg>",
   "useFor": [
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "shadow-dom-style-isolation",
    "slot-content-projection",
    "declarative-shadow-dom",
    "host-part-slotted-styling"
   ]
  },
  {
   "id": "form-associated-custom-elements",
   "num": "W-288",
   "name": "Form-Associated Custom Elements",
   "nameJa": "フォーム対応カスタム要素（ElementInternals）",
   "category": "component",
   "description": "静的プロパティstatic formAssociated = trueを宣言し、コンストラクタでthis.attachInternals()を呼ぶと、自作のカスタム要素がElementInternalsという道具箱を得る。internals.setFormValue()で送信値を登録できるので、<my-rating>のような独自UIでも囲んでいる<form>のFormData・required検証・reset操作に標準の<input>と同じように参加できる。",
   "useCase": "星評価やトグルスイッチなど見た目は完全に独自だが、既存のフォーム送信・バリデーションの仕組みにそのまま乗せたいコンポーネントを作るときに使う。",
   "code": "class RatingInput extends HTMLElement {\n  static formAssociated = true;\n  constructor(){\n    super();\n    this.internals = this.attachInternals();\n  }\n  setValue(v){\n    this.internals.setFormValue(String(v));\n  }\n}\ncustomElements.define('rating-input', RatingInput);",
   "tags": [
    "Web Components",
    "ElementInternals",
    "フォーム",
    "アクセシビリティ"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"フォーム対応カスタム要素のデモ\"><style>.wcfac-chk{animation:wcfac-pop 4s ease-in-out infinite}@keyframes wcfac-pop{0%,25%{stroke-dashoffset:24}45%,100%{stroke-dashoffset:0}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"26\" y=\"34\" width=\"86\" height=\"82\" rx=\"8\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\" stroke-dasharray=\"4 3\"/><text x=\"69\" y=\"26\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8\" fill=\"var(--w-sub,#a7b4cd)\">&lt;form&gt;</text><g fill=\"var(--w-amber,#ffc857)\"><circle cx=\"46\" cy=\"70\" r=\"6\"/><circle cx=\"66\" cy=\"70\" r=\"6\" opacity=\".4\"/><circle cx=\"86\" cy=\"70\" r=\"6\" opacity=\".4\"/></g><text x=\"69\" y=\"100\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8\" fill=\"var(--w-sub,#a7b4cd)\">rating-input</text><path d=\"M132 75h30\" stroke=\"var(--w-accent,#8fe3d0)\" stroke-width=\"2\" marker-end=\"url(#wcfac-ar)\"/><defs><marker id=\"wcfac-ar\" markerWidth=\"6\" markerHeight=\"6\" refX=\"4\" refY=\"3\" orient=\"auto\"><path d=\"M0 0L5 3L0 6Z\" fill=\"var(--w-accent,#8fe3d0)\"/></marker></defs><circle cx=\"196\" cy=\"75\" r=\"20\" fill=\"none\" stroke=\"var(--w-accent,#8fe3d0)\" stroke-width=\"3\"/><path class=\"wcfac-chk\" d=\"M187 75l7 7 13-15\" fill=\"none\" stroke=\"var(--w-accent,#8fe3d0)\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-dasharray=\"24\" /></svg>",
   "useFor": [
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "customizable-select",
    "custom-elements-define",
    "shadow-dom-style-isolation",
    "slot-content-projection"
   ]
  },
  {
   "id": "svg-line-area-chart",
   "num": "W-289",
   "name": "Line & Area Chart Coordinate Scale",
   "nameJa": "折れ線・面グラフの座標変換",
   "category": "component",
   "description": "数値の配列を、決まった描画範囲(x:20〜220、y:130〜30など)のピクセル座標に変換して折れ線・面グラフを描く方法。yは(値-最小値)/(最大値-最小値)で0〜1に正規化してから描画範囲の高さを掛け、原点を引く。折れ線の座標に加えて底辺(ベースライン)へ戻る2点を足せば、同じ点列から塗り面のパスも作れる。軸なしの極小折れ線(スパークライン)と違い、こちらはベースラインと面塗りを含む「一枚のグラフ」として仕上げる技法。",
   "useCase": "売上推移やアクセス数の週次・月次グラフなど、軸や塗り面まで含めた通常サイズの折れ線・面グラフをSVGだけで描きたいときに使う。",
   "code": "function scaleY(v, min, max, top = 30, bottom = 130) {\n  return bottom - ((v - min) / (max - min)) * (bottom - top);\n}\nconst values = [40, 65, 50, 80, 60, 95, 75];\nconst xs = values.map((_, i) => 20 + i * (200 / (values.length - 1)));\nconst ys = values.map((v) => scaleY(v, Math.min(...values), Math.max(...values)));\n// 面グラフはこの点列 + [xs.at(-1),130] + [xs[0],130] を Z で閉じるだけ",
   "tags": [
    "データ可視化",
    "グラフ",
    "SVG",
    "スケール変換"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"値を座標に変換する折れ線・面グラフのデモ\"><style>.slac-area{animation:slac-fade 4s ease-in-out infinite}@keyframes slac-fade{0%,100%{opacity:.5}50%{opacity:.28}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><defs><linearGradient id=\"slac-grad\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0%\" stop-color=\"var(--w-accent,#5ad2d9)\" stop-opacity=\".6\"/><stop offset=\"100%\" stop-color=\"var(--w-accent,#5ad2d9)\" stop-opacity=\"0\"/></linearGradient></defs><line x1=\"20\" y1=\"130\" x2=\"220\" y2=\"130\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\"/><path class=\"slac-area\" d=\"M20.0,130.0 L53.3,84.5 L86.7,111.8 L120.0,57.3 L153.3,93.6 L186.7,30.0 L220.0,66.4 L220.0,130 L20.0,130 Z\" fill=\"url(#slac-grad)\" stroke=\"none\"/><polyline points=\"20.0,130.0 53.3,84.5 86.7,111.8 120.0,57.3 153.3,93.6 186.7,30.0 220.0,66.4\" fill=\"none\" stroke=\"var(--w-accent,#5ad2d9)\" stroke-width=\"2.5\" stroke-linejoin=\"round\"/><circle cx=\"20.0\" cy=\"130.0\" r=\"2.5\" fill=\"var(--w-accent,#5ad2d9)\"/><circle cx=\"53.3\" cy=\"84.5\" r=\"2.5\" fill=\"var(--w-accent,#5ad2d9)\"/><circle cx=\"86.7\" cy=\"111.8\" r=\"2.5\" fill=\"var(--w-accent,#5ad2d9)\"/><circle cx=\"120.0\" cy=\"57.3\" r=\"2.5\" fill=\"var(--w-accent,#5ad2d9)\"/><circle cx=\"153.3\" cy=\"93.6\" r=\"2.5\" fill=\"var(--w-accent,#5ad2d9)\"/><circle cx=\"186.7\" cy=\"30.0\" r=\"2.5\" fill=\"var(--w-accent,#5ad2d9)\"/><circle cx=\"220.0\" cy=\"66.4\" r=\"2.5\" fill=\"var(--w-accent,#5ad2d9)\"/></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "bar-chart-grid-vs-svg",
    "svg-radar-chart",
    "svg-gauge-meter",
    "chart-legend-layout"
   ]
  },
  {
   "id": "bar-chart-grid-vs-svg",
   "num": "W-290",
   "name": "Bar Chart: CSS Grid vs SVG",
   "nameJa": "棒グラフ：CSS GridとSVGの使い分け",
   "category": "component",
   "description": "棒グラフはCSS Gridでも素のSVGでも作れるが向き不向きが違う。CSS Gridは1本ずつ<div>にして各バーの高さをカスタムプロパティ経由のcalc()やgrid-template-rowsのfr値で決める方法で、HTML表としての意味構造やホバー・フォーカスなどのDOMインタラクションを保ったまま作れる。SVGはrectのyとheightを値からのスケール計算で直接指定する方法で、軸線や複雑な装飾、印刷・書き出しを含む1枚絵として扱いたい場合に向く。同じ見た目でも実装の選び方で得意分野が変わる。",
   "useCase": "アクセシブルな表データの延長として棒グラフを組み込みたいならCSS Grid、スライドや画像として書き出す固定レイアウトの資料に組み込むならSVG、という判断基準が欲しいときに使う。",
   "code": "/* CSS Grid版: 1バー=1トラック、高さはfrで比率指定 */\n.bars{display:grid;grid-template-columns:repeat(5,1fr);align-items:end;gap:5px;height:70px}\n.bars>div{background:var(--accent);border-radius:2px}\n.bars>div:nth-child(1){height:calc(3/9*100%)}\n.bars>div:nth-child(4){height:calc(9/9*100%)}\n\n// SVG版: 値をそのままy/heightへスケール変換\nconst h = (v / max) * 70;\n// <rect x={x} y={125 - h} width=\"12\" height={h}/>",
   "tags": [
    "データ可視化",
    "グラフ",
    "CSS Grid",
    "SVG"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"CSS GridとSVG、2通りで作る棒グラフのデモ\"><style>.bcgv-bar{animation:bcgv-breathe 3.6s ease-in-out infinite}@keyframes bcgv-breathe{0%,100%{transform:scaleY(1)}50%{transform:scaleY(.9)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><line x1=\"20\" y1=\"125\" x2=\"105\" y2=\"125\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\"/><line x1=\"135\" y1=\"125\" x2=\"220\" y2=\"125\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\"/><rect class=\"bcgv-bar\" style=\"animation-delay:0s\" x=\"20\" y=\"101.7\" width=\"12\" height=\"23.3\" rx=\"2\" fill=\"var(--w-accent,#5ad2d9)\" transform-origin=\"26 125\"/><rect class=\"bcgv-bar\" style=\"animation-delay:0.15s\" x=\"37\" y=\"70.6\" width=\"12\" height=\"54.4\" rx=\"2\" fill=\"var(--w-accent,#5ad2d9)\" transform-origin=\"43 125\"/><rect class=\"bcgv-bar\" style=\"animation-delay:0.3s\" x=\"54\" y=\"86.1\" width=\"12\" height=\"38.9\" rx=\"2\" fill=\"var(--w-accent,#5ad2d9)\" transform-origin=\"60 125\"/><rect class=\"bcgv-bar\" style=\"animation-delay:0.44999999999999996s\" x=\"71\" y=\"55.0\" width=\"12\" height=\"70.0\" rx=\"2\" fill=\"var(--w-accent,#5ad2d9)\" transform-origin=\"77 125\"/><rect class=\"bcgv-bar\" style=\"animation-delay:0.6s\" x=\"88\" y=\"93.9\" width=\"12\" height=\"31.1\" rx=\"2\" fill=\"var(--w-accent,#5ad2d9)\" transform-origin=\"94 125\"/><rect class=\"bcgv-bar\" style=\"animation-delay:0s\" x=\"135\" y=\"101.7\" width=\"12\" height=\"23.3\" rx=\"2\" fill=\"var(--w-accent,#5ad2d9)\" transform-origin=\"141 125\"/><rect class=\"bcgv-bar\" style=\"animation-delay:0.15s\" x=\"152\" y=\"70.6\" width=\"12\" height=\"54.4\" rx=\"2\" fill=\"var(--w-accent,#5ad2d9)\" transform-origin=\"158 125\"/><rect class=\"bcgv-bar\" style=\"animation-delay:0.3s\" x=\"169\" y=\"86.1\" width=\"12\" height=\"38.9\" rx=\"2\" fill=\"var(--w-accent,#5ad2d9)\" transform-origin=\"175 125\"/><rect class=\"bcgv-bar\" style=\"animation-delay:0.44999999999999996s\" x=\"186\" y=\"55.0\" width=\"12\" height=\"70.0\" rx=\"2\" fill=\"var(--w-accent,#5ad2d9)\" transform-origin=\"192 125\"/><rect class=\"bcgv-bar\" style=\"animation-delay:0.6s\" x=\"203\" y=\"93.9\" width=\"12\" height=\"31.1\" rx=\"2\" fill=\"var(--w-accent,#5ad2d9)\" transform-origin=\"209 125\"/><text x=\"62\" y=\"142\" text-anchor=\"middle\" font-size=\"9\" fill=\"var(--w-sub,#a7b4cd)\">CSS Grid</text><text x=\"177\" y=\"142\" text-anchor=\"middle\" font-size=\"9\" fill=\"var(--w-sub,#a7b4cd)\">SVG</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "svg-line-area-chart",
    "svg-radar-chart",
    "svg-gauge-meter",
    "css-grid-heatmap"
   ]
  },
  {
   "id": "svg-radar-chart",
   "num": "W-291",
   "name": "Radar / Spider Chart",
   "nameJa": "レーダーチャート（極座標の多角形）",
   "category": "component",
   "description": "評価項目の数だけ中心から軸を放射状に伸ばし、各軸上に値に応じた点を打って多角形として結ぶグラフ。i番目の軸の角度をangle=-90°+i・360°/Nで求め、値vを半径r=(v/最大値)・Rに変換してx=cx+r・cos(angle)、y=cy+r・sin(angle)で座標を出す。放射配置(極座標→直交座標)と同じ数式を「ノードの位置」ではなく「評価値の大きさ」に転用したもの。",
   "useCase": "複数項目のスコアを1対象で見せる自己評価シート、複数対象を重ねて比較する製品比較表など、多軸の評価を面積の形として直感的に見せたいときに使う。",
   "code": "function radarPoint(i, n, value, max, cx = 120, cy = 78, r = 55) {\n  const angle = -Math.PI / 2 + i * ((2 * Math.PI) / n);\n  const rr = (value / max) * r;\n  return [cx + rr * Math.cos(angle), cy + rr * Math.sin(angle)];\n}\n// values=[8,6,9,5,7], max=10 の5軸なら\n// radarPoint(0,5,8,10) -> [120, 34]",
   "tags": [
    "データ可視化",
    "グラフ",
    "レーダーチャート",
    "極座標"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"極座標で多角形を作るレーダーチャートのデモ\"><style>.srdc-poly{animation:srdc-pulse 4s ease-in-out infinite;transform-origin:120px 78px}@keyframes srdc-pulse{0%,100%{transform:scale(1)}50%{transform:scale(.96)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><polygon points=\"120,23 172.3,61 152.3,122.5 87.7,122.5 67.7,61\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1\" opacity=\".4\"/><line x1=\"120\" y1=\"78\" x2=\"120\" y2=\"23\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1\" opacity=\".5\"/><line x1=\"120\" y1=\"78\" x2=\"172.3\" y2=\"61\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1\" opacity=\".5\"/><line x1=\"120\" y1=\"78\" x2=\"152.3\" y2=\"122.5\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1\" opacity=\".5\"/><line x1=\"120\" y1=\"78\" x2=\"87.7\" y2=\"122.5\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1\" opacity=\".5\"/><line x1=\"120\" y1=\"78\" x2=\"67.7\" y2=\"61\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1\" opacity=\".5\"/><polygon class=\"srdc-poly\" points=\"120,34 151.4,67.8 149.1,118 103.8,100.2 83.4,66.1\" fill=\"var(--w-accent,#5ad2d9)\" fill-opacity=\".35\" stroke=\"var(--w-accent,#5ad2d9)\" stroke-width=\"2\" stroke-linejoin=\"round\"/></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "svg-line-area-chart",
    "bar-chart-grid-vs-svg",
    "chart-legend-layout",
    "conic-gradient-chart"
   ]
  },
  {
   "id": "svg-gauge-meter",
   "num": "W-292",
   "name": "Gauge / Semi-circle Meter",
   "nameJa": "ゲージ・半円メーター",
   "category": "component",
   "description": "0〜100%を左端から右端まで半円の弧で表すメーター。割合t(0〜1)を角度angle=180°・(1-t)に変換し、x=cx+r・cos(angle)、y=cy-r・sin(angle)で弧の終点座標を求める。その終点を使ってA(楕円弧)コマンドで背景の弧と同じ弧を値の分だけ短く描けば、円形プログレスリングを半円に展開した表現になる。針を追加する場合も同じ式で角度から座標を出せる。",
   "useCase": "達成率やKPIのスコア、バッテリー残量のような「上限のある1つの値」を、数字よりも視覚的な位置で直感的に見せたいダッシュボードで使う。",
   "code": "function gaugePoint(t, cx = 120, cy = 110, r = 70) {\n  const angle = Math.PI * (1 - t); // t=0で左端(180°)、t=1で右端(0°)\n  return [cx + r * Math.cos(angle), cy - r * Math.sin(angle)];\n}\n// gaugePoint(0.65) -> [151.8, 47.6]\n// <path d={`M${cx-r},${cy} A${r},${r} 0 0,1 ${x},${y}`} stroke=\"accent\"/>",
   "tags": [
    "データ可視化",
    "メーター",
    "SVG",
    "KPI"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"半円メーターのデモ（65%）\"><style>.sgm-needle{animation:sgm-sway 3s ease-in-out infinite;transform-origin:120px 110px}@keyframes sgm-sway{0%,100%{transform:rotate(-2deg)}50%{transform:rotate(2deg)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><path d=\"M50,110 A70,70 0 0,1 190,110\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"10\" stroke-linecap=\"round\" opacity=\".35\"/><path d=\"M50,110 A70,70 0 0,1 151.8,47.6\" fill=\"none\" stroke=\"var(--w-accent,#5ad2d9)\" stroke-width=\"10\" stroke-linecap=\"round\"/><g class=\"sgm-needle\"><line x1=\"120\" y1=\"110\" x2=\"145\" y2=\"61\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"3\" stroke-linecap=\"round\"/><circle cx=\"120\" cy=\"110\" r=\"6\" fill=\"var(--w-amber,#ffc857)\"/></g><text x=\"120\" y=\"138\" text-anchor=\"middle\" font-size=\"16\" font-weight=\"700\" fill=\"var(--w-ink,#e8eef9)\" font-family=\"ui-sans-serif,system-ui,sans-serif\">65%</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "svg-line-area-chart",
    "bar-chart-grid-vs-svg",
    "svg-sparkline",
    "svg-radar-chart"
   ]
  },
  {
   "id": "css-grid-heatmap",
   "num": "W-293",
   "name": "CSS Grid Heatmap",
   "nameJa": "ヒートマップ（CSS Grid＋色の段階）",
   "category": "component",
   "description": "行×列の数値をCSS Gridのセル(またはSVGの矩形グリッド)に敷き詰め、値の大小を単一の色の不透明度や明度の段階で表す表現。値vを0〜1に正規化し、opacity=0.15+v・0.85のように下限を設けて変換すると、値が0でもセルの存在自体は見えるため「データが無い」のか「値が低い」のかを取り違えにくい。多色グラデーションより判読しやすく、実装もCSS Gridのセルかsvgのrectどちらでも同じ考え方で組める。",
   "useCase": "曜日×時間帯のアクセス数、機能×チームの利用率など、2つの軸を持つ表形式データを一覧して濃淡で傾向を掴みたいダッシュボードで使う。",
   "code": "// value: 0-1に正規化済みの値\nfunction heatOpacity(value, floor = 0.15) {\n  return floor + value * (1 - floor);\n}\n// heatOpacity(0.8) -> 0.83, heatOpacity(0) -> 0.15 (0でも存在は見える)\n// CSS Grid版: grid-template-columns:repeat(5,1fr) のセルに\n// background:var(--accent); opacity:var(--v) を1セルずつ付与する",
   "tags": [
    "データ可視化",
    "ヒートマップ",
    "CSS Grid",
    "色の段階"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"値を色の濃淡に変換するヒートマップのデモ\"><style>.cgh-cell{opacity:var(--o,1);animation:cgh-wave 4.5s ease-in-out infinite}@keyframes cgh-wave{0%,100%{opacity:var(--o,1)}50%{opacity:calc(var(--o,1) * .7)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect class=\"cgh-cell\" style=\"--o:0.23;animation-delay:0.00s\" x=\"45\" y=\"35\" width=\"16\" height=\"14\" rx=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><rect class=\"cgh-cell\" style=\"--o:0.41;animation-delay:0.15s\" x=\"69\" y=\"35\" width=\"16\" height=\"14\" rx=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><rect class=\"cgh-cell\" style=\"--o:0.57;animation-delay:0.30s\" x=\"93\" y=\"35\" width=\"16\" height=\"14\" rx=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><rect class=\"cgh-cell\" style=\"--o:0.74;animation-delay:0.45s\" x=\"117\" y=\"35\" width=\"16\" height=\"14\" rx=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><rect class=\"cgh-cell\" style=\"--o:0.92;animation-delay:0.60s\" x=\"141\" y=\"35\" width=\"16\" height=\"14\" rx=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><rect class=\"cgh-cell\" style=\"--o:0.32;animation-delay:0.15s\" x=\"45\" y=\"55\" width=\"16\" height=\"14\" rx=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><rect class=\"cgh-cell\" style=\"--o:0.57;animation-delay:0.30s\" x=\"69\" y=\"55\" width=\"16\" height=\"14\" rx=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><rect class=\"cgh-cell\" style=\"--o:0.83;animation-delay:0.45s\" x=\"93\" y=\"55\" width=\"16\" height=\"14\" rx=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><rect class=\"cgh-cell\" style=\"--o:1.00;animation-delay:0.60s\" x=\"117\" y=\"55\" width=\"16\" height=\"14\" rx=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><rect class=\"cgh-cell\" style=\"--o:0.66;animation-delay:0.75s\" x=\"141\" y=\"55\" width=\"16\" height=\"14\" rx=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><rect class=\"cgh-cell\" style=\"--o:0.23;animation-delay:0.30s\" x=\"45\" y=\"75\" width=\"16\" height=\"14\" rx=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><rect class=\"cgh-cell\" style=\"--o:0.41;animation-delay:0.45s\" x=\"69\" y=\"75\" width=\"16\" height=\"14\" rx=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><rect class=\"cgh-cell\" style=\"--o:0.66;animation-delay:0.60s\" x=\"93\" y=\"75\" width=\"16\" height=\"14\" rx=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><rect class=\"cgh-cell\" style=\"--o:0.49;animation-delay:0.75s\" x=\"117\" y=\"75\" width=\"16\" height=\"14\" rx=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><rect class=\"cgh-cell\" style=\"--o:0.32;animation-delay:0.90s\" x=\"141\" y=\"75\" width=\"16\" height=\"14\" rx=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "bar-chart-grid-vs-svg",
    "svg-line-area-chart",
    "svg-radar-chart",
    "svg-gauge-meter"
   ]
  },
  {
   "id": "dot-waffle-chart",
   "num": "W-294",
   "name": "Dot / Waffle Chart",
   "nameJa": "ドット・ワッフルチャート",
   "category": "component",
   "description": "10×10=100個のマス(ドット)を並べ、割合pに応じて先頭からround(p/100・100)個だけ塗りつぶして残りを淡色にする表現。円グラフのように角度を計算する必要がなく「100個中何個」を数えるだけの直感的な比率表示になる。1マス=1%という等価性がそのまま伝わるため、円グラフより低リテラシーな読み手にも誤読されにくい。",
   "useCase": "アンケートの回答割合、達成率、市場シェアなど「全体のうち何割か」を、円グラフより素朴で数えやすい形で見せたいスライドや資料に使う。",
   "code": "// 全100マス中、何マス目までを塗るか\nfunction waffleFilled(index, percent, total = 100) {\n  return index < Math.round((percent / 100) * total);\n}\n// waffleFilled(61, 62) -> true\n// waffleFilled(62, 62) -> false",
   "tags": [
    "データ可視化",
    "ワッフルチャート",
    "割合",
    "アイソタイプ"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"100個のドットで割合を表すワッフルチャートのデモ（62%）\"><style>.dwc-fill{animation:dwc-breathe 4s ease-in-out infinite}@keyframes dwc-breathe{0%,100%{opacity:1}50%{opacity:.72}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.00s\" cx=\"72.8\" cy=\"20.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.01s\" cx=\"83.3\" cy=\"20.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.02s\" cx=\"93.8\" cy=\"20.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.03s\" cx=\"104.3\" cy=\"20.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.04s\" cx=\"114.8\" cy=\"20.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.05s\" cx=\"125.3\" cy=\"20.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.06s\" cx=\"135.8\" cy=\"20.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.07s\" cx=\"146.3\" cy=\"20.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.08s\" cx=\"156.8\" cy=\"20.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.09s\" cx=\"167.3\" cy=\"20.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.10s\" cx=\"72.8\" cy=\"30.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.11s\" cx=\"83.3\" cy=\"30.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.12s\" cx=\"93.8\" cy=\"30.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.13s\" cx=\"104.3\" cy=\"30.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.14s\" cx=\"114.8\" cy=\"30.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.15s\" cx=\"125.3\" cy=\"30.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.16s\" cx=\"135.8\" cy=\"30.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.17s\" cx=\"146.3\" cy=\"30.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.18s\" cx=\"156.8\" cy=\"30.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.19s\" cx=\"167.3\" cy=\"30.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.20s\" cx=\"72.8\" cy=\"41.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.21s\" cx=\"83.3\" cy=\"41.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.22s\" cx=\"93.8\" cy=\"41.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.23s\" cx=\"104.3\" cy=\"41.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.24s\" cx=\"114.8\" cy=\"41.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.25s\" cx=\"125.3\" cy=\"41.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.26s\" cx=\"135.8\" cy=\"41.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.27s\" cx=\"146.3\" cy=\"41.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.28s\" cx=\"156.8\" cy=\"41.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.29s\" cx=\"167.3\" cy=\"41.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.30s\" cx=\"72.8\" cy=\"51.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.31s\" cx=\"83.3\" cy=\"51.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.32s\" cx=\"93.8\" cy=\"51.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.33s\" cx=\"104.3\" cy=\"51.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.34s\" cx=\"114.8\" cy=\"51.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.35s\" cx=\"125.3\" cy=\"51.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.36s\" cx=\"135.8\" cy=\"51.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.37s\" cx=\"146.3\" cy=\"51.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.38s\" cx=\"156.8\" cy=\"51.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.39s\" cx=\"167.3\" cy=\"51.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.40s\" cx=\"72.8\" cy=\"62.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.41s\" cx=\"83.3\" cy=\"62.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.42s\" cx=\"93.8\" cy=\"62.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.43s\" cx=\"104.3\" cy=\"62.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.44s\" cx=\"114.8\" cy=\"62.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.45s\" cx=\"125.3\" cy=\"62.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.46s\" cx=\"135.8\" cy=\"62.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.47s\" cx=\"146.3\" cy=\"62.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.48s\" cx=\"156.8\" cy=\"62.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.49s\" cx=\"167.3\" cy=\"62.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.50s\" cx=\"72.8\" cy=\"72.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.51s\" cx=\"83.3\" cy=\"72.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.52s\" cx=\"93.8\" cy=\"72.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.53s\" cx=\"104.3\" cy=\"72.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.54s\" cx=\"114.8\" cy=\"72.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.55s\" cx=\"125.3\" cy=\"72.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.56s\" cx=\"135.8\" cy=\"72.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.57s\" cx=\"146.3\" cy=\"72.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.58s\" cx=\"156.8\" cy=\"72.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.59s\" cx=\"167.3\" cy=\"72.8\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.60s\" cx=\"72.8\" cy=\"83.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle class=\"dwc-fill\" style=\"animation-delay:0.61s\" cx=\"83.3\" cy=\"83.3\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><circle cx=\"93.8\" cy=\"83.3\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"104.3\" cy=\"83.3\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"114.8\" cy=\"83.3\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"125.3\" cy=\"83.3\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"135.8\" cy=\"83.3\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"146.3\" cy=\"83.3\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"156.8\" cy=\"83.3\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"167.3\" cy=\"83.3\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"72.8\" cy=\"93.8\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"83.3\" cy=\"93.8\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"93.8\" cy=\"93.8\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"104.3\" cy=\"93.8\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"114.8\" cy=\"93.8\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"125.3\" cy=\"93.8\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"135.8\" cy=\"93.8\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"146.3\" cy=\"93.8\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"156.8\" cy=\"93.8\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"167.3\" cy=\"93.8\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"72.8\" cy=\"104.3\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"83.3\" cy=\"104.3\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"93.8\" cy=\"104.3\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"104.3\" cy=\"104.3\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"114.8\" cy=\"104.3\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"125.3\" cy=\"104.3\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"135.8\" cy=\"104.3\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"146.3\" cy=\"104.3\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"156.8\" cy=\"104.3\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"167.3\" cy=\"104.3\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"72.8\" cy=\"114.8\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"83.3\" cy=\"114.8\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"93.8\" cy=\"114.8\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"104.3\" cy=\"114.8\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"114.8\" cy=\"114.8\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"125.3\" cy=\"114.8\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"135.8\" cy=\"114.8\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"146.3\" cy=\"114.8\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"156.8\" cy=\"114.8\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><circle cx=\"167.3\" cy=\"114.8\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\"/><text x=\"120\" y=\"140\" text-anchor=\"middle\" font-size=\"14\" font-weight=\"700\" fill=\"var(--w-ink,#e8eef9)\" font-family=\"ui-sans-serif,system-ui,sans-serif\">62%</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "svg-line-area-chart",
    "bar-chart-grid-vs-svg",
    "svg-radar-chart",
    "svg-gauge-meter"
   ]
  },
  {
   "id": "chart-legend-layout",
   "num": "W-295",
   "name": "Chart Legend Layout",
   "nameJa": "凡例の組み方",
   "category": "component",
   "description": "色や模様と系列名の対応を示す凡例は、同じ大きさ・同じ形の色見本(スワイッチ)を一定の間隔で並べ、見本と文字の間隔も系列ごとに揃えることで初めて機能する。見本のサイズや余白がバラつくと視線の対応付けがずれて誤読につながる。可能な限りグラフ本体に直接ラベルを添えて凡例を省略し、系列数が多い場合だけ凡例に頼る、という優先順位も合わせて意識するとよい。",
   "useCase": "複数系列の棒グラフや折れ線グラフ、円グラフで、色と項目名の対応をひと目で追えるようにしたいときに使う。",
   "code": "<ul class=\"legend\">\n  <li><span class=\"swatch\" style=\"background:var(--accent)\"></span>系列A</li>\n  <li><span class=\"swatch\" style=\"background:var(--amber)\"></span>系列B</li>\n</ul>\n<style>\n.legend{display:flex;gap:16px;list-style:none;padding:0}\n.legend li{display:flex;align-items:center;gap:6px;font-size:12px}\n.swatch{width:12px;height:12px;border-radius:3px;flex:none}\n</style>",
   "tags": [
    "データ可視化",
    "凡例",
    "グラフ",
    "可読性"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"色見本とラベルをそろえて並べる凡例のデモ\"><style>.clg-1{animation:clg-p 4.5s infinite}.clg-2{animation:clg-p 4.5s infinite;animation-delay:1.5s}.clg-3{animation:clg-p 4.5s infinite;animation-delay:3s}@keyframes clg-p{0%,10%,100%{opacity:.6}4%{opacity:1}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><line x1=\"20\" y1=\"90\" x2=\"220\" y2=\"90\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\"/><rect class=\"clg-1\" x=\"40\" y=\"50\" width=\"30\" height=\"40\" rx=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><rect class=\"clg-2\" x=\"100\" y=\"35\" width=\"30\" height=\"55\" rx=\"3\" fill=\"var(--w-amber,#ffc857)\"/><rect class=\"clg-3\" x=\"160\" y=\"60\" width=\"30\" height=\"30\" rx=\"3\" fill=\"#8b7cf6\"/><g class=\"clg-1\"><rect x=\"30\" y=\"110\" width=\"12\" height=\"12\" rx=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><text x=\"46\" y=\"120\" font-size=\"10\" fill=\"var(--w-ink,#e8eef9)\" font-family=\"ui-sans-serif,system-ui,sans-serif\">系列A</text></g><g class=\"clg-2\"><rect x=\"95\" y=\"110\" width=\"12\" height=\"12\" rx=\"3\" fill=\"var(--w-amber,#ffc857)\"/><text x=\"111\" y=\"120\" font-size=\"10\" fill=\"var(--w-ink,#e8eef9)\" font-family=\"ui-sans-serif,system-ui,sans-serif\">系列B</text></g><g class=\"clg-3\"><rect x=\"160\" y=\"110\" width=\"12\" height=\"12\" rx=\"3\" fill=\"#8b7cf6\"/><text x=\"176\" y=\"120\" font-size=\"10\" fill=\"var(--w-ink,#e8eef9)\" font-family=\"ui-sans-serif,system-ui,sans-serif\">系列C</text></g></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "svg-line-area-chart",
    "bar-chart-grid-vs-svg",
    "svg-radar-chart",
    "diagram-label-min-size"
   ]
  },
  {
   "id": "diagram-label-min-size",
   "num": "W-296",
   "name": "Minimum Label Size for Diagrams",
   "nameJa": "図中の文字サイズの下限",
   "category": "component",
   "description": "図解やグラフに添えるラベルは、本文サイズの都合で小さくしすぎると縮小表示や画面外の書き出し画像で読めなくなる。IBM Carbonのデータ可視化用タイプセットでは、ラベルに使う最小のトークン(label-01)を12px/0.75remに定めており、これより小さいラベルはキャプションやフィールドラベル用途にも推奨されていない。図版を作る際はこの12px前後を下限の目安にし、画像として縮小される可能性がある場合はさらに余裕を持たせる。",
   "useCase": "スライドやOGP画像など、実寸より縮小されて表示されることが多い書き出し用の図版で、文字が潰れて読めなくなるのを防ぎたいときに使う。",
   "code": ":root { --label-min: 12px; }\n.chart-label {\n  /* ビューポートに応じて可変にしつつ、下限だけは死守する */\n  font-size: max(var(--label-min), 0.9vw);\n}",
   "tags": [
    "データ可視化",
    "タイポグラフィ",
    "可読性",
    "縮小表示"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"図中ラベルの文字サイズ下限を比較するデモ\"><style>.dlms-row{animation:dlms-p 4s ease-in-out infinite}@keyframes dlms-p{0%,100%{opacity:1}50%{opacity:.7}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><line x1=\"20\" y1=\"78\" x2=\"220\" y2=\"78\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1\" stroke-dasharray=\"2 4\" opacity=\".5\"/><g class=\"dlms-row\" style=\"animation-delay:0.32s\"><text x=\"26\" y=\"32\" font-size=\"9\" fill=\"var(--w-sub,#a7b4cd)\" font-family=\"ui-monospace,monospace\">7px</text><text x=\"70\" y=\"32\" font-size=\"7\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\"0.55\" font-family=\"ui-sans-serif,system-ui,sans-serif\">ラベル</text><text x=\"205\" y=\"32\" text-anchor=\"middle\" font-size=\"12\" fill=\"var(--w-amber,#ffc857)\" font-family=\"ui-sans-serif,system-ui,sans-serif\">△</text></g><g class=\"dlms-row\" style=\"animation-delay:0.62s\"><text x=\"26\" y=\"62\" font-size=\"9\" fill=\"var(--w-sub,#a7b4cd)\" font-family=\"ui-monospace,monospace\">9px</text><text x=\"70\" y=\"62\" font-size=\"9\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\"0.55\" font-family=\"ui-sans-serif,system-ui,sans-serif\">ラベル</text><text x=\"205\" y=\"62\" text-anchor=\"middle\" font-size=\"12\" fill=\"var(--w-amber,#ffc857)\" font-family=\"ui-sans-serif,system-ui,sans-serif\">△</text></g><g class=\"dlms-row\" style=\"animation-delay:0.92s\"><text x=\"26\" y=\"92\" font-size=\"9\" fill=\"var(--w-sub,#a7b4cd)\" font-family=\"ui-monospace,monospace\">12px</text><text x=\"70\" y=\"92\" font-size=\"12\" fill=\"var(--w-ink,#e8eef9)\" opacity=\"1\" font-family=\"ui-sans-serif,system-ui,sans-serif\">ラベル</text><text x=\"205\" y=\"92\" text-anchor=\"middle\" font-size=\"12\" fill=\"var(--w-accent,#5ad2d9)\" font-family=\"ui-sans-serif,system-ui,sans-serif\">✓</text></g><g class=\"dlms-row\" style=\"animation-delay:1.24s\"><text x=\"26\" y=\"124\" font-size=\"9\" fill=\"var(--w-sub,#a7b4cd)\" font-family=\"ui-monospace,monospace\">16px</text><text x=\"70\" y=\"124\" font-size=\"16\" fill=\"var(--w-ink,#e8eef9)\" opacity=\"1\" font-family=\"ui-sans-serif,system-ui,sans-serif\">ラベル</text><text x=\"205\" y=\"124\" text-anchor=\"middle\" font-size=\"12\" fill=\"var(--w-accent,#5ad2d9)\" font-family=\"ui-sans-serif,system-ui,sans-serif\">✓</text></g></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "chart-legend-layout",
    "text-autospace",
    "svg-line-area-chart",
    "bar-chart-grid-vs-svg"
   ]
  },
  {
   "id": "colorblind-safe-encoding",
   "num": "W-297",
   "name": "Don't Rely on Color Alone",
   "nameJa": "色だけに頼らない区別",
   "category": "component",
   "description": "系列やステータスを色だけで区別すると、色覚特性を持つ人や白黒印刷・モノクロ表示では情報が消えてしまう。色に加えて模様(斜線・ドットなどの<pattern>塗り)や形(丸・四角など)を重ねて使うと、色を完全に抜いても区別がつく。このSVGサンプルはカラー版とグレースケール版を交互にクロスフェードさせており、色を消しても模様と形の違いだけで3系列が判別できることを示している。",
   "useCase": "凡例やステータス表示、円グラフの隣接セグメントなど、色の違いだけに意味を持たせてしまいがちな箇所で、色覚多様性や印刷時の劣化に配慮したいときに使う。",
   "code": "<pattern id=\"stripes\" width=\"6\" height=\"6\" patternUnits=\"userSpaceOnUse\" patternTransform=\"rotate(45)\">\n  <line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"6\" stroke=\"var(--bg)\" stroke-width=\"2.5\"/>\n</pattern>\n<!-- 色 + 模様 + 形(丸/四角)の3つを重ねて区別する -->\n<circle r=\"12\" fill=\"var(--amber)\"/>\n<circle r=\"12\" fill=\"url(#stripes)\" opacity=\".7\"/>",
   "tags": [
    "データ可視化",
    "アクセシビリティ",
    "色覚",
    "パターン"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"色に加えて模様・形でも系列を区別するデモ\"><style>.cse-color{animation:cse-fade 5s ease-in-out infinite}.cse-gray{animation:cse-fade-inv 5s ease-in-out infinite}@keyframes cse-fade{0%,40%{opacity:1}50%,90%{opacity:0}100%{opacity:1}}@keyframes cse-fade-inv{0%,40%{opacity:0}50%,90%{opacity:1}100%{opacity:0}}</style><defs><pattern id=\"cse-stripes\" width=\"6\" height=\"6\" patternUnits=\"userSpaceOnUse\" patternTransform=\"rotate(45)\"><line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"6\" stroke=\"var(--w-bg,#101830)\" stroke-width=\"2.5\"/></pattern><pattern id=\"cse-dots\" width=\"7\" height=\"7\" patternUnits=\"userSpaceOnUse\"><circle cx=\"3.5\" cy=\"3.5\" r=\"1.4\" fill=\"var(--w-bg,#101830)\"/></pattern><filter id=\"cse-gray\"><feColorMatrix type=\"saturate\" values=\"0\"/></filter></defs><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g class=\"cse-color\"><circle cx=\"40\" cy=\"35\" r=\"12\" fill=\"var(--w-accent,#5ad2d9)\"/><circle cx=\"40\" cy=\"75\" r=\"12\" fill=\"var(--w-amber,#ffc857)\"/><circle cx=\"40\" cy=\"75\" r=\"12\" fill=\"url(#cse-stripes)\" opacity=\".7\"/><rect x=\"28\" y=\"103\" width=\"24\" height=\"24\" rx=\"4\" fill=\"#8b7cf6\"/><rect x=\"28\" y=\"103\" width=\"24\" height=\"24\" rx=\"4\" fill=\"url(#cse-dots)\" opacity=\".7\"/></g><g class=\"cse-gray\"><circle cx=\"40\" cy=\"35\" r=\"12\" fill=\"var(--w-accent,#5ad2d9)\" filter=\"url(#cse-gray)\"/><circle cx=\"40\" cy=\"75\" r=\"12\" fill=\"var(--w-amber,#ffc857)\" filter=\"url(#cse-gray)\"/><circle cx=\"40\" cy=\"75\" r=\"12\" fill=\"url(#cse-stripes)\" opacity=\".7\" filter=\"url(#cse-gray)\"/><rect x=\"28\" y=\"103\" width=\"24\" height=\"24\" rx=\"4\" fill=\"#8b7cf6\" filter=\"url(#cse-gray)\"/><rect x=\"28\" y=\"103\" width=\"24\" height=\"24\" rx=\"4\" fill=\"url(#cse-dots)\" opacity=\".7\" filter=\"url(#cse-gray)\"/></g><text x=\"65\" y=\"39\" font-size=\"12\" fill=\"var(--w-ink,#e8eef9)\" font-family=\"ui-sans-serif,system-ui,sans-serif\">系列A</text><text x=\"65\" y=\"79\" font-size=\"12\" fill=\"var(--w-ink,#e8eef9)\" font-family=\"ui-sans-serif,system-ui,sans-serif\">系列B</text><text x=\"65\" y=\"119\" font-size=\"12\" fill=\"var(--w-ink,#e8eef9)\" font-family=\"ui-sans-serif,system-ui,sans-serif\">系列C</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "form-associated-custom-elements",
    "svg-line-area-chart",
    "bar-chart-grid-vs-svg",
    "svg-radar-chart"
   ]
  },
  {
   "id": "fe-colormatrix-huerotate",
   "num": "W-298",
   "name": "feColorMatrix Hue Rotate",
   "nameJa": "色相をまとめて回転させる",
   "category": "svgfx",
   "description": "feColorMatrixは色のR/G/B/Aをひとつの行列でまとめて変換するフィルター。type=\"hueRotate\"なら明るさや彩度を保ったまま色相環上で色をぐるっと回転できる。彩度だけ落とす、2色間で塗り分ける（デュオトーン）、チャンネルを入れ替えるといった色調操作も、同じ primitive に渡す行列の数値を変えるだけで作れる。",
   "useCase": "1枚の素材からブランドカラー違いのアイコンを量産したいときや、ホバー時にだけ色調を変えたいときに使う。",
   "code": "<filter id=\"hue-shift\">\n  <feColorMatrix type=\"hueRotate\" values=\"160\"/>\n</filter>\n<circle fill=\"teal\" filter=\"url(#hue-shift)\"/>",
   "tags": [
    "SVG",
    "フィルター",
    "色相",
    "色調補正",
    "ブランドカラー"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"feColorMatrixで色相を回転するデモ\"><style>.fecm-dial{transform-origin:120px 128px;animation:fecm-spin 4s linear infinite}@keyframes fecm-spin{to{transform:rotate(360deg)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><defs><filter id=\"fecm-hue\" x=\"-20%\" y=\"-20%\" width=\"140%\" height=\"140%\"><feColorMatrix type=\"hueRotate\" values=\"160\"/></filter></defs><text x=\"20\" y=\"30\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"11\" fill=\"var(--w-sub,#a7b4cd)\">before</text><circle cx=\"34\" cy=\"60\" r=\"14\" fill=\"var(--w-accent,#5ad2d9)\"/><circle cx=\"64\" cy=\"60\" r=\"14\" fill=\"var(--w-amber,#ffc857)\"/><circle cx=\"94\" cy=\"60\" r=\"14\" fill=\"#ff6b81\"/><text x=\"140\" y=\"30\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"11\" fill=\"var(--w-sub,#a7b4cd)\">after</text><g filter=\"url(#fecm-hue)\"><circle cx=\"154\" cy=\"60\" r=\"14\" fill=\"var(--w-accent,#5ad2d9)\"/><circle cx=\"184\" cy=\"60\" r=\"14\" fill=\"var(--w-amber,#ffc857)\"/><circle cx=\"214\" cy=\"60\" r=\"14\" fill=\"#ff6b81\"/></g><g class=\"fecm-dial\"><circle cx=\"120\" cy=\"128\" r=\"14\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"2\" opacity=\".5\"/><circle cx=\"120\" cy=\"114\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/></g></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "fe-componenttransfer-posterize",
    "fe-morphology-outline",
    "fe-tile-pattern",
    "fe-diffuselighting-emboss"
   ]
  },
  {
   "id": "fe-componenttransfer-posterize",
   "num": "W-299",
   "name": "feComponentTransfer Posterize",
   "nameJa": "階調を間引いてポスター調にする",
   "category": "svgfx",
   "description": "feComponentTransferは各色チャンネルを個別のカーブ関数で変換するフィルター。子要素のfeFuncR/G/Bにtype=\"discrete\"とtableValuesを指定すると、なめらかな階調が数段の帯にまとめられ、シルクスクリーン印刷のようなポスター調になる。type=\"gamma\"やtype=\"linear\"にすればトーンカーブ調整としても使える。",
   "useCase": "写真調の背景をグラフィカルなポスター表現に落としたいときや、階調を意図的に粗くしてレトロ印刷感を出したいときに使う。",
   "code": "<filter id=\"posterize\">\n  <feComponentTransfer>\n    <feFuncR type=\"discrete\" tableValues=\"0 .5 1\"/>\n    <feFuncG type=\"discrete\" tableValues=\"0 .5 1\"/>\n    <feFuncB type=\"discrete\" tableValues=\"0 .5 1\"/>\n  </feComponentTransfer>\n</filter>",
   "tags": [
    "SVG",
    "フィルター",
    "ポスタリゼーション",
    "トーンカーブ",
    "レトロ"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"feComponentTransferで階調を落とすデモ\"><style>.fect-scan{animation:fect-move 3.6s ease-in-out infinite}@keyframes fect-move{0%,100%{transform:translateX(0)}50%{transform:translateX(140px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><defs><linearGradient id=\"fect-grad\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"0\"><stop offset=\"0\" stop-color=\"var(--w-accent,#5ad2d9)\"/><stop offset=\"1\" stop-color=\"var(--w-amber,#ffc857)\"/></linearGradient><filter id=\"fect-post\"><feComponentTransfer><feFuncR type=\"discrete\" tableValues=\"0 .35 .7 1\"/><feFuncG type=\"discrete\" tableValues=\"0 .35 .7 1\"/><feFuncB type=\"discrete\" tableValues=\"0 .35 .7 1\"/></feComponentTransfer></filter></defs><text x=\"20\" y=\"38\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"11\" fill=\"var(--w-sub,#a7b4cd)\">before</text><rect x=\"20\" y=\"46\" width=\"200\" height=\"22\" rx=\"4\" fill=\"url(#fect-grad)\"/><text x=\"20\" y=\"96\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"11\" fill=\"var(--w-sub,#a7b4cd)\">after</text><rect x=\"20\" y=\"104\" width=\"200\" height=\"22\" rx=\"4\" fill=\"url(#fect-grad)\" filter=\"url(#fect-post)\"/><rect class=\"fect-scan\" x=\"16\" y=\"40\" width=\"6\" height=\"90\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".35\"/></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "fe-colormatrix-huerotate",
    "fe-morphology-outline",
    "fe-tile-pattern",
    "fe-diffuselighting-emboss"
   ]
  },
  {
   "id": "fe-morphology-outline",
   "num": "W-300",
   "name": "feMorphology Outline",
   "nameJa": "図形を太らせて縁を作る",
   "category": "svgfx",
   "description": "feMorphologyはアルファ形状を膨張(dilate)または収縮(erode)させるフィルター。operator=\"dilate\"で太らせたコピーを元の形の下に敷くと、画像編集ソフトの「境界線を追加」と同じ縁取り(アウトライン)が作れる。ぼかしを併用しないので輪郭はくっきりしたまま太くなる。",
   "useCase": "背景に溶け込みやすいロゴやアイコンに、背景色を問わず視認性を保つ縁取りを付けたいときに使う。",
   "code": "<filter id=\"outline\">\n  <feMorphology in=\"SourceAlpha\" operator=\"dilate\" radius=\"3\" result=\"thick\"/>\n  <feFlood flood-color=\"#fff\"/>\n  <feComposite in2=\"thick\" operator=\"in\"/>\n  <feMerge>\n    <feMergeNode/>\n    <feMergeNode in=\"SourceGraphic\"/>\n  </feMerge>\n</filter>",
   "tags": [
    "SVG",
    "フィルター",
    "アウトライン",
    "縁取り",
    "視認性"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"feMorphologyで縁取りを作るデモ\"><style>.femo-badge{animation:femo-pulse 3s ease-in-out infinite;transform-origin:120px 75px}@keyframes femo-pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.06)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><defs><filter id=\"femo-outline\" x=\"-40%\" y=\"-40%\" width=\"180%\" height=\"180%\"><feMorphology in=\"SourceAlpha\" operator=\"dilate\" radius=\"4\" result=\"femo-thick\"/><feFlood flood-color=\"var(--w-bg,#101830)\" result=\"femo-color\"/><feComposite in=\"femo-color\" in2=\"femo-thick\" operator=\"in\" result=\"femo-ring\"/><feMerge><feMergeNode in=\"femo-ring\"/><feMergeNode in=\"SourceGraphic\"/></feMerge></filter></defs><g class=\"femo-badge\" filter=\"url(#femo-outline)\"><path d=\"M120 40 L146 58 L136 88 L104 88 L94 58 Z\" fill=\"var(--w-accent,#5ad2d9)\"/></g><circle cx=\"60\" cy=\"110\" r=\"10\" fill=\"var(--w-amber,#ffc857)\" filter=\"url(#femo-outline)\"/><rect x=\"160\" y=\"100\" width=\"24\" height=\"24\" rx=\"5\" fill=\"var(--w-amber,#ffc857)\" filter=\"url(#femo-outline)\"/></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "fe-colormatrix-huerotate",
    "fe-componenttransfer-posterize",
    "fe-tile-pattern",
    "fe-diffuselighting-emboss"
   ]
  },
  {
   "id": "fe-tile-pattern",
   "num": "W-301",
   "name": "feTile Repeat",
   "nameJa": "小さな断片をフィルターで敷き詰める",
   "category": "svgfx",
   "description": "feTileは、別のフィルタープリミティブが作った小さな矩形領域（x/y/width/heightで指定するサブリージョン）を切り出し、フィルター全体の範囲に敷き詰め直すプリミティブ。<pattern>要素を使わずに、フィルターの計算結果そのものをタイル化できるのが特徴。",
   "useCase": "feTurbulenceなどで生成した模様の一部だけを取り出して規則的なテクスチャに変換したいときに使う。",
   "code": "<filter id=\"tile\" x=\"0\" y=\"0\" width=\"100%\" height=\"100%\">\n  <feOffset in=\"SourceGraphic\" x=\"0\" y=\"0\" width=\"24\" height=\"24\" result=\"cell\"/>\n  <feTile in=\"cell\"/>\n</filter>",
   "tags": [
    "SVG",
    "フィルター",
    "タイリング",
    "反復",
    "テクスチャ"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"feTileでタイル状に敷き詰めるデモ\"><style>.fetl-card{animation:fetl-fade 4s ease-in-out infinite}@keyframes fetl-fade{0%,100%{opacity:1}50%{opacity:.75}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><defs><filter id=\"fetl-f\" filterUnits=\"userSpaceOnUse\" primitiveUnits=\"userSpaceOnUse\" x=\"20\" y=\"20\" width=\"200\" height=\"110\"><feOffset in=\"SourceGraphic\" dx=\"0\" dy=\"0\" x=\"0\" y=\"0\" width=\"26\" height=\"26\" result=\"fetl-cell\"/><feTile in=\"fetl-cell\"/></filter></defs><g class=\"fetl-card\"><circle cx=\"13\" cy=\"13\" r=\"4\" fill=\"var(--w-accent,#5ad2d9)\" filter=\"url(#fetl-f)\"/></g><rect x=\"20\" y=\"20\" width=\"200\" height=\"110\" rx=\"8\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1\" opacity=\".4\"/></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "fe-colormatrix-huerotate",
    "fe-componenttransfer-posterize",
    "fe-morphology-outline",
    "fe-diffuselighting-emboss"
   ]
  },
  {
   "id": "fe-diffuselighting-emboss",
   "num": "W-302",
   "name": "feDiffuseLighting Emboss",
   "nameJa": "疑似的な光でエンボス加工する",
   "category": "svgfx",
   "description": "feDiffuseLightingは、ぼかしたアルファ画像を凹凸マップに見立て、仮想の光源を当てて陰影を計算するフィルター。子要素にfeDistantLight（無限遠からの平行光、太陽光のような当たり方）を置くと、紙に型押ししたようなエンボス調の質感になる。lighting-colorは光の色そのものを指定するCSSプロパティ。",
   "useCase": "バッジやロゴに立体的な型押し感を出したいときや、フラットな背景に控えめな質感を足したいときに使う。",
   "code": "<filter id=\"emboss\">\n  <feGaussianBlur in=\"SourceAlpha\" stdDeviation=\"2\" result=\"b\"/>\n  <feDiffuseLighting in=\"b\" surfaceScale=\"4\" lighting-color=\"#fff\">\n    <feDistantLight azimuth=\"235\" elevation=\"55\"/>\n  </feDiffuseLighting>\n</filter>",
   "tags": [
    "SVG",
    "フィルター",
    "疑似3D",
    "エンボス",
    "質感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"feDiffuseLightingでエンボス加工するデモ\"><style>.fedl-light{animation:fedl-glow 4s ease-in-out infinite}@keyframes fedl-glow{0%,100%{lighting-color:var(--w-ink,#e8eef9)}50%{lighting-color:var(--w-amber,#ffc857)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><defs><filter id=\"fedl-f\" x=\"-30%\" y=\"-30%\" width=\"160%\" height=\"160%\"><feGaussianBlur in=\"SourceAlpha\" stdDeviation=\"2.4\" result=\"fedl-blur\"/><feDiffuseLighting class=\"fedl-light\" in=\"fedl-blur\" surfaceScale=\"5\" diffuseConstant=\"1.15\" lighting-color=\"var(--w-ink,#e8eef9)\" result=\"fedl-lit\"><feDistantLight azimuth=\"235\" elevation=\"55\"/></feDiffuseLighting><feComposite in=\"fedl-lit\" in2=\"SourceAlpha\" operator=\"in\" result=\"fedl-clip\"/><feComposite in=\"fedl-clip\" in2=\"SourceGraphic\" operator=\"arithmetic\" k1=\"0\" k2=\".5\" k3=\".6\" k4=\"0\"/></filter></defs><g filter=\"url(#fedl-f)\"><rect x=\"70\" y=\"42\" width=\"100\" height=\"66\" rx=\"14\" fill=\"var(--w-accent,#5ad2d9)\"/><circle cx=\"120\" cy=\"75\" r=\"20\" fill=\"var(--w-bg,#101830)\"/></g></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "fe-specularlighting-spotlight",
    "sketchy-outline-filter",
    "grain-noise",
    "fe-colormatrix-huerotate"
   ]
  },
  {
   "id": "fe-specularlighting-spotlight",
   "num": "W-303",
   "name": "feSpecularLighting Spotlight",
   "nameJa": "スポットライトのハイライトを当てる",
   "category": "svgfx",
   "description": "feSpecularLightingはfeDiffuseLightingの兄弟プリミティブで、光沢のある反射ハイライトだけを計算する。子要素をfeSpotLightにすると、位置(x/y/z)と狙う方向(pointsAtX/Y/Z)を持つ懐中電灯のような光源になり、円錐状に絞られた光が当たった部分だけがテカる。fePointLightは同じ仕組みで全方向に広がる点光源。",
   "useCase": "ボタンやアイコンに1点だけツヤのある光沢を足して、クリック可能に見える立体感を出したいときに使う。",
   "code": "<filter id=\"spotlight\">\n  <feSpecularLighting in=\"SourceAlpha\" surfaceScale=\"6\" specularConstant=\"1\" specularExponent=\"16\" lighting-color=\"#fff\">\n    <feSpotLight x=\"70\" y=\"30\" z=\"90\" pointsAtX=\"120\" pointsAtY=\"75\" pointsAtZ=\"0\"/>\n  </feSpecularLighting>\n</filter>",
   "tags": [
    "SVG",
    "フィルター",
    "疑似3D",
    "光沢",
    "スポットライト"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"feSpecularLightingでスポット光沢を当てるデモ\"><style>.fesl-light{animation:fesl-glow 3.6s ease-in-out infinite}@keyframes fesl-glow{0%,100%{lighting-color:#fff}50%{lighting-color:var(--w-accent,#5ad2d9)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><defs><filter id=\"fesl-f\" x=\"-40%\" y=\"-40%\" width=\"180%\" height=\"180%\"><feSpecularLighting class=\"fesl-light\" in=\"SourceAlpha\" surfaceScale=\"6\" specularConstant=\"1\" specularExponent=\"16\" lighting-color=\"#fff\" result=\"fesl-spec\"><feSpotLight x=\"70\" y=\"20\" z=\"90\" pointsAtX=\"120\" pointsAtY=\"75\" pointsAtZ=\"0\" specularExponent=\"20\" limitingConeAngle=\"40\"/></feSpecularLighting><feComposite in=\"fesl-spec\" in2=\"SourceAlpha\" operator=\"in\" result=\"fesl-clip\"/><feComposite in=\"fesl-clip\" in2=\"SourceGraphic\" operator=\"over\"/></filter></defs><circle cx=\"120\" cy=\"75\" r=\"42\" fill=\"var(--w-sub,#a7b4cd)\" filter=\"url(#fesl-f)\"/></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "fe-diffuselighting-emboss",
    "fe-colormatrix-huerotate",
    "fe-componenttransfer-posterize",
    "fe-morphology-outline"
   ]
  },
  {
   "id": "fe-convolvematrix-edgedetect",
   "num": "W-304",
   "name": "feConvolveMatrix Edge Detect",
   "nameJa": "隣接ピクセルの差分で輪郭を検出する",
   "category": "svgfx",
   "description": "feConvolveMatrixは注目ピクセルとその周囲を小さな行列(カーネル)で重み付け合成するフィルターで、画像処理のコンボリューションそのものをSVGで表現できる。中心を強調し周囲を引く行列を使うと輪郭だけが光るエッジ検出になり、中心を強めるだけの行列にすればシャープ化になる。",
   "useCase": "アイコンや図形の輪郭だけを強調したいときや、スキャン画像のような解析風エフェクトを作りたいときに使う。",
   "code": "<filter id=\"edge\" color-interpolation-filters=\"sRGB\">\n  <feConvolveMatrix order=\"3\"\n    kernelMatrix=\"-1 -1 -1 -1 8 -1 -1 -1 -1\"\n    edgeMode=\"duplicate\"/>\n</filter>",
   "tags": [
    "SVG",
    "フィルター",
    "エッジ検出",
    "コンボリューション",
    "解析風"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"feConvolveMatrixで輪郭を検出するデモ\"><style>.fecv-grid{animation:fecv-pulse 3.4s ease-in-out infinite;transform-origin:120px 75px}@keyframes fecv-pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.05)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><defs><filter id=\"fecv-f\" x=\"-20%\" y=\"-20%\" width=\"140%\" height=\"140%\" color-interpolation-filters=\"sRGB\"><feConvolveMatrix order=\"3\" kernelMatrix=\"-1 -1 -1 -1 8 -1 -1 -1 -1\" divisor=\"1\" bias=\"0\" edgeMode=\"duplicate\" preserveAlpha=\"true\"/></filter></defs><g class=\"fecv-grid\" filter=\"url(#fecv-f)\"><rect x=\"70\" y=\"35\" width=\"100\" height=\"80\" fill=\"var(--w-sub,#a7b4cd)\"/><rect x=\"70\" y=\"35\" width=\"50\" height=\"40\" fill=\"var(--w-accent,#5ad2d9)\"/><rect x=\"120\" y=\"75\" width=\"50\" height=\"40\" fill=\"var(--w-amber,#ffc857)\"/><circle cx=\"120\" cy=\"75\" r=\"16\" fill=\"var(--w-bg,#101830)\"/></g></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "fe-colormatrix-huerotate",
    "fe-componenttransfer-posterize",
    "fe-morphology-outline",
    "fe-tile-pattern"
   ]
  },
  {
   "id": "fe-blend-modes",
   "num": "W-305",
   "name": "feBlend Modes",
   "nameJa": "フィルター内部で2つの色を合成する",
   "category": "svgfx",
   "description": "feBlendはCSSのmix-blend-modeと同じ乗算(multiply)・スクリーン(screen)・比較(difference)などの合成モードを、フィルターパイプラインの内部で使うプリミティブ。ページ背景と合成するBackgroundImage入力は環境依存が大きいため実務では避け、feFloodやfeTurbulenceなど自分で作った色・模様同士を混ぜるのが安定した使い方。",
   "useCase": "1つのフィルター内で生成した2枚の色や模様を、乗算やスクリーンで重ねて新しい質感を作りたいときに使う。",
   "code": "<filter id=\"blend\">\n  <feFlood flood-color=\"teal\" result=\"a\"/>\n  <feFlood flood-color=\"gold\" result=\"b\"/>\n  <feBlend in=\"a\" in2=\"b\" mode=\"multiply\" result=\"mix\"/>\n  <feComposite in=\"mix\" in2=\"SourceAlpha\" operator=\"in\"/>\n</filter>",
   "tags": [
    "SVG",
    "フィルター",
    "ブレンドモード",
    "合成",
    "配色"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"feBlendで2色を合成するデモ\"><style>.fbln-b{animation:fbln-cycle 4s ease-in-out infinite}@keyframes fbln-cycle{0%,100%{flood-color:var(--w-amber,#ffc857)}50%{flood-color:#ff6b81}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><defs><filter id=\"fbln-f\" x=\"-20%\" y=\"-20%\" width=\"140%\" height=\"140%\"><feFlood flood-color=\"var(--w-accent,#5ad2d9)\" result=\"fbln-a\"/><feFlood class=\"fbln-b\" flood-color=\"var(--w-amber,#ffc857)\" result=\"fbln-bcol\"/><feBlend in=\"fbln-a\" in2=\"fbln-bcol\" mode=\"multiply\" result=\"fbln-mix\"/><feComposite in=\"fbln-mix\" in2=\"SourceAlpha\" operator=\"in\"/></filter></defs><g filter=\"url(#fbln-f)\"><path d=\"M120 34 137 66 173 71 147 96 154 132 120 114 86 132 93 96 67 71 103 66 Z\"/></g><text x=\"120\" y=\"146\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">mode=\"multiply\"</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "fe-colormatrix-huerotate",
    "fe-componenttransfer-posterize",
    "fe-morphology-outline",
    "fe-tile-pattern"
   ]
  },
  {
   "id": "fe-composite-neonglow",
   "num": "W-306",
   "name": "Manual Neon Glow",
   "nameJa": "feFlood・feOffset・feCompositeで手作りする発光",
   "category": "svgfx",
   "description": "feDropShadowは影の色・ズレ・ぼかしをまとめて指定できる便利プリミティブだが、内部では実はfeOffset・feFlood・feCompositeなどの組み合わせに展開されている。これを自分で書き下すと、色を自由に変えたり、複製した発光レイヤーを重ねて濃さを増したりと、ワンライナーでは効かない細かい調整ができる。",
   "useCase": "ロゴやCTAボタンにネオンサインのような発光を付けたいとき、単純な影より強く光らせたいときに使う。",
   "code": "<filter id=\"glow\">\n  <feGaussianBlur in=\"SourceAlpha\" stdDeviation=\"4\" result=\"blur\"/>\n  <feFlood flood-color=\"cyan\" result=\"color\"/>\n  <feComposite in=\"color\" in2=\"blur\" operator=\"in\" result=\"glow\"/>\n  <feMerge>\n    <feMergeNode in=\"glow\"/><feMergeNode in=\"glow\"/>\n    <feMergeNode in=\"SourceGraphic\"/>\n  </feMerge>\n</filter>",
   "tags": [
    "SVG",
    "フィルター",
    "ネオン",
    "発光",
    "夜"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"手作りネオン発光のデモ\"><style>.feng-flood{animation:feng-neon 3.4s ease-in-out infinite}@keyframes feng-neon{0%,100%{flood-color:var(--w-accent,#5ad2d9)}50%{flood-color:var(--w-amber,#ffc857)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><defs><filter id=\"feng-f\" x=\"-60%\" y=\"-60%\" width=\"220%\" height=\"220%\"><feGaussianBlur in=\"SourceAlpha\" stdDeviation=\"4\" result=\"feng-blur\"/><feFlood class=\"feng-flood\" flood-color=\"var(--w-accent,#5ad2d9)\" result=\"feng-color\"/><feComposite in=\"feng-color\" in2=\"feng-blur\" operator=\"in\" result=\"feng-glow\"/><feMerge><feMergeNode in=\"feng-glow\"/><feMergeNode in=\"feng-glow\"/><feMergeNode in=\"SourceGraphic\"/></feMerge></filter></defs><text x=\"120\" y=\"90\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"46\" font-weight=\"800\" fill=\"var(--w-bg,#101830)\" filter=\"url(#feng-f)\">A</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "fe-colormatrix-huerotate",
    "fe-componenttransfer-posterize",
    "fe-morphology-outline",
    "fe-tile-pattern"
   ]
  },
  {
   "id": "filter-region-bleed",
   "num": "W-307",
   "name": "Filter Region Bleed",
   "nameJa": "ぼかしが切れないようフィルター領域を広げる",
   "category": "svgfx",
   "description": "<filter>のx/y/width/height（既定値はfilterUnits=\"objectBoundingBox\"で-10%〜120%）は、フィルター結果を描画してよい範囲を決める見えない枠。ぼかしや発光のstdDeviationを大きくしてもこの枠からはみ出た分は四角く切り取られてしまうため、強いぼかしほど枠を-50%〜200%のように広げておく必要がある。primitiveUnitsを\"userSpaceOnUse\"にすると、各プリミティブの数値をパーセントでなく実寸で指定できる。",
   "useCase": "強いぼかしや発光を付けたら縁が不自然に四角く切れてしまった、というときの原因調査と対策に使う。",
   "code": "<!-- 既定のまま：はみ出た分が四角く切れる -->\n<filter id=\"tight\"><feGaussianBlur stdDeviation=\"10\"/></filter>\n\n<!-- 領域を広げる：自然にフェードアウトする -->\n<filter id=\"loose\" x=\"-60%\" y=\"-60%\" width=\"220%\" height=\"220%\">\n  <feGaussianBlur stdDeviation=\"10\"/>\n</filter>",
   "tags": [
    "SVG",
    "フィルター",
    "filterUnits",
    "ぼかし",
    "落とし穴"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"フィルター領域を広げて切れを防ぐデモ\"><style>.freg-a,.freg-b{animation:freg-float 3.6s ease-in-out infinite}@keyframes freg-float{0%,100%{transform:translateY(0)}50%{transform:translateY(-6px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><defs><filter id=\"freg-tight\" x=\"-5%\" y=\"-5%\" width=\"110%\" height=\"110%\"><feGaussianBlur stdDeviation=\"9\"/></filter><filter id=\"freg-loose\" x=\"-70%\" y=\"-70%\" width=\"240%\" height=\"240%\"><feGaussianBlur stdDeviation=\"9\"/></filter></defs><rect x=\"18\" y=\"40\" width=\"90\" height=\"70\" rx=\"6\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1\" stroke-dasharray=\"3 3\" opacity=\".5\"/><circle class=\"freg-a\" cx=\"63\" cy=\"75\" r=\"22\" fill=\"var(--w-accent,#5ad2d9)\" filter=\"url(#freg-tight)\"/><circle class=\"freg-b\" cx=\"177\" cy=\"75\" r=\"22\" fill=\"var(--w-accent,#5ad2d9)\" filter=\"url(#freg-loose)\"/><text x=\"63\" y=\"128\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">既定：切れる</text><text x=\"177\" y=\"128\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">領域を拡張</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "fe-colormatrix-huerotate",
    "fe-componenttransfer-posterize",
    "fe-morphology-outline",
    "fe-tile-pattern"
   ]
  },
  {
   "id": "smil-animate-basic",
   "num": "W-308",
   "name": "SMIL animate",
   "nameJa": "SMILで属性を直接アニメーションする",
   "category": "svgfx",
   "description": "<animate>はSVG要素の属性値を時間で補間するSMILアニメーション。attributeNameで対象を指定し、valuesに複数値をセミコロン区切りで渡すだけでキーフレームになる。2015年にChromeが廃止方針を一度出したが実装は取り下げられ、現在はMDNでBaseline「広く利用可能」（2020年1月〜）と案内されている、CSSでは届かない属性（フィルターのパラメータなど）を動かせる数少ない宣言的手段。",
   "useCase": "JSを書かずに数値や色をループさせたいときや、CSSでは変化させられないSVG固有の属性を動かしたいときに使う。",
   "code": "<circle r=\"20\" fill=\"teal\">\n  <animate attributeName=\"r\" values=\"20;34;20\" dur=\"3s\" repeatCount=\"indefinite\"/>\n  <animate attributeName=\"fill\" values=\"teal;gold;teal\" dur=\"3s\" repeatCount=\"indefinite\"/>\n</circle>",
   "tags": [
    "SVG",
    "SMIL",
    "アニメーション",
    "属性",
    "宣言的"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"SMILのanimateで半径と色を動かすデモ\"><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><circle cx=\"120\" cy=\"75\" r=\"36\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1\" opacity=\".3\"/><circle cx=\"120\" cy=\"75\" r=\"20\" fill=\"#5ad2d9\"><animate attributeName=\"r\" values=\"20;34;20\" dur=\"3s\" repeatCount=\"indefinite\"/><animate attributeName=\"fill\" values=\"#5ad2d9;#ffc857;#5ad2d9\" dur=\"3s\" repeatCount=\"indefinite\"/></circle></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "smil-animatemotion-mpath",
    "smil-animatetransform",
    "smil-begin-chain",
    "smil-keysplines-easing"
   ]
  },
  {
   "id": "smil-animatetransform",
   "num": "W-309",
   "name": "SMIL animateTransform",
   "nameJa": "SMILでtransformを回す・伸ばす",
   "category": "svgfx",
   "description": "<animateTransform>はtranslate・rotate・scale・skewXなどtransform属性専用のSMILアニメーション。CSSのtransformアニメーションと役割は似ているが、transform属性しか持たない古いSVGビューアや、transform-originの概念がない環境でも同じ書き方で動く。type=\"rotate\"のfrom/toに中心点も一緒に書けるのが特徴。",
   "useCase": "計器の針やコンパスなど、特定の中心点を軸にした回転を素のSVGだけで表現したいときに使う。",
   "code": "<rect x=\"118\" y=\"40\" width=\"4\" height=\"30\" fill=\"teal\">\n  <animateTransform attributeName=\"transform\" type=\"rotate\"\n    from=\"0 120 75\" to=\"360 120 75\" dur=\"4s\" repeatCount=\"indefinite\"/>\n</rect>",
   "tags": [
    "SVG",
    "SMIL",
    "回転",
    "transform",
    "計器"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"SMILのanimateTransformで針を回すデモ\"><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><circle cx=\"120\" cy=\"75\" r=\"40\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"2\" opacity=\".4\"/><circle cx=\"120\" cy=\"41\" r=\"2.4\" fill=\"var(--w-sub,#a7b4cd)\"/><circle cx=\"120\" cy=\"109\" r=\"2.4\" fill=\"var(--w-sub,#a7b4cd)\"/><circle cx=\"86\" cy=\"75\" r=\"2.4\" fill=\"var(--w-sub,#a7b4cd)\"/><circle cx=\"154\" cy=\"75\" r=\"2.4\" fill=\"var(--w-sub,#a7b4cd)\"/><rect x=\"118\" y=\"42\" width=\"4\" height=\"33\" rx=\"2\" fill=\"var(--w-accent,#5ad2d9)\"><animateTransform attributeName=\"transform\" type=\"rotate\" from=\"0 120 75\" to=\"360 120 75\" dur=\"4s\" repeatCount=\"indefinite\"/></rect><circle cx=\"120\" cy=\"75\" r=\"5\" fill=\"var(--w-amber,#ffc857)\"/></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "smil-animate-basic",
    "smil-animatemotion-mpath",
    "smil-begin-chain",
    "smil-keysplines-easing"
   ]
  },
  {
   "id": "smil-animatemotion-mpath",
   "num": "W-310",
   "name": "SMIL animateMotion + mpath",
   "nameJa": "既存パスに沿って要素を動かす",
   "category": "svgfx",
   "description": "<animateMotion>は要素そのものを2次元的に動かすSMILアニメーション。子要素の<mpath>で既存の<path>をhref参照すれば、パス座標を二重に書かずに済む。CSSのoffset-pathが同じ目的で使えるが、mpathは参照先のpathをそのまま流用できるため、すでに引いてある案内線・地図のルートなどにそのまま乗せたいときに便利。",
   "useCase": "地図上のルート表示や、曲がりくねった案内線に沿ってアイコンを移動させたいときに使う。",
   "code": "<path id=\"route\" d=\"M20,120 C60,20 100,140 140,60 S220,20 220,90\" fill=\"none\"/>\n<circle r=\"7\" fill=\"teal\">\n  <animateMotion dur=\"3.5s\" repeatCount=\"indefinite\">\n    <mpath href=\"#route\"/>\n  </animateMotion>\n</circle>",
   "tags": [
    "SVG",
    "SMIL",
    "パスアニメ",
    "モーション",
    "ルート"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"SMILのanimateMotionでパスに沿って動かすデモ\"><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><path id=\"smm-path\" d=\"M20,120 C60,20 100,140 140,60 S220,20 220,90\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"2\" opacity=\".4\"/><circle r=\"7\" fill=\"var(--w-accent,#5ad2d9)\"><animateMotion dur=\"3.5s\" repeatCount=\"indefinite\"><mpath href=\"#smm-path\"/></animateMotion></circle></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "smil-animate-basic",
    "smil-animatetransform",
    "smil-begin-chain",
    "smil-keysplines-easing"
   ]
  },
  {
   "id": "smil-begin-chain",
   "num": "W-311",
   "name": "SMIL begin Chaining",
   "nameJa": "beginの連鎖でアニメを順番につなぐ",
   "category": "svgfx",
   "description": "SMILのbegin属性は時刻だけでなく「別アニメの終わりからn秒後」という同期指定（id.end+0.5sのようなsyncbase構文）を書ける。<set>は補間せず一瞬で値を切り替える離散的なアニメで、begin連鎖と組み合わせると信号機のように複数要素が順番にON/OFFするシーケンスを、JSのタイマーなしで表現できる。単純な等間隔ループならrepeatCountだけで足りるが、フェーズごとに長さが違う手順にはbegin連鎖が向く。",
   "useCase": "信号機やステップ形式のオンボーディングなど、決まった順番で切り替わる演出をCSSだけでは表現しにくいときに使う。",
   "code": "<circle id=\"red\" fill=\"red\">\n  <set attributeName=\"opacity\" to=\"1\" begin=\"0s;yellow.end\" dur=\"1.6s\"/>\n</circle>\n<circle id=\"green\">\n  <set attributeName=\"opacity\" to=\"1\" begin=\"red.end\" dur=\"1.6s\"/>\n</circle>\n<circle id=\"yellow\">\n  <set attributeName=\"opacity\" to=\"1\" begin=\"green.end\" dur=\"0.6s\"/>\n</circle>",
   "tags": [
    "SVG",
    "SMIL",
    "シーケンス",
    "begin連鎖",
    "信号機"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"SMILのbegin連鎖で信号機を切り替えるデモ\"><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"96\" y=\"20\" width=\"48\" height=\"110\" rx=\"14\" fill=\"#1c2740\"/><circle cx=\"120\" cy=\"46\" r=\"14\" fill=\"#ff6b81\" opacity=\".25\"><set id=\"smb-red-on\" attributeName=\"opacity\" to=\"1\" begin=\"0s;smb-yellow-on.end\" dur=\"1.6s\" fill=\"remove\"/></circle><circle cx=\"120\" cy=\"104\" r=\"14\" fill=\"#5ad2d9\" opacity=\".25\"><set id=\"smb-green-on\" attributeName=\"opacity\" to=\"1\" begin=\"smb-red-on.end\" dur=\"1.6s\" fill=\"remove\"/></circle><circle cx=\"120\" cy=\"75\" r=\"14\" fill=\"#ffc857\" opacity=\".25\"><set id=\"smb-yellow-on\" attributeName=\"opacity\" to=\"1\" begin=\"smb-green-on.end\" dur=\"0.6s\" fill=\"remove\"/></circle></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "smil-animate-basic",
    "smil-animatetransform",
    "smil-animatemotion-mpath",
    "smil-keysplines-easing"
   ]
  },
  {
   "id": "smil-keysplines-easing",
   "num": "W-312",
   "name": "SMIL keySplines Easing",
   "nameJa": "keySplinesでSMILに緩急を付ける",
   "category": "svgfx",
   "description": "SMILのcalcModeは既定でlinear（等速）。calcMode=\"spline\"にしてkeySplinesへcubic-bezierの制御点を渡すと、CSSのeasing関数と同じ理屈で緩急を付けられる。keyTimesで各キーフレームの時刻割合を指定し、区間の数だけkeySplinesをセミコロン区切りで並べる。repeatCountは単純な繰り返し回数の指定に使う属性で、無限ループならindefiniteを渡す。",
   "useCase": "CSSアニメーションが使えない古いパイプラインやメール向けSVGでも、等速でない自然な動きを付けたいときに使う。",
   "code": "<circle cx=\"20\" r=\"8\" fill=\"teal\">\n  <animate attributeName=\"cx\" values=\"20;220;20\" keyTimes=\"0;0.5;1\"\n    calcMode=\"spline\" keySplines=\"0.65 0 0.35 1;0.65 0 0.35 1\"\n    dur=\"2.4s\" repeatCount=\"indefinite\"/>\n</circle>",
   "tags": [
    "SVG",
    "SMIL",
    "イージング",
    "keySplines",
    "緩急"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"SMILのkeySplinesでイージングを比較するデモ\"><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><text x=\"20\" y=\"34\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">calcMode=\"linear\"</text><line x1=\"20\" y1=\"46\" x2=\"220\" y2=\"46\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1\" opacity=\".3\"/><circle cy=\"46\" r=\"8\" fill=\"var(--w-accent,#5ad2d9)\"><animate attributeName=\"cx\" values=\"20;220;20\" keyTimes=\"0;0.5;1\" calcMode=\"linear\" dur=\"2.4s\" repeatCount=\"indefinite\"/></circle><text x=\"20\" y=\"104\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">calcMode=\"spline\"</text><line x1=\"20\" y1=\"116\" x2=\"220\" y2=\"116\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1\" opacity=\".3\"/><circle cy=\"116\" r=\"8\" fill=\"var(--w-amber,#ffc857)\"><animate attributeName=\"cx\" values=\"20;220;20\" keyTimes=\"0;0.5;1\" calcMode=\"spline\" keySplines=\"0.65 0 0.35 1;0.65 0 0.35 1\" dur=\"2.4s\" repeatCount=\"indefinite\"/></circle></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "smil-animate-basic",
    "smil-animatetransform",
    "smil-animatemotion-mpath",
    "smil-begin-chain"
   ]
  },
  {
   "id": "svg-pathlength-normalize",
   "num": "W-313",
   "name": "pathLength Normalization",
   "nameJa": "パスの長さを0〜100に正規化する",
   "category": "svgfx",
   "description": "stroke-dasharrayやstroke-dashoffsetは実際のパスの長さ(単位はユーザー単位)を基準に動く。複雑な曲線やジグザグだと正確な長さを計算しづらいが、パス自身にpathLength=\"100\"を指定すると、そのパスの長さを「100」とみなすようブラウザが距離計算をスケーリングし直してくれる。円のように公式で長さを出せない自由な形の線でも、ダッシュの値を常に0〜100の割合で扱える。",
   "useCase": "チェックやサインのような不規則な形の線を「描画中」演出にしたいとき、実測せずに0〜100だけで管理したいときに使う。",
   "code": "<path d=\"M130,24 86,84 114,84 100,126 156,64 124,64Z\"\n  pathLength=\"100\" fill=\"none\" stroke=\"teal\" stroke-width=\"6\"\n  stroke-dasharray=\"100\" style=\"stroke-dashoffset:30\"/>",
   "tags": [
    "SVG",
    "パス",
    "pathLength",
    "正規化",
    "線画"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"pathLengthでパスの長さを正規化するデモ\"><style>.spl-bolt{stroke-dasharray:100;animation:spl-draw 2.6s ease-in-out infinite}@keyframes spl-draw{0%,100%{stroke-dashoffset:64}50%{stroke-dashoffset:0}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><path class=\"spl-bolt\" d=\"M130,24 86,84 114,84 100,126 156,64 124,64Z\" pathLength=\"100\" fill=\"none\" stroke=\"var(--w-accent,#5ad2d9)\" stroke-width=\"7\" stroke-linejoin=\"round\" stroke-linecap=\"round\"/><text x=\"120\" y=\"142\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">pathLength=\"100\"</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "svg-fillrule-evenodd",
    "stroke-draw",
    "fe-colormatrix-huerotate",
    "fe-componenttransfer-posterize"
   ]
  },
  {
   "id": "svg-vector-effect-stroke",
   "num": "W-314",
   "name": "Non-Scaling Stroke",
   "nameJa": "拡大しても線の太さを変えない",
   "category": "svgfx",
   "description": "SVGの図形を transform で拡大すると、既定では塗りだけでなくstroke-widthも一緒に拡大されて線が太くなってしまう。vector-effect=\"non-scaling-stroke\"を指定した要素は、拡大縮小の影響を線幅だけ受けなくなり、地図やダイアグラムをズームしても罫線が常に同じ太さで見える。",
   "useCase": "ズーム可能な地図やインフォグラフィックで、拡大しても罫線や枠線の太さを一定に保ちたいときに使う。",
   "code": "<circle r=\"30\" fill=\"none\" stroke=\"teal\" stroke-width=\"6\"\n  vector-effect=\"non-scaling-stroke\"/>\n<!-- transform: scale(2) してもstroke-widthは6のまま -->",
   "tags": [
    "SVG",
    "vector-effect",
    "ストローク",
    "ズーム",
    "地図"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"non-scaling-strokeで線幅を保つデモ\"><style>.sve-a{transform-origin:70px 75px;animation:sve-scale 3.2s ease-in-out infinite}.sve-b{transform-origin:170px 75px;animation:sve-scale 3.2s ease-in-out infinite}@keyframes sve-scale{0%,100%{transform:scale(.8)}50%{transform:scale(1.3)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><circle class=\"sve-a\" cx=\"70\" cy=\"75\" r=\"28\" fill=\"none\" stroke=\"var(--w-accent,#5ad2d9)\" stroke-width=\"6\"/><circle class=\"sve-b\" cx=\"170\" cy=\"75\" r=\"28\" fill=\"none\" stroke=\"var(--w-accent,#5ad2d9)\" stroke-width=\"6\" vector-effect=\"non-scaling-stroke\"/><text x=\"70\" y=\"130\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">既定</text><text x=\"170\" y=\"130\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">non-scaling</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "stroke-draw",
    "checkmark-draw",
    "progress-ring",
    "viewbox-camera"
   ]
  },
  {
   "id": "svg-paint-order-outline",
   "num": "W-315",
   "name": "paint-order on Shapes",
   "nameJa": "図形の塗りと線の順序を入れ替える",
   "category": "svgfx",
   "description": "SVGは既定でfill(塗り)を描いた後にstroke(線)を重ねるため、太い線を付けると図形の輪郭が線の内側半分に食い込んで見える。paint-order=\"stroke fill\"にすると線を先に描いてから塗りを重ねられるので、線が塗りの外側にはみ出さず、ステッカーのようなくっきりした縁取りになる。文字だけでなく円や多角形などどんな図形にも使える汎用のプロパティ。",
   "useCase": "バッジやアイコンに太い縁取りを付けるとき、線が図形を侵食して細く見えるのを防ぎたいときに使う。",
   "code": ".badge{\n  fill: gold;\n  stroke: navy;\n  stroke-width: 12;\n  paint-order: stroke fill; /* 既定は fill stroke */\n}",
   "tags": [
    "SVG",
    "paint-order",
    "縁取り",
    "バッジ",
    "アイコン"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"paint-orderで図形の縁取りを変えるデモ\"><style>.spo-a,.spo-b{transform-origin:center;animation:spo-pulse 3s ease-in-out infinite}.spo-a{transform-origin:70px 75px}.spo-b{transform-origin:170px 75px}@keyframes spo-pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.07)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><path class=\"spo-a\" d=\"M70,43 L102,75 L70,107 L38,75 Z\" fill=\"var(--w-amber,#ffc857)\" stroke=\"var(--w-bg,#101830)\" stroke-width=\"12\" stroke-linejoin=\"round\"/><path class=\"spo-b\" d=\"M170,43 L202,75 L170,107 L138,75 Z\" fill=\"var(--w-amber,#ffc857)\" stroke=\"var(--w-bg,#101830)\" stroke-width=\"12\" stroke-linejoin=\"round\" paint-order=\"stroke fill\"/><text x=\"70\" y=\"130\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">既定</text><text x=\"170\" y=\"130\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">stroke fill</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "fe-morphology-outline",
    "text-on-path",
    "symbol-sprite",
    "fe-colormatrix-huerotate"
   ]
  },
  {
   "id": "svg-fillrule-evenodd",
   "num": "W-316",
   "name": "fill-rule evenodd",
   "nameJa": "同じ形なのに塗りの規則で穴が変わる",
   "category": "svgfx",
   "description": "1本のpathに外側と内側の2つの輪郭(サブパス)を同じ回転方向で書くと、既定のfill-rule=\"nonzero\"では重なり同士が足し合わされて穴なしの塗りになる。fill-rule=\"evenodd\"にすると、境界線をまたぐ回数の偶奇だけで内外を判定するため、同じパスデータのまま中央に穴が開いたドーナツ状になる。clip-pathで切り抜く際のclip-ruleも同じ考え方。",
   "useCase": "アイコンフォントや地図のように、1つのpathの中に穴や飛び地を表現したいときに使う。",
   "code": "<path d=\"M34,0 A34,34 0 1,1 -34,0 A34,34 0 1,1 34,0\n         M15,0 A15,15 0 1,1 -15,0 A15,15 0 1,1 15,0\"\n  fill=\"teal\" fill-rule=\"evenodd\"/><!-- nonzeroだと穴がふさがる -->",
   "tags": [
    "SVG",
    "fill-rule",
    "evenodd",
    "穴",
    "パス"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"fill-ruleのevenoddとnonzeroを比較するデモ\"><style>.sfr-spin{transform-origin:0 0;animation:sfr-pulse 3s ease-in-out infinite}@keyframes sfr-pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.08)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><defs><path id=\"sfr-ring\" d=\"M34,0 A34,34 0 1,1 -34,0 A34,34 0 1,1 34,0 M15,0 A15,15 0 1,1 -15,0 A15,15 0 1,1 15,0\"/></defs><g transform=\"translate(70,75)\"><use class=\"sfr-spin\" href=\"#sfr-ring\" fill=\"var(--w-accent,#5ad2d9)\" fill-rule=\"evenodd\"/></g><g transform=\"translate(170,75)\"><use class=\"sfr-spin\" href=\"#sfr-ring\" fill=\"var(--w-accent,#5ad2d9)\" fill-rule=\"nonzero\"/></g><text x=\"70\" y=\"130\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">evenodd</text><text x=\"170\" y=\"130\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">nonzero</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "svg-pathlength-normalize",
    "fe-colormatrix-huerotate",
    "fe-componenttransfer-posterize",
    "fe-morphology-outline"
   ]
  },
  {
   "id": "svg-marker-arrows",
   "num": "W-317",
   "name": "Path Markers",
   "nameJa": "折れ線の要所に矢印や点を自動で置く",
   "category": "svgfx",
   "description": "<marker>要素を定義し、線を引く要素にmarker-start・marker-mid・marker-endを指定すると、始点・各頂点・終点に矢印や丸印を自動で配置できる。頂点が増減してもマーカー側の定義を書き直す必要がないため、図形描画ライブラリのような動的な折れ線に向く。頂点の角の見た目はstroke-linejoin(丸め方)とstroke-miterlimit(尖りの上限)で別途調整する。",
   "useCase": "フローチャートの矢印や、データフローの向きを示す線を、頂点の数に関わらず一貫した見た目で描きたいときに使う。",
   "code": "<marker id=\"arrow\" viewBox=\"0 0 10 10\" refX=\"8\" refY=\"5\"\n  markerWidth=\"8\" markerHeight=\"8\" orient=\"auto-start-reverse\">\n  <path d=\"M0,0 L10,5 L0,10 Z\" fill=\"teal\"/>\n</marker>\n<polyline points=\"30,110 120,110 120,40 210,40\"\n  fill=\"none\" stroke=\"teal\" stroke-width=\"4\" marker-end=\"url(#arrow)\"/>",
   "tags": [
    "SVG",
    "マーカー",
    "矢印",
    "フローチャート",
    "折れ線"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"marker-start・mid・endで矢印を配置するデモ\"><style>.smar-flow{stroke-dasharray:6 10;animation:smar-march 1.6s linear infinite}@keyframes smar-march{to{stroke-dashoffset:-32}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><defs><marker id=\"smar-start\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerWidth=\"6\" markerHeight=\"6\"><circle cx=\"5\" cy=\"5\" r=\"4\" fill=\"var(--w-accent,#5ad2d9)\"/></marker><marker id=\"smar-mid\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerWidth=\"5\" markerHeight=\"5\"><circle cx=\"5\" cy=\"5\" r=\"3\" fill=\"var(--w-amber,#ffc857)\"/></marker><marker id=\"smar-end\" viewBox=\"0 0 10 10\" refX=\"8\" refY=\"5\" markerWidth=\"8\" markerHeight=\"8\" orient=\"auto-start-reverse\"><path d=\"M0,0 L10,5 L0,10 Z\" fill=\"var(--w-accent,#5ad2d9)\"/></marker></defs><polyline points=\"30,110 120,110 120,40 210,40\" fill=\"none\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"4\" stroke-linejoin=\"round\" marker-start=\"url(#smar-start)\" marker-mid=\"url(#smar-mid)\" marker-end=\"url(#smar-end)\"/><polyline class=\"smar-flow\" points=\"30,110 120,110 120,40 210,40\" fill=\"none\" stroke=\"var(--w-ink,#e8eef9)\" stroke-width=\"2\" opacity=\".8\"/></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "orthogonal-elbow-connector",
    "fe-colormatrix-huerotate",
    "fe-componenttransfer-posterize",
    "fe-morphology-outline"
   ]
  },
  {
   "id": "svg-preserveaspectratio",
   "num": "W-318",
   "name": "preserveAspectRatio Modes",
   "nameJa": "縦横比が違う枠にどう収めるか決める",
   "category": "svgfx",
   "description": "viewBoxを持つ<svg>や<symbol>を、中身と違う縦横比の枠にはめ込むとき、preserveAspectRatioが挙動を決める。既定のxMidYMid meetは全体を収めて余白を残し、sliceは枠いっぱいに拡大してはみ出た分を切り、noneは縦横比を無視して枠に合わせて伸び縮みする。ネストした<svg>はそれ自体が独立した小さなビューポートになる。",
   "useCase": "ロゴやアイコンをアスペクト比の違うカードやサムネイル枠にはめ込むとき、余白・トリミング・引き伸ばしのどれにするか決めたいときに使う。",
   "code": "<svg width=\"64\" height=\"70\" viewBox=\"0 0 100 40\"\n  preserveAspectRatio=\"xMidYMid slice\">\n  <rect x=\"10\" y=\"10\" width=\"80\" height=\"20\" fill=\"teal\"/>\n</svg>",
   "tags": [
    "SVG",
    "preserveAspectRatio",
    "viewBox",
    "入れ子svg",
    "レスポンシブ"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"preserveAspectRatioの3つの挙動を比較するデモ\"><style>.spar-frame{animation:spar-glow 3.6s ease-in-out infinite}@keyframes spar-glow{0%,100%{stroke-opacity:.3}50%{stroke-opacity:.85}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"8\" y=\"32\" width=\"64\" height=\"70\" rx=\"6\" fill=\"#1c2740\"/><svg x=\"8\" y=\"32\" width=\"64\" height=\"70\" viewBox=\"0 0 100 40\" preserveAspectRatio=\"xMidYMid meet\"><rect x=\"10\" y=\"10\" width=\"80\" height=\"20\" rx=\"4\" fill=\"var(--w-accent,#5ad2d9)\"/></svg><rect class=\"spar-frame\" x=\"8\" y=\"32\" width=\"64\" height=\"70\" rx=\"6\" fill=\"none\" stroke=\"var(--w-accent,#5ad2d9)\" stroke-width=\"1.5\"/><rect x=\"84\" y=\"32\" width=\"64\" height=\"70\" rx=\"6\" fill=\"#1c2740\"/><svg x=\"84\" y=\"32\" width=\"64\" height=\"70\" viewBox=\"0 0 100 40\" preserveAspectRatio=\"xMidYMid slice\"><rect x=\"10\" y=\"10\" width=\"80\" height=\"20\" rx=\"4\" fill=\"var(--w-accent,#5ad2d9)\"/></svg><rect class=\"spar-frame\" x=\"84\" y=\"32\" width=\"64\" height=\"70\" rx=\"6\" fill=\"none\" stroke=\"var(--w-accent,#5ad2d9)\" stroke-width=\"1.5\"/><rect x=\"160\" y=\"32\" width=\"64\" height=\"70\" rx=\"6\" fill=\"#1c2740\"/><svg x=\"160\" y=\"32\" width=\"64\" height=\"70\" viewBox=\"0 0 100 40\" preserveAspectRatio=\"none\"><rect x=\"10\" y=\"10\" width=\"80\" height=\"20\" rx=\"4\" fill=\"var(--w-accent,#5ad2d9)\"/></svg><rect class=\"spar-frame\" x=\"160\" y=\"32\" width=\"64\" height=\"70\" rx=\"6\" fill=\"none\" stroke=\"var(--w-accent,#5ad2d9)\" stroke-width=\"1.5\"/><text x=\"40\" y=\"118\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">meet</text><text x=\"116\" y=\"118\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">slice</text><text x=\"192\" y=\"118\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">none</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "viewbox-camera",
    "fe-colormatrix-huerotate",
    "fe-componenttransfer-posterize",
    "fe-morphology-outline"
   ]
  },
  {
   "id": "svg-spreadmethod",
   "num": "W-319",
   "name": "Gradient spreadMethod",
   "nameJa": "グラデーションの余白をどう埋めるか決める",
   "category": "svgfx",
   "description": "グラデーションの始点・終点(x1/x2など)を図形の内側に収めると、両端に「色指定が及んでいない」余白ができる。spreadMethodはその余白の埋め方を決める属性で、pad(既定・端の色を伸ばす)、reflect(折り返して繰り返す)、repeat(同じ向きで繰り返す)の3種類がある。角度を変えたいだけならgradientTransformで見た目を回転・拡大できる。",
   "useCase": "2色だけで縞模様やジグザグ模様を作りたいときや、グラデーションの端の処理を意図的に選びたいときに使う。",
   "code": "<linearGradient id=\"g\" x1=\"20%\" x2=\"80%\" spreadMethod=\"repeat\">\n  <stop offset=\"0\" stop-color=\"teal\"/>\n  <stop offset=\"1\" stop-color=\"gold\"/>\n</linearGradient>",
   "tags": [
    "SVG",
    "グラデーション",
    "spreadMethod",
    "縞模様",
    "塗り"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"spreadMethodのpad・reflect・repeatを比較するデモ\"><style>.ssm-scan{animation:ssm-move 3.6s ease-in-out infinite}@keyframes ssm-move{0%,100%{transform:translateX(0)}50%{transform:translateX(190px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><defs><linearGradient id=\"ssm-pad\" x1=\".2\" y1=\"0\" x2=\".8\" y2=\"0\" spreadMethod=\"pad\"><stop offset=\"0\" stop-color=\"var(--w-accent,#5ad2d9)\"/><stop offset=\"1\" stop-color=\"var(--w-amber,#ffc857)\"/></linearGradient><linearGradient id=\"ssm-reflect\" x1=\".2\" y1=\"0\" x2=\".8\" y2=\"0\" spreadMethod=\"reflect\"><stop offset=\"0\" stop-color=\"var(--w-accent,#5ad2d9)\"/><stop offset=\"1\" stop-color=\"var(--w-amber,#ffc857)\"/></linearGradient><linearGradient id=\"ssm-repeat\" x1=\".2\" y1=\"0\" x2=\".8\" y2=\"0\" spreadMethod=\"repeat\"><stop offset=\"0\" stop-color=\"var(--w-accent,#5ad2d9)\"/><stop offset=\"1\" stop-color=\"var(--w-amber,#ffc857)\"/></linearGradient></defs><text x=\"20\" y=\"27\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">pad</text><rect x=\"20\" y=\"32\" width=\"200\" height=\"22\" rx=\"4\" fill=\"url(#ssm-pad)\"/><text x=\"20\" y=\"66\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">reflect</text><rect x=\"20\" y=\"71\" width=\"200\" height=\"22\" rx=\"4\" fill=\"url(#ssm-reflect)\"/><text x=\"20\" y=\"105\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">repeat</text><rect x=\"20\" y=\"110\" width=\"200\" height=\"22\" rx=\"4\" fill=\"url(#ssm-repeat)\"/><rect class=\"ssm-scan\" x=\"16\" y=\"28\" width=\"5\" height=\"108\" fill=\"var(--w-ink,#e8eef9)\" opacity=\".3\"/></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "gradient-animate",
    "fe-colormatrix-huerotate",
    "fe-componenttransfer-posterize",
    "fe-morphology-outline"
   ]
  },
  {
   "id": "svg-mask-type",
   "num": "W-320",
   "name": "mask-type luminance vs alpha",
   "nameJa": "マスクを明るさで見るか透明度で見るか",
   "category": "svgfx",
   "description": "<mask>は既定でmask-type=\"luminance\"、つまりマスク画像の明るさ(輝度)を不透明度として使う。同じマスクをmask-type=\"alpha\"にすると、色の明暗は無視してマスク画像自身のアルファ(透明度)だけを見る。不透明な色だけで塗られたグラデーションをマスクにすると、luminanceでは暗い側が透けて見えるのに対し、alphaでは色に関係なく全面がそのまま見えるという違いが出る。",
   "useCase": "白黒のグラデーションで滑らかにフェードさせたいのか、色を無視して形だけで切り抜きたいのかを切り替えたいときに使う。",
   "code": "<mask id=\"m\" mask-type=\"alpha\">\n  <rect width=\"80\" height=\"80\" fill=\"url(#fadeGrad)\"/>\n</mask>\n<rect width=\"80\" height=\"80\" fill=\"teal\" mask=\"url(#m)\"/>",
   "tags": [
    "SVG",
    "mask-type",
    "輝度",
    "アルファ",
    "マスク"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"mask-typeのluminanceとalphaを比較するデモ\"><style>.smty-a,.smty-b{transform-origin:center;animation:smty-pulse 3.4s ease-in-out infinite}.smty-a{transform-origin:70px 75px}.smty-b{transform-origin:170px 75px}@keyframes smty-pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.05)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><defs><linearGradient id=\"smty-grad\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"0\"><stop offset=\"0\" stop-color=\"#0a1020\"/><stop offset=\"1\" stop-color=\"#ffffff\"/></linearGradient><mask id=\"smty-lum\"><rect x=\"30\" y=\"30\" width=\"80\" height=\"80\" fill=\"url(#smty-grad)\"/></mask><mask id=\"smty-alpha\" mask-type=\"alpha\"><rect x=\"130\" y=\"30\" width=\"80\" height=\"80\" fill=\"url(#smty-grad)\"/></mask></defs><rect class=\"smty-a\" x=\"30\" y=\"30\" width=\"80\" height=\"80\" rx=\"10\" fill=\"var(--w-accent,#5ad2d9)\" mask=\"url(#smty-lum)\"/><rect class=\"smty-b\" x=\"130\" y=\"30\" width=\"80\" height=\"80\" rx=\"10\" fill=\"var(--w-accent,#5ad2d9)\" mask=\"url(#smty-alpha)\"/><text x=\"70\" y=\"130\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">luminance(既定)</text><text x=\"170\" y=\"130\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">alpha</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "mask-reveal",
    "svg-clip-path",
    "fe-colormatrix-huerotate",
    "fe-componenttransfer-posterize"
   ]
  },
  {
   "id": "svg-title-desc-role",
   "num": "W-321",
   "name": "title/desc + role=img",
   "nameJa": "SVGに読み上げ用の名前と説明を持たせる",
   "category": "svgfx",
   "description": "装飾ではなく意味を持つSVGには、role=\"img\"で「これは1枚の画像として扱う要素だ」と伝えたうえで、子要素の<title>でアクセシブルな名前、<desc>で補足説明を与える。aria-labelledbyでtitle/descのidを指し示すと、スクリーンリーダーは<title>を短い名前として、<desc>を詳細説明として読み上げる。aria-labelだけで足りる場面もあるが、説明文まで必要ならtitle/descの組み合わせがより丁寧。",
   "useCase": "アイコンだけで意味を伝えているボタンや、内容が複雑なインフォグラフィックをスクリーンリーダー利用者にも伝えたいときに使う。",
   "code": "<svg role=\"img\" aria-labelledby=\"bellTitle bellDesc\">\n  <title id=\"bellTitle\">通知ベルのアイコン</title>\n  <desc id=\"bellDesc\">新着通知があることを示すバッジ付きのベル</desc>\n  <path d=\"...\"/>\n</svg>",
   "tags": [
    "SVG",
    "アクセシビリティ",
    "title",
    "desc",
    "スクリーンリーダー"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"通知ベルのアイコン\"><title id=\"sttl-t\">通知ベルのアイコン</title><desc id=\"sttl-d\">新着通知があることを示す、赤いバッジ付きのベル形アイコン。</desc><style>.sttl-bell{transform-origin:120px 40px;animation:sttl-ring 2.6s ease-in-out infinite}@keyframes sttl-ring{0%,100%{transform:rotate(0deg)}25%{transform:rotate(8deg)}75%{transform:rotate(-8deg)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g class=\"sttl-bell\"><path d=\"M120,40 C104,40 96,54 96,72 L96,92 L88,104 L152,104 L144,92 L144,72 C144,54 136,40 120,40 Z\" fill=\"var(--w-ink,#e8eef9)\"/><circle cx=\"120\" cy=\"112\" r=\"7\" fill=\"var(--w-ink,#e8eef9)\"/><circle cx=\"148\" cy=\"50\" r=\"9\" fill=\"#ff6b81\"/></g></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "fe-colormatrix-huerotate",
    "fe-componenttransfer-posterize",
    "fe-morphology-outline",
    "fe-tile-pattern"
   ]
  },
  {
   "id": "svg-inline-vs-img-theming",
   "num": "W-322",
   "name": "Inline SVG vs <img> Theming",
   "nameJa": "SVGの埋め込み方でCSS変数が届くか変わる",
   "category": "svgfx",
   "description": "HTML内に直接書いたインラインSVGは、ページ本体と同じ文書・同じカスケードの中にあるため、fill=\"var(--brand)\"のようにCSSカスタムプロパティやcurrentColorがそのまま効く。ところが同じSVGファイルを<img src=\"icon.svg\">やCSSのbackground-imageで読み込むと、ブラウザはそれを別文書として分離して描画するため、ページ側のCSS変数は届かずファイル内のフォールバック値（またはブラウザ既定）で描画される。",
   "useCase": "アイコンをテーマカラーで動的に染めたいのか、単なる静的画像として使い回したいのかを先に決めたいときに使う。",
   "code": "<!-- インライン: var()もcurrentColorも効く -->\n<svg><path fill=\"var(--brand,#5ad2d9)\" d=\"...\"/></svg>\n\n<!-- 外部ファイル参照: 別文書扱いでvar()は届かない -->\n<img src=\"icon.svg\" alt=\"\">\n<div style=\"background-image:url(icon.svg)\"></div>",
   "tags": [
    "SVG",
    "CSS変数",
    "テーマ",
    "img",
    "アイコン運用"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"インラインSVGと画像読み込みでCSS変数の届き方が変わるデモ\"><style>.sinl-a,.sinl-b{transform-origin:center;animation:sinl-pulse 3.2s ease-in-out infinite}.sinl-a{transform-origin:70px 75px}.sinl-b{transform-origin:170px 75px}@keyframes sinl-pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.08)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g class=\"sinl-a\"><circle cx=\"70\" cy=\"75\" r=\"30\" fill=\"var(--w-accent,#5ad2d9)\"/><path d=\"M58,75 L67,84 L84,64\" stroke=\"var(--w-bg,#101830)\" stroke-width=\"5\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></g><g class=\"sinl-b\"><circle cx=\"170\" cy=\"75\" r=\"30\" fill=\"#8a93a6\"/><path d=\"M158,75 L167,84 L184,64\" stroke=\"var(--w-bg,#101830)\" stroke-width=\"5\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></g><text x=\"70\" y=\"128\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">inline</text><text x=\"170\" y=\"128\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"10\" fill=\"var(--w-sub,#a7b4cd)\">&lt;img&gt;/background</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "fe-colormatrix-huerotate",
    "fe-componenttransfer-posterize",
    "fe-morphology-outline",
    "fe-tile-pattern"
   ]
  },
  {
   "id": "orthogonal-elbow-connector",
   "num": "W-323",
   "name": "Orthogonal Elbow Connector",
   "nameJa": "直交エルボー・コネクタ",
   "category": "svgfx",
   "description": "2つの箱を斜め線でなく「水平→丸い角→垂直→丸い角→水平」の経路で結ぶSVGパス。両端のx中間点midを軸に、H(水平線)・V(垂直線)・Q(2次ベジェで角を丸める)を組み合わせて1本のd属性にする。角の半径rを固定しておけば、始点終点の位置が変わっても同じ式で再利用できる。",
   "useCase": "フローチャートや構成図、ロードマップで箱同士を配線するとき、直線的で読み取りやすい経路を再現性高く描きたい場合に使う。",
   "code": "function elbowPath(x1, y1, x2, y2, r = 10) {\n  const mid = (x1 + x2) / 2;\n  const dy = y2 > y1 ? r : -r;\n  return `M${x1},${y1} H${mid - r} Q${mid},${y1} ${mid},${y1 + dy}\n          V${y2 - dy} Q${mid},${y2} ${mid + r},${y2} H${x2}`;\n}\n// elbowPath(70, 75, 170, 40) => \"M70,75 H110 Q120,75 120,65 V50 Q120,40 130,40 H170\"",
   "tags": [
    "SVG",
    "図解",
    "コネクタ",
    "フローチャート",
    "スパッと決まる"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"直交エルボー・コネクタのデモ\"><style>.oec-dot{animation:oec-move 4s linear infinite}@keyframes oec-move{0%{offset-distance:0%}100%{offset-distance:100%}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"20\" y=\"55\" width=\"50\" height=\"40\" rx=\"8\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\"/><text x=\"45\" y=\"79\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"13\" fill=\"var(--w-ink,#e8eef9)\">A</text><rect x=\"170\" y=\"20\" width=\"50\" height=\"40\" rx=\"8\" fill=\"var(--w-accent,#5ad2d9)\" opacity=\".2\" stroke=\"var(--w-accent,#5ad2d9)\" stroke-width=\"1.5\"/><text x=\"195\" y=\"44\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"13\" fill=\"var(--w-ink,#e8eef9)\">B</text><path id=\"oec-path\" d=\"M70,75 H110 Q120,75 120,65 V50 Q120,40 130,40 H170\" fill=\"none\" stroke=\"var(--w-accent,#5ad2d9)\" stroke-width=\"3\" stroke-linecap=\"round\"/><circle class=\"oec-dot\" r=\"4\" fill=\"var(--w-amber,#ffc857)\"><animateMotion dur=\"4s\" repeatCount=\"indefinite\"><mpath href=\"#oec-path\"/></animateMotion></circle></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "connector-crossing-bridge",
    "connector-fan-attach",
    "bezier-connector-tangent",
    "svg-marker-arrows"
   ]
  },
  {
   "id": "connector-crossing-bridge",
   "num": "W-324",
   "name": "Connector Crossing Bridge",
   "nameJa": "交差のブリッジ（配線の立体交差）",
   "category": "svgfx",
   "description": "2本の配線が交差する箇所で「繋がっていない」ことを明示する描き方。接続している交点は塗りつぶした小さな円(ドット)を置き、接続していない交点は片方の線だけに半径8px程度の半円アーク(SVGのAコマンド)を割り込ませて相手の線を跨がせる。ドットと跳躍アークという2つの記号を使い分けることで、線を消したり避けたりせずに交差の意味を伝えられる。",
   "useCase": "回路図風の装飾、依存関係図、サイトマップなど配線が絡む図で、交点が「接続」か「素通り」かを一目で区別させたいときに使う。",
   "code": "// 交差点(cx,cy)で線Bだけをジャンプさせる半円バンプ\nfunction hopArc(cx, cy, r = 8) {\n  return `A${r},${r} 0 0,1 ${cx},${cy + r}`; // 直前の点は (cx, cy - r) である前提\n}\n// 例: 縦線が y=67 から y=83 の区間だけ右に膨らんで水平線を跨ぐ\n// d=\"M170,20 V67 A8,8 0 0,1 170,83 V130\"",
   "tags": [
    "SVG",
    "図解",
    "コネクタ",
    "交差",
    "配線"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"配線交差のブリッジ表現のデモ\"><style>.ccb-flow{animation:ccb-run 4s linear infinite}@keyframes ccb-run{0%{transform:translateX(0)}100%{transform:translateX(200px)}}.ccb-dot{animation:ccb-pulse 2s ease-in-out infinite}@keyframes ccb-pulse{0%,100%{r:3}50%{r:4.5}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><line x1=\"20\" y1=\"75\" x2=\"220\" y2=\"75\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"2.5\"/><circle class=\"ccb-flow\" cx=\"20\" cy=\"75\" r=\"3.5\" fill=\"var(--w-amber,#ffc857)\"/><line x1=\"70\" y1=\"20\" x2=\"70\" y2=\"130\" stroke=\"var(--w-accent,#5ad2d9)\" stroke-width=\"2.5\"/><circle class=\"ccb-dot\" cx=\"70\" cy=\"75\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><path d=\"M170,20 V67 A8,8 0 0,1 170,83 V130\" fill=\"none\" stroke=\"var(--w-accent,#5ad2d9)\" stroke-width=\"2.5\"/><text x=\"70\" y=\"140\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"9\" fill=\"var(--w-sub,#a7b4cd)\">接続</text><text x=\"170\" y=\"140\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"9\" fill=\"var(--w-sub,#a7b4cd)\">非接続</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "orthogonal-elbow-connector",
    "connector-fan-attach",
    "bezier-connector-tangent",
    "inline-label-on-line"
   ]
  },
  {
   "id": "connector-fan-attach",
   "num": "W-325",
   "name": "Fan-out Connection Points",
   "nameJa": "接続点の分散（ファン配置）",
   "category": "svgfx",
   "description": "1つの箱の同じ辺にN本の線が集まるとき、接続点を辺の端に寄せず等間隔に割り振る配置法。辺の長さLに対し、k番目(1〜N)の接続点をL・k/(N+1)の位置に置くだけで、線が1点に束ならず自然に分散する。中心を境に対称になるのも利点。",
   "useCase": "ハブ&スポーク型の構成図、1つの親ノードから複数の子ノードへ分岐する組織図やアーキテクチャ図で、接続点の重なりを避けたいときに使う。",
   "code": "// 辺の長さL、接続本数Nから k番目(1-indexed)の接続点位置を求める\nfunction fanPoint(edgeStart, edgeLength, n, k) {\n  return edgeStart + (edgeLength * k) / (n + 1);\n}\n// 辺が y=45〜105 (L=60) の3分岐なら\n// fanPoint(45, 60, 3, 1) -> 60, fanPoint(45, 60, 3, 2) -> 75, fanPoint(45, 60, 3, 3) -> 90",
   "tags": [
    "SVG",
    "図解",
    "コネクタ",
    "ハブ&スポーク",
    "均等配置"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"接続点をファン状に均等分散させるデモ\"><style>.cfa-l{animation:cfa-p 3.6s infinite}@keyframes cfa-p{0%,15%,100%{opacity:.4}5%{opacity:1}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"20\" y=\"45\" width=\"50\" height=\"60\" rx=\"8\" fill=\"var(--w-accent,#5ad2d9)\" opacity=\".2\" stroke=\"var(--w-accent,#5ad2d9)\" stroke-width=\"1.5\"/><text x=\"45\" y=\"79\" text-anchor=\"middle\" font-family=\"ui-sans-serif,system-ui,sans-serif\" font-size=\"12\" fill=\"var(--w-ink,#e8eef9)\">HUB</text><rect x=\"190\" y=\"18\" width=\"34\" height=\"24\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.2\"/><rect x=\"190\" y=\"63\" width=\"34\" height=\"24\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.2\"/><rect x=\"190\" y=\"108\" width=\"34\" height=\"24\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.2\"/><line class=\"cfa-l\" style=\"animation-delay:0s\" x1=\"70\" y1=\"60\" x2=\"190\" y2=\"30\" stroke=\"var(--w-accent,#5ad2d9)\" stroke-width=\"2\"/><circle cx=\"70\" cy=\"60\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><line class=\"cfa-l\" style=\"animation-delay:.6s\" x1=\"70\" y1=\"75\" x2=\"190\" y2=\"75\" stroke=\"var(--w-accent,#5ad2d9)\" stroke-width=\"2\"/><circle cx=\"70\" cy=\"75\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/><line class=\"cfa-l\" style=\"animation-delay:1.2s\" x1=\"70\" y1=\"90\" x2=\"190\" y2=\"120\" stroke=\"var(--w-accent,#5ad2d9)\" stroke-width=\"2\"/><circle cx=\"70\" cy=\"90\" r=\"3\" fill=\"var(--w-accent,#5ad2d9)\"/></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "orthogonal-elbow-connector",
    "connector-crossing-bridge",
    "bezier-connector-tangent",
    "inline-label-on-line"
   ]
  },
  {
   "id": "inline-label-on-line",
   "num": "W-326",
   "name": "Inline Label on a Line",
   "nameJa": "線を途切れさせて置くラベル",
   "category": "svgfx",
   "description": "罫線や軸線の上にラベルを重ねるとき、文字の下だけ背景色の帯で線を一旦「消し」、さらにその帯の外側にも数px余白を残してから線を再開する2段構えの配置法。SVGは後に描いた要素が前の要素の上に重なる描画順の仕組みを利用し、線→背景帯→ラベルの順に重ねるだけで実装できる。帯だけで線を消すと文字が線と密着して読みにくくなるため、帯をラベルよりひと回り大きく取り、線の再開点とラベルの間に見た目の隙間を作るのが要点。",
   "useCase": "タイムラインの日付ラベル、ロードマップの区切り、罫線をまたぐ数値キャプションなど「線の上に文字を置く」場面で、線と文字が重なって潰れるのを防ぎたいときに使う。",
   "code": "<!-- 線 → 背景色の帯(erase) → ラベル本体、の順に重ねる -->\n<line x1=\"20\" y1=\"75\" x2=\"220\" y2=\"75\" stroke=\"#a7b4cd\"/>\n<rect x=\"92\" y=\"63\" width=\"56\" height=\"24\" fill=\"var(--bg)\"/> <!-- 線を消す帯 -->\n<rect x=\"100\" y=\"66\" width=\"40\" height=\"18\" rx=\"9\" fill=\"var(--bg)\" stroke=\"#5ad2d9\"/>\n<text x=\"120\" y=\"79\" text-anchor=\"middle\">Q3</text>\n<!-- 帯の端(x=92/148)とラベル本体の端(x=100/140)の差=8pxが見た目の隙間 -->",
   "tags": [
    "SVG",
    "図解",
    "ラベル",
    "タイムライン",
    "可読性"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"線を途切れさせて置くラベルのデモ\"><style>.ilol-pill{animation:ilol-pulse 4s ease-in-out infinite}@keyframes ilol-pulse{0%,100%{opacity:1}50%{opacity:.55}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><line x1=\"20\" y1=\"75\" x2=\"220\" y2=\"75\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"2\"/><circle cx=\"55\" cy=\"75\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\"/><circle cx=\"185\" cy=\"75\" r=\"3\" fill=\"var(--w-sub,#a7b4cd)\"/><rect x=\"92\" y=\"63\" width=\"56\" height=\"24\" fill=\"var(--w-bg,#101830)\"/><rect class=\"ilol-pill\" x=\"100\" y=\"66\" width=\"40\" height=\"18\" rx=\"9\" fill=\"var(--w-bg,#101830)\" stroke=\"var(--w-accent,#5ad2d9)\" stroke-width=\"1.5\"/><text x=\"120\" y=\"79\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"11\" fill=\"var(--w-ink,#e8eef9)\">Q3</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "orthogonal-elbow-connector",
    "connector-crossing-bridge",
    "connector-fan-attach",
    "bezier-connector-tangent"
   ]
  },
  {
   "id": "bezier-connector-tangent",
   "num": "W-327",
   "name": "Tangent-aligned Bezier Connector",
   "nameJa": "向きに合わせる曲線コネクタ",
   "category": "svgfx",
   "description": "2つの箱を結ぶ曲線の制御点を、それぞれのノードが向いている方向(接線)に沿わせて置く技法。始点では「その方向に伸びる仮想の取っ手」の先を制御点1、終点では逆向きに同じだけ伸ばした先を制御点2にする。両端が水平方向を向いていれば、制御点のyを端点と揃えるだけでねじれのないなめらかなS字曲線になる。",
   "useCase": "高さや列がそろっていない2つの箱を、角が立たないなめらかな曲線でつなぎたいとき、フローチャートの分岐やロードマップの合流線に使う。",
   "code": "// p0/p1: [x,y]、t0/t1: 各点でカーブが向く方向の単位ベクトル、d: 取っ手の長さ\nfunction tangentBezier(p0, t0, p1, t1, d = 40) {\n  const c1 = [p0[0] + t0[0] * d, p0[1] + t0[1] * d];\n  const c2 = [p1[0] - t1[0] * d, p1[1] - t1[1] * d];\n  return `M${p0} C${c1} ${c2} ${p1}`;\n}\n// tangentBezier([60,110], [1,0], [180,35], [1,0], 40)\n// => \"M60,110 C100,110 140,35 180,35\"",
   "tags": [
    "SVG",
    "図解",
    "コネクタ",
    "ベジェ",
    "なめらか"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"始点終点の向きに制御点を合わせる曲線コネクタのデモ\"><style>.bct-dot{animation:bct-move 4s linear infinite}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"20\" y=\"95\" width=\"40\" height=\"30\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".22\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.5\"/><text x=\"40\" y=\"114\" text-anchor=\"middle\" font-size=\"11\" fill=\"var(--w-ink,#e8eef9)\" font-family=\"ui-sans-serif,system-ui,sans-serif\">A</text><rect x=\"180\" y=\"20\" width=\"40\" height=\"30\" rx=\"6\" fill=\"var(--w-accent,#5ad2d9)\" opacity=\".2\" stroke=\"var(--w-accent,#5ad2d9)\" stroke-width=\"1.5\"/><text x=\"200\" y=\"39\" text-anchor=\"middle\" font-size=\"11\" fill=\"var(--w-ink,#e8eef9)\" font-family=\"ui-sans-serif,system-ui,sans-serif\">B</text><path id=\"bct-path\" d=\"M60,110 C100,110 140,35 180,35\" fill=\"none\" stroke=\"var(--w-accent,#5ad2d9)\" stroke-width=\"3\" stroke-linecap=\"round\"/><circle r=\"4\" fill=\"var(--w-amber,#ffc857)\" class=\"bct-dot\"><animateMotion dur=\"4s\" repeatCount=\"indefinite\"><mpath href=\"#bct-path\"/></animateMotion></circle></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "orthogonal-elbow-connector",
    "connector-crossing-bridge",
    "connector-fan-attach",
    "inline-label-on-line"
   ]
  },
  {
   "id": "sketchy-outline-filter",
   "num": "W-328",
   "name": "Sketchy Diagram Outline",
   "nameJa": "手描き風の図解輪郭",
   "category": "svgfx",
   "description": "feTurbulenceで作ったフラクタルノイズをfeDisplacementMapで図形の輪郭線だけに適用し、直線をわずかにガタつかせて手描き風にする技法。既存の「ノイズのゆらぎ(feTurbulence)」「変位マップ(feDisplacementMap)」は値を連続アニメーションさせて水面や液体のような有機的な動きを作るのに対し、この技法はseedとbaseFrequencyを固定した1回きりの静止した歪みを箱や線の輪郭だけに適用し、文字ラベルはフィルターの外に置いて可読性を保つ。用途がアニメーション演出ではなく図解の質感付けである点で明確に異なる。",
   "useCase": "ラフスケッチ風・ホワイトボード風のトンマナで説明図やフローチャートを作りたいとき、かっちりしすぎた印象を和らげたいときに使う。",
   "code": "<filter id=\"rough\">\n  <feTurbulence type=\"fractalNoise\" baseFrequency=\"0.045\" numOctaves=\"2\" seed=\"7\" result=\"noise\"/>\n  <feDisplacementMap in=\"SourceGraphic\" in2=\"noise\" scale=\"4\"/>\n</filter>\n<!-- 図形の輪郭だけをこのフィルターで包み、テキストは外に置いて可読性を保つ -->\n<g filter=\"url(#rough)\"><rect .../><line .../></g>\n<text ...>A</text>",
   "tags": [
    "SVG",
    "フィルター",
    "手描き風",
    "図解",
    "質感"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"図解の輪郭だけを手描き風に歪ませるデモ\"><style>.sof-link{animation:sof-pulse 4s ease-in-out infinite}@keyframes sof-pulse{0%,100%{stroke-width:2.5}50%{stroke-width:4}}</style><defs><filter id=\"sof-rough\" x=\"-15%\" y=\"-15%\" width=\"130%\" height=\"130%\"><feTurbulence type=\"fractalNoise\" baseFrequency=\"0.045\" numOctaves=\"2\" seed=\"7\" result=\"sof-noise\"/><feDisplacementMap in=\"SourceGraphic\" in2=\"sof-noise\" scale=\"4\" xChannelSelector=\"R\" yChannelSelector=\"G\"/></filter></defs><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g filter=\"url(#sof-rough)\"><rect x=\"30\" y=\"45\" width=\"60\" height=\"50\" rx=\"6\" fill=\"none\" stroke=\"var(--w-accent,#5ad2d9)\" stroke-width=\"3\"/><rect x=\"150\" y=\"45\" width=\"60\" height=\"50\" rx=\"6\" fill=\"none\" stroke=\"var(--w-accent,#5ad2d9)\" stroke-width=\"3\"/><line class=\"sof-link\" x1=\"90\" y1=\"70\" x2=\"150\" y2=\"70\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"2.5\"/></g><text x=\"60\" y=\"75\" text-anchor=\"middle\" font-size=\"12\" fill=\"var(--w-ink,#e8eef9)\" font-family=\"ui-sans-serif,system-ui,sans-serif\">A</text><text x=\"180\" y=\"75\" text-anchor=\"middle\" font-size=\"12\" fill=\"var(--w-ink,#e8eef9)\" font-family=\"ui-sans-serif,system-ui,sans-serif\">B</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "fe-diffuselighting-emboss",
    "grain-noise",
    "fe-colormatrix-huerotate",
    "fe-componenttransfer-posterize"
   ]
  },
  {
   "id": "canvas-getimagedata",
   "num": "W-329",
   "name": "Canvas getImageData / putImageData",
   "nameJa": "ピクセル単位で読み書きする（getImageData）",
   "category": "media",
   "description": "getImageDataは指定範囲の色情報をRGBAの数値配列（ImageData）として取得し、putImageDataは加工したその配列をcanvasへ書き戻す。1ピクセルごとに明るさを反転したりモザイクをかけたりと、CSSフィルターでは表現しきれない自由な画素処理ができる代わりに、範囲が広いと計算コストが高くなる。",
   "useCase": "アップロードされた画像に独自のモザイク・色調変換・簡易的な顔ぼかしなどをブラウザだけで施したいときに使う。",
   "code": "const img = ctx.getImageData(0, 0, w, h);\nconst d = img.data;\nfor (let i = 0; i < d.length; i += 4) {\n  const v = 255 - d[i];      // R反転\n  d[i] = v; d[i+1] = v; d[i+2] = v;\n}\nctx.putImageData(img, 0, 0);",
   "tags": [
    "Canvas",
    "JavaScript",
    "ピクセル",
    "画像処理"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"getImageDataでピクセルを操作するデモ\"><style>.cvgid-p{animation:cvgid-inv 4.5s steps(1) infinite}@keyframes cvgid-inv{0%,45%{fill:var(--w-accent,#8fe3d0)}50%,95%{fill:var(--w-amber,#ffc857)}100%{fill:var(--w-accent,#8fe3d0)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g><rect class=\"cvgid-p\" x=\"64\" y=\"32\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.00s\"/><rect class=\"cvgid-p\" x=\"84\" y=\"32\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.12s\"/><rect class=\"cvgid-p\" x=\"104\" y=\"32\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.24s\"/><rect class=\"cvgid-p\" x=\"124\" y=\"32\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.36s\"/><rect class=\"cvgid-p\" x=\"144\" y=\"32\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.48s\"/><rect class=\"cvgid-p\" x=\"164\" y=\"32\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.60s\"/><rect class=\"cvgid-p\" x=\"64\" y=\"52\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.12s\"/><rect class=\"cvgid-p\" x=\"84\" y=\"52\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.24s\"/><rect class=\"cvgid-p\" x=\"104\" y=\"52\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.36s\"/><rect class=\"cvgid-p\" x=\"124\" y=\"52\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.48s\"/><rect class=\"cvgid-p\" x=\"144\" y=\"52\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.60s\"/><rect class=\"cvgid-p\" x=\"164\" y=\"52\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.72s\"/><rect class=\"cvgid-p\" x=\"64\" y=\"72\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.24s\"/><rect class=\"cvgid-p\" x=\"84\" y=\"72\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.36s\"/><rect class=\"cvgid-p\" x=\"104\" y=\"72\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.48s\"/><rect class=\"cvgid-p\" x=\"124\" y=\"72\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.60s\"/><rect class=\"cvgid-p\" x=\"144\" y=\"72\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.72s\"/><rect class=\"cvgid-p\" x=\"164\" y=\"72\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.84s\"/><rect class=\"cvgid-p\" x=\"64\" y=\"92\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.36s\"/><rect class=\"cvgid-p\" x=\"84\" y=\"92\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.48s\"/><rect class=\"cvgid-p\" x=\"104\" y=\"92\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.60s\"/><rect class=\"cvgid-p\" x=\"124\" y=\"92\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.72s\"/><rect class=\"cvgid-p\" x=\"144\" y=\"92\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.84s\"/><rect class=\"cvgid-p\" x=\"164\" y=\"92\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.96s\"/><rect class=\"cvgid-p\" x=\"64\" y=\"112\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.48s\"/><rect class=\"cvgid-p\" x=\"84\" y=\"112\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.60s\"/><rect class=\"cvgid-p\" x=\"104\" y=\"112\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.72s\"/><rect class=\"cvgid-p\" x=\"124\" y=\"112\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.84s\"/><rect class=\"cvgid-p\" x=\"144\" y=\"112\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.96s\"/><rect class=\"cvgid-p\" x=\"164\" y=\"112\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:1.08s\"/><rect class=\"cvgid-p\" x=\"64\" y=\"132\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.60s\"/><rect class=\"cvgid-p\" x=\"84\" y=\"132\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.72s\"/><rect class=\"cvgid-p\" x=\"104\" y=\"132\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.84s\"/><rect class=\"cvgid-p\" x=\"124\" y=\"132\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:0.96s\"/><rect class=\"cvgid-p\" x=\"144\" y=\"132\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:1.08s\"/><rect class=\"cvgid-p\" x=\"164\" y=\"132\" width=\"16\" height=\"16\" rx=\"2\" fill=\"var(--w-accent,#8fe3d0)\" style=\"animation-delay:1.20s\"/></g></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "canvas-ctx-filter",
    "canvas-capture-stream",
    "canvas-measuretext",
    "canvas-path2d"
   ]
  },
  {
   "id": "canvas-capture-stream",
   "num": "W-330",
   "name": "Canvas captureStream()",
   "nameJa": "Canvasを動画ストリーム化する（captureStream）",
   "category": "media",
   "description": "canvas.captureStream(fps)は、canvasに描画され続けている内容をリアルタイムのMediaStream（video/audioなどの時系列データを表す入れ物）として取り出すメソッド。取得したストリームはMediaRecorderで録画してファイル化したり、WebRTCで別の相手に配信したりできる。",
   "useCase": "canvasで作ったグラフや生成アートのアニメーションを、そのままWebM動画として書き出したり配信したりしたいときに使う。",
   "code": "const stream = canvas.captureStream(30); // 30fps\nconst rec = new MediaRecorder(stream, { mimeType: 'video/webm' });\nconst chunks = [];\nrec.ondataavailable = e => chunks.push(e.data);\nrec.onstop = () => {\n  const blob = new Blob(chunks, { type: 'video/webm' });\n  // blobをダウンロードリンク等に使う\n};\nrec.start();",
   "tags": [
    "Canvas",
    "JavaScript",
    "MediaStream",
    "録画",
    "配信"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"captureStreamで動画化するデモ\"><style>.cvcap-dot{animation:cvcap-flow 3.6s linear infinite}@keyframes cvcap-flow{0%{transform:translateX(0);opacity:0}15%{opacity:1}85%{opacity:1}100%{transform:translateX(96px);opacity:0}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><rect x=\"30\" y=\"48\" width=\"66\" height=\"54\" rx=\"6\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".18\" stroke=\"var(--w-accent,#8fe3d0)\"/><text x=\"63\" y=\"79\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"16\" fill=\"var(--w-accent,#8fe3d0)\">▶</text><circle class=\"cvcap-dot\" cx=\"104\" cy=\"75\" r=\"4\" fill=\"var(--w-amber,#ffc857)\"/><path d=\"M100 75h96\" stroke=\"var(--w-sub,#a7b4cd)\" stroke-width=\"1.4\" stroke-dasharray=\"4 4\" opacity=\".5\"/><rect x=\"150\" y=\"52\" width=\"60\" height=\"46\" rx=\"6\" fill=\"none\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"2\"/><path d=\"M158 60l44 30M202 60l-44 30\" stroke=\"var(--w-amber,#ffc857)\" stroke-width=\"1\" opacity=\".4\"/><text x=\"180\" y=\"110\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"8\" fill=\"var(--w-sub,#a7b4cd)\">MediaStream</text></svg>",
   "useFor": [
    "lp",
    "site"
   ],
   "weight": "脇役",
   "relatedIds": [
    "canvas-getimagedata",
    "canvas-ctx-filter",
    "canvas-measuretext",
    "canvas-path2d"
   ]
  },
  {
   "id": "lottie-dotlottie",
   "num": "W-331",
   "name": "Lottie / dotLottie",
   "nameJa": "Lottie / dotLottieでベクターアニメを埋め込む",
   "category": "media",
   "description": "After Effectsで作ったアニメーションをBodymovinプラグインでベクター情報のJSON書き出しし、lottie-webやdotlottie-wcなどのJSライブラリでCanvas/SVGへ再生する仕組み。dotLottieはそのJSONと画像・音声などの素材を1つの.lottieファイル（ZIP）にまとめた配布用フォーマットで、読み込みリクエスト数を減らせる。動画ファイルと違い、拡大してもベクターなので滲まず、色をJS側から差し替えることもできる。",
   "useCase": "ローディングアイコンやマイクロインタラクションを、mp4やGIFより軽量かつ高精細なベクターアニメとして再生したいときに使う。",
   "code": "<!-- dotlottie-wc（Web Components版プレーヤー）を読み込み済みの前提 -->\n<dotlottie-wc\n  src=\"loading.lottie\"\n  autoplay\n  loop\n  style=\"width:120px;height:120px\">\n</dotlottie-wc>",
   "tags": [
    "Lottie",
    "dotLottie",
    "アニメーション",
    "ベクター"
   ],
   "support": "広く対応",
   "svg": "<svg viewBox=\"0 0 240 150\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" aria-label=\"Lottie / dotLottieのデモ\"><style>.lotti-p1,.lotti-p2,.lotti-p3{animation:lotti-bounce 3.6s ease-in-out infinite}.lotti-p2{animation-delay:.15s}.lotti-p3{animation-delay:.3s}@keyframes lotti-bounce{0%,20%,50%,100%{transform:translateY(0)}35%{transform:translateY(-22px)}}</style><rect width=\"240\" height=\"150\" rx=\"10\" fill=\"var(--w-bg,#101830)\"/><g fill=\"var(--w-accent,#8fe3d0)\"><circle class=\"lotti-p1\" cx=\"90\" cy=\"92\" r=\"10\"/><circle class=\"lotti-p2\" cx=\"120\" cy=\"92\" r=\"10\"/><circle class=\"lotti-p3\" cx=\"150\" cy=\"92\" r=\"10\"/></g><rect x=\"70\" y=\"112\" width=\"100\" height=\"4\" rx=\"2\" fill=\"var(--w-sub,#a7b4cd)\" opacity=\".4\"/><text x=\"120\" y=\"34\" text-anchor=\"middle\" font-family=\"ui-monospace,monospace\" font-size=\"9\" fill=\"var(--w-sub,#a7b4cd)\">.lottie (JSON + assets)</text></svg>",
   "useFor": [
    "slide",
    "lp",
    "site"
   ],
   "weight": "主役",
   "relatedIds": [
    "css-registerproperty-js",
    "ruby-heading-reveal",
    "smil-animate-basic",
    "smil-animatemotion-mpath"
   ]
  }
 ],
 "tones": [
  {
   "id": "quiet-luxury",
   "name": "静かな高級感",
   "summary": "士業・不動産・ハイエンド商材。彩度を抑え、余白を広く取って信頼感を出す",
   "mood": [
    "高級感",
    "落ち着き",
    "フォーマル"
   ],
   "color": {
    "light": {
     "bg": "#fdfdfc",
     "surface": "#f2f0e7",
     "ink": "#3b352b",
     "sub": "#71624b",
     "line": "#d8d0bf",
     "accent": "#978365",
     "accent2": "#1c2024",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "dark": null,
    "contrast": {
     "inkOnBg": 11.93,
     "subOnBg": 5.81
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Old Mincho",
     "en": "Playfair Display"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "composed"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "32px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2,0,0.38,0.9)",
     "provenance": "verified",
     "source": "IBM Carbon slow-01 + standard.productive"
    }
   },
   "provenance": {
    "type": "derived",
    "source": "Radix Colors (gold, slate)",
    "license": "MIT"
   },
   "fontClass": "明朝系",
   "shapeClass": "やわらか"
  },
  {
   "id": "hard-tech",
   "name": "硬派なテック",
   "summary": "開発者向け・SaaS・インフラ。直角と無駄のない動きで、機能を前に出す",
   "mood": [
    "硬派",
    "無駄がない",
    "夜"
   ],
   "color": {
    "light": null,
    "dark": {
     "bg": "#161616",
     "surface": "#262626",
     "ink": "#f4f4f4",
     "sub": "#a8a8a8",
     "line": "#525252",
     "accent": "#0f62fe",
     "accent2": "#78a9ff",
     "onAccent": "#ffffff",
     "onAccent2": "#0b0d10"
    },
    "contrast": {
     "inkOnBg": 16.45,
     "subOnBg": 7.61
    }
   },
   "font": {
    "heading": {
     "ja": "IBM Plex Sans JP",
     "en": "IBM Plex Sans"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "JetBrains Mono"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（角丸トークンを持たない＝直角が様式）"
    },
    "shadow": {
     "value": "none",
     "provenance": "verified",
     "source": "IBM Carbon（影トークンなし＝フラット）"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2,0,0.38,0.9)",
     "provenance": "verified",
     "source": "IBM Carbon fast-02 + standard.productive"
    }
   },
   "provenance": {
    "type": "derived",
    "source": "IBM Carbon (gray100, blue)",
    "license": "Apache-2.0"
   },
   "fontClass": "ゴシック系",
   "shapeClass": "角ばった"
  },
  {
   "id": "pop-energetic",
   "name": "元気なポップ",
   "summary": "BtoC・若年層・キャンペーン。丸みと強い影で、明るく前に出る",
   "mood": [
    "元気",
    "明るい",
    "目を引く"
   ],
   "color": {
    "light": {
     "bg": "#ffffff",
     "surface": "#fff1f2",
     "ink": "#0f172a",
     "sub": "#64748b",
     "line": "#fecdd3",
     "accent": "#f43f5e",
     "accent2": "#fbbf24",
     "onAccent": "#0b0d10",
     "onAccent2": "#0b0d10"
    },
    "dark": null,
    "contrast": {
     "inkOnBg": 17.85,
     "subOnBg": 4.76
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Maru Gothic",
     "en": "Poppins"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "16px",
     "provenance": "composed"
    },
    "shadow": {
     "value": "0px 8px 16px -4px rgba(244,63,94,0.25)",
     "provenance": "composed"
    },
    "spacing": {
     "value": "16px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "300ms",
     "easing": "cubic-bezier(0.3,0.8,0.6,1)",
     "provenance": "verified",
     "source": "GitHub Primer 推奨既定easing"
    }
   },
   "provenance": {
    "type": "derived",
    "source": "Tailwind CSS (rose, amber, slate)",
    "license": "MIT"
   },
   "fontClass": "丸ゴシック系",
   "shapeClass": "丸みのある"
  },
  {
   "id": "corporate-trust",
   "name": "信頼の企業色",
   "summary": "BtoB・堅実な提案資料。奇をてらわず、読みやすさと一貫性を優先する",
   "mood": [
    "信頼",
    "堅実",
    "定番"
   ],
   "color": {
    "light": {
     "bg": "#fbfdff",
     "surface": "#f4faff",
     "ink": "#1c2024",
     "sub": "#60646c",
     "line": "#acd8fc",
     "accent": "#0090ff",
     "accent2": "#8b8d98",
     "onAccent": "#0b0d10",
     "onAccent2": "#0b0d10"
    },
    "dark": {
     "bg": "#0d1520",
     "surface": "#111927",
     "ink": "#edeef0",
     "sub": "#b0b4ba",
     "line": "#104d87",
     "accent": "#3b9eff",
     "accent2": "#696e77",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 16.07,
     "subOnBg": 5.82,
     "darkInkOnBg": 15.79,
     "darkSubOnBg": 8.8
    }
   },
   "font": {
    "heading": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "6px",
     "provenance": "verified",
     "source": "Atlassian radius.medium"
    },
    "shadow": {
     "value": "0px 1px 1px #1E1F2140, 0px 0px 1px #1E1F214F",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "16px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "200ms",
     "easing": "cubic-bezier(0.4,1,0.6,1)",
     "provenance": "verified",
     "source": "Atlassian medium + out.practical"
    }
   },
   "provenance": {
    "type": "derived",
    "source": "Radix Colors (blue, slate)",
    "license": "MIT"
   },
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか"
  },
  {
   "id": "warm-natural",
   "name": "温かいナチュラル",
   "summary": "食・オーガニック・雑貨。生成りの背景と緑で、素材の手ざわりを出す",
   "mood": [
    "温かい",
    "自然",
    "やわらか"
   ],
   "color": {
    "light": {
     "bg": "#fffbeb",
     "surface": "#ecfdf5",
     "ink": "#064e3b",
     "sub": "#92400e",
     "line": "#fde68a",
     "accent": "#059669",
     "accent2": "#f59e0b",
     "onAccent": "#0b0d10",
     "onAccent2": "#0b0d10"
    },
    "dark": null,
    "contrast": {
     "inkOnBg": 9.37,
     "subOnBg": 6.84
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Kaku Gothic New",
     "en": "Montserrat"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "composed"
    },
    "shadow": {
     "value": "0px 1px 0px 0px rgba(26,26,26,0.07)",
     "provenance": "verified",
     "source": "Shopify Polaris shadow-100"
    },
    "spacing": {
     "value": "24px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "300ms",
     "easing": "ease-out",
     "provenance": "composed"
    }
   },
   "provenance": {
    "type": "derived",
    "source": "Tailwind CSS (amber, emerald)",
    "license": "MIT"
   },
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか"
  },
  {
   "id": "minimal-mono",
   "name": "ミニマル・モノトーン",
   "summary": "ポートフォリオ・作品を主役にする。色を引き、影も使わず、線と余白で組む",
   "mood": [
    "ミニマル",
    "静か",
    "作品が主役"
   ],
   "color": {
    "light": {
     "bg": "#ffffff",
     "surface": "#f8f9fa",
     "ink": "#212529",
     "sub": "#495057",
     "line": "#dee2e6",
     "accent": "#212529",
     "accent2": "#868e96",
     "onAccent": "#ffffff",
     "onAccent2": "#0b0d10"
    },
    "dark": null,
    "contrast": {
     "inkOnBg": 15.43,
     "subOnBg": 8.18
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS 1",
     "en": "Work Sans"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "4px",
     "provenance": "composed"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "24px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "200ms",
     "easing": "cubic-bezier(0.4,0,0.2,1)",
     "provenance": "composed"
    }
   },
   "provenance": {
    "type": "derived",
    "source": "Open Color (gray)",
    "license": "MIT"
   },
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか"
  },
  {
   "id": "dark-modern",
   "name": "ダーク基調のモダン",
   "summary": "プロダクト紹介・夜に見る画面。暗い面の上で、青と水色を光らせる",
   "mood": [
    "モダン",
    "夜",
    "洗練"
   ],
   "color": {
    "light": null,
    "dark": {
     "bg": "#111113",
     "surface": "#18191b",
     "ink": "#edeef0",
     "sub": "#b0b4ba",
     "line": "#363a3f",
     "accent": "#3e63dd",
     "accent2": "#00a2c7",
     "onAccent": "#ffffff",
     "onAccent2": "#0b0d10"
    },
    "contrast": {
     "inkOnBg": 16.25,
     "subOnBg": 9.06
    }
   },
   "font": {
    "heading": {
     "ja": "Murecho",
     "en": "Space Grotesk"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "composed"
    },
    "shadow": {
     "value": "0px 8px 12px rgba(0,0,0,0.4)",
     "provenance": "composed"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "250ms",
     "easing": "cubic-bezier(0.2,0,0,1)",
     "provenance": "verified",
     "source": "Material Design 3 standard"
    }
   },
   "provenance": {
    "type": "derived",
    "source": "Radix Colors dark (slate, indigo, cyan)",
    "license": "MIT"
   },
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか"
  },
  {
   "id": "medical-clean",
   "name": "医療・クリーン",
   "summary": "医療/ヘルスケア。水色と白で清潔感を出し、判別性の高い書体を使う",
   "mood": [
    "清潔",
    "安心",
    "誠実"
   ],
   "color": {
    "light": {
     "bg": "#fafdfe",
     "surface": "#f2fafb",
     "ink": "#1c2024",
     "sub": "#60646c",
     "line": "#9ddde7",
     "accent": "#00a2c7",
     "accent2": "#29a383",
     "onAccent": "#0b0d10",
     "onAccent2": "#0b0d10"
    },
    "dark": null,
    "contrast": {
     "inkOnBg": 16.03,
     "subOnBg": 5.81
    }
   },
   "font": {
    "heading": {
     "ja": "BIZ UDGothic",
     "en": "Inter"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "composed"
    },
    "shadow": {
     "value": "0px 1px 0px 0px rgba(26,26,26,0.07)",
     "provenance": "verified",
     "source": "Shopify Polaris shadow-100"
    },
    "spacing": {
     "value": "16px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "200ms",
     "easing": "cubic-bezier(0.2,0,0,1)",
     "provenance": "verified",
     "source": "Material Design 3 standard"
    }
   },
   "provenance": {
    "type": "derived",
    "source": "Radix Colors (cyan, jade)",
    "license": "MIT"
   },
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか"
  },
  {
   "id": "education-friendly",
   "name": "教育・親しみやすい",
   "summary": "講座・スクール・初心者向け。丸ゴシックと空色で、身構えさせない",
   "mood": [
    "親しみ",
    "やさしい",
    "わかりやすい"
   ],
   "color": {
    "light": {
     "bg": "#f0f9ff",
     "surface": "#ffffff",
     "ink": "#1e293b",
     "sub": "#475569",
     "line": "#bae6fd",
     "accent": "#0ea5e9",
     "accent2": "#f59e0b",
     "onAccent": "#0b0d10",
     "onAccent2": "#0b0d10"
    },
    "dark": null,
    "contrast": {
     "inkOnBg": 13.72,
     "subOnBg": 7.11
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS Rounded 1c",
     "en": "DM Sans"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "16px",
     "provenance": "composed"
    },
    "shadow": {
     "value": "0px 4px 8px rgba(14,165,233,0.15)",
     "provenance": "composed"
    },
    "spacing": {
     "value": "16px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "300ms",
     "easing": "cubic-bezier(0.3,0.8,0.6,1)",
     "provenance": "verified",
     "source": "GitHub Primer 推奨既定easing"
    }
   },
   "provenance": {
    "type": "derived",
    "source": "Tailwind CSS (sky, slate, amber)",
    "license": "MIT"
   },
   "fontClass": "丸ゴシック系",
   "shapeClass": "丸みのある"
  },
  {
   "id": "finance-data",
   "name": "金融・数字を見せる",
   "summary": "実績やデータが主役。余白を詰めて情報密度を上げ、数字は等幅で揃える",
   "mood": [
    "精密",
    "説得力",
    "密度が高い"
   ],
   "color": {
    "light": {
     "bg": "#fcfcfd",
     "surface": "#f9f9fb",
     "ink": "#1c2024",
     "sub": "#60646c",
     "line": "#d9d9e0",
     "accent": "#3e63dd",
     "accent2": "#29a383",
     "onAccent": "#ffffff",
     "onAccent2": "#0b0d10"
    },
    "dark": null,
    "contrast": {
     "inkOnBg": 15.98,
     "subOnBg": 5.79
    }
   },
   "font": {
    "heading": {
     "ja": "LINE Seed JP",
     "en": "Manrope"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "JetBrains Mono"
    }
   },
   "shape": {
    "radius": {
     "value": "6px",
     "provenance": "verified",
     "source": "Atlassian radius.medium"
    },
    "shadow": {
     "value": "0px 1px 1px #1E1F2140, 0px 0px 1px #1E1F214F",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "12px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-04"
    },
    "motion": {
     "duration": "150ms",
     "easing": "cubic-bezier(0.2,0,0.38,0.9)",
     "provenance": "verified",
     "source": "IBM Carbon moderate-01 + standard.productive"
    }
   },
   "provenance": {
    "type": "derived",
    "source": "Radix Colors (slate, indigo, jade)",
    "license": "MIT"
   },
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか"
  },
  {
   "id": "creative-bold",
   "name": "クリエイティブ・大胆",
   "summary": "制作会社・イベント。強い影と大きな角丸で、型にはまらない印象を作る",
   "mood": [
    "大胆",
    "個性的",
    "ダイナミック"
   ],
   "color": {
    "light": {
     "bg": "#ffffff",
     "surface": "#f5f3ff",
     "ink": "#2e1065",
     "sub": "#475569",
     "line": "#ddd6fe",
     "accent": "#7c3aed",
     "accent2": "#f43f5e",
     "onAccent": "#ffffff",
     "onAccent2": "#0b0d10"
    },
    "dark": null,
    "contrast": {
     "inkOnBg": 15.24,
     "subOnBg": 7.58
    }
   },
   "font": {
    "heading": {
     "ja": "Murecho",
     "en": "Instrument Serif"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "note": "和文ゴシック×欧文セリフという定石外の組み合わせ。型を外す印象を狙って意図的に選んでいる",
   "shape": {
    "radius": {
     "value": "24px",
     "provenance": "composed"
    },
    "shadow": {
     "value": "0px 20px 20px -8px rgba(26,26,26,0.28)",
     "provenance": "verified",
     "source": "Shopify Polaris shadow-600"
    },
    "spacing": {
     "value": "24px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "350ms",
     "easing": "cubic-bezier(0.4,0.14,0.3,1)",
     "provenance": "verified",
     "source": "Material Design 3 expressive系"
    }
   },
   "provenance": {
    "type": "derived",
    "source": "Tailwind CSS (violet, rose)",
    "license": "MIT"
   },
   "fontClass": "ゴシック系",
   "shapeClass": "丸みのある"
  },
  {
   "id": "japanese-modern",
   "name": "和モダン",
   "summary": "和風だが古臭くない。角をほぼ立て、影を使わず、間で見せる",
   "mood": [
    "和",
    "静けさ",
    "余白"
   ],
   "color": {
    "light": {
     "bg": "#f7f3ea",
     "surface": "#efe8d8",
     "ink": "#2b2622",
     "sub": "#6b6255",
     "line": "#d8cdb8",
     "accent": "#a6403a",
     "accent2": "#3c5a6e",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": null,
    "contrast": {
     "inkOnBg": 13.52,
     "subOnBg": 5.41
    }
   },
   "font": {
    "heading": {
     "ja": "Shippori Mincho",
     "en": "Playfair Display"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "2px",
     "provenance": "composed"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "32px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0,0,0.38,0.9)",
     "provenance": "verified",
     "source": "Material Design 3 entrance系"
    }
   },
   "provenance": {
    "type": "original",
    "source": "和紙・墨・藍・朱など日本の伝統色の傾向を参考に独自構成",
    "license": null
   },
   "fontClass": "明朝系",
   "shapeClass": "角ばった"
  },
  {
   "id": "retro-nostalgic",
   "name": "レトロ・ノスタルジック",
   "summary": "昭和や90年代の空気。日焼けした紙の色と、印刷物のようなずれた影",
   "mood": [
    "レトロ",
    "懐かしい",
    "紙"
   ],
   "color": {
    "light": {
     "bg": "#f4ecd8",
     "surface": "#ecdfc0",
     "ink": "#3b2a20",
     "sub": "#6b5541",
     "line": "#d8c49a",
     "accent": "#c9762c",
     "accent2": "#3e7c7c",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "dark": null,
    "contrast": {
     "inkOnBg": 11.6,
     "subOnBg": 5.94
    }
   },
   "font": {
    "heading": {
     "ja": "Sawarabi Gothic",
     "en": "Montserrat"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "4px",
     "provenance": "composed"
    },
    "shadow": {
     "value": "2px 2px 0px rgba(59,42,32,0.3)",
     "provenance": "composed"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "200ms",
     "easing": "ease",
     "provenance": "composed"
    }
   },
   "provenance": {
    "type": "original",
    "source": null,
    "license": null
   },
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか"
  },
  {
   "id": "cyber-neon",
   "name": "サイバー・ネオン",
   "summary": "ゲーム・AI・近未来。暗闇に光る発光色。角は立て、動きは速く",
   "mood": [
    "近未来",
    "発光",
    "夜"
   ],
   "color": {
    "light": null,
    "dark": {
     "bg": "#0b0b12",
     "surface": "#14141f",
     "ink": "#eef0ff",
     "sub": "#9a9ecb",
     "line": "#2a2a40",
     "accent": "#00e5ff",
     "accent2": "#ff2fd0",
     "onAccent": "#0b0d10",
     "onAccent2": "#0b0d10"
    },
    "contrast": {
     "inkOnBg": 17.32,
     "subOnBg": 7.59
    }
   },
   "font": {
    "heading": {
     "ja": "Kosugi",
     "en": "JetBrains Mono"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "JetBrains Mono"
    }
   },
   "shape": {
    "radius": {
     "value": "4px",
     "provenance": "composed"
    },
    "shadow": {
     "value": "0px 0px 16px rgba(0,229,255,0.5)",
     "provenance": "composed"
    },
    "spacing": {
     "value": "16px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "150ms",
     "easing": "cubic-bezier(0.2,0,0.38,0.9)",
     "provenance": "verified",
     "source": "IBM Carbon moderate-01 + standard.productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": null,
    "license": null
   },
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか"
  },
  {
   "id": "handwritten-intimate",
   "name": "手描き・親密",
   "summary": "個人発信・noteのような温度感。ペン書き風の見出しと、生成りの背景",
   "mood": [
    "親密",
    "手書き",
    "温度がある"
   ],
   "color": {
    "light": {
     "bg": "#fffbf5",
     "surface": "#fff3e9",
     "ink": "#4a3f35",
     "sub": "#6e5f52",
     "line": "#e8d9c8",
     "accent": "#e8896b",
     "accent2": "#7fa88a",
     "onAccent": "#0b0d10",
     "onAccent2": "#0b0d10"
    },
    "dark": null,
    "contrast": {
     "inkOnBg": 9.92,
     "subOnBg": 5.95
    }
   },
   "font": {
    "heading": {
     "ja": "Klee One",
     "en": "DM Sans"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "composed"
    },
    "shadow": {
     "value": "0px 2px 4px rgba(74,63,53,0.12)",
     "provenance": "composed"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "300ms",
     "easing": "ease-out",
     "provenance": "composed"
    }
   },
   "provenance": {
    "type": "original",
    "source": null,
    "license": null
   },
   "fontClass": "手書き・筆",
   "shapeClass": "やわらか"
  },
  {
   "id": "law-firm",
   "name": "士業の重厚さ",
   "summary": "弁護士・税理士・司法書士。濃紺と余白で、軽く見せない",
   "mood": [
    "信頼",
    "重厚",
    "フォーマル"
   ],
   "fontClass": "明朝系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#f7fafe",
     "surface": "#eaeff4",
     "ink": "#2e343a",
     "sub": "#5d646c",
     "line": "#c5ccd3",
     "accent": "#4f6483",
     "accent2": "#5f646a",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#111315",
     "surface": "#1a1d21",
     "ink": "#c9d1d8",
     "sub": "#7b838b",
     "line": "#34393e",
     "accent": "#7e94b4",
     "accent2": "#70747b",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.02,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "BIZ UDPMincho",
     "en": "Libre Baskerville"
    },
    "body": {
     "ja": "BIZ UDPGothic",
     "en": "PT Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "3px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.small"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "300ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium2 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "real-estate",
   "name": "不動産の安心感",
   "summary": "住宅・仲介・管理。落ち着いた緑と広い余白で、暮らしの落ち着きを出す",
   "mood": [
    "安心",
    "落ち着き",
    "誠実"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#4b6d54",
     "accent2": "#3b6d6b",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#789b80",
     "accent2": "#4a7d7a",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Kaku Gothic Antique",
     "en": "Archivo"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Source Sans 3"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "medical-care",
   "name": "医療の清潔感",
   "summary": "病院・クリニック。白を基調に青緑を差して、清潔さと安心を両立する",
   "mood": [
    "清潔",
    "安心",
    "誠実"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#f5fbff",
     "surface": "#e8eff8",
     "ink": "#2b353e",
     "sub": "#586572",
     "line": "#c5d0dc",
     "accent": "#007471",
     "accent2": "#156c90",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#0f1317",
     "surface": "#181e23",
     "ink": "#c5d0dd",
     "sub": "#768390",
     "line": "#313a43",
     "accent": "#37a19e",
     "accent2": "#2b7ca1",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "BIZ UDPGothic",
     "en": "Public Sans"
    },
    "body": {
     "ja": "BIZ UDPGothic",
     "en": "Public Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "verified",
     "source": "Ant Design borderRadiusLG"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "250ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium1 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "dental",
   "name": "歯科の明るさ",
   "summary": "歯科医院。水色と丸みで、怖さを和らげて通いやすくする",
   "mood": [
    "清潔",
    "やさしい",
    "明るい"
   ],
   "fontClass": "丸ゴシック系",
   "shapeClass": "丸みのある",
   "color": {
    "light": {
     "bg": "#f5fbff",
     "surface": "#e8eff8",
     "ink": "#2b353e",
     "sub": "#586572",
     "line": "#c5d0dc",
     "accent": "#007180",
     "accent2": "#356697",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#0f1317",
     "surface": "#181e23",
     "ink": "#c5d0dd",
     "sub": "#768390",
     "line": "#313a43",
     "accent": "#399faf",
     "accent2": "#4677a9",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Maru Gothic",
     "en": "Quicksand"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Nunito"
    }
   },
   "shape": {
    "radius": {
     "value": "16px",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 borderRadius3XLarge"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow8"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "300ms",
     "easing": "cubic-bezier(0.08, 0.82, 0.17, 1)",
     "provenance": "verified",
     "source": "Ant Design motionEaseOutCirc"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "pharmacy",
   "name": "調剤薬局の実直さ",
   "summary": "薬局・ドラッグ。緑と大きめの文字で、間違いのない印象を作る",
   "mood": [
    "実直",
    "清潔",
    "読みやすい"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#397243",
     "accent2": "#804f7f",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#66a06e",
     "accent2": "#976395",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "BIZ UDPGothic",
     "en": "Public Sans"
    },
    "body": {
     "ja": "BIZ UDPGothic",
     "en": "Public Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "6px",
     "provenance": "verified",
     "source": "Ant Design borderRadius (seed)"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "12px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-04 (0.75rem)"
    },
    "motion": {
     "duration": "150ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.01 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "nursing-care",
   "name": "介護のあたたかさ",
   "summary": "介護・訪問看護。あたたかい橙と丸みで、人の手のぬくもりを出す",
   "mood": [
    "あたたかい",
    "やさしい",
    "安心"
   ],
   "fontClass": "丸ゴシック系",
   "shapeClass": "丸みのある",
   "color": {
    "light": {
     "bg": "#fff9f3",
     "surface": "#f5ede5",
     "ink": "#3c3228",
     "sub": "#6d6153",
     "line": "#d8cdc1",
     "accent": "#8e5130",
     "accent2": "#7a5f13",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#16120e",
     "surface": "#211c16",
     "ink": "#d9cdc1",
     "sub": "#8c8071",
     "line": "#3f372d",
     "accent": "#c58360",
     "accent2": "#8c7129",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.77
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Maru Gothic",
     "en": "Quicksand"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Nunito"
    }
   },
   "shape": {
    "radius": {
     "value": "16px",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 borderRadius3XLarge"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow8"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "300ms",
     "easing": "cubic-bezier(0.08, 0.82, 0.17, 1)",
     "provenance": "verified",
     "source": "Ant Design motionEaseOutCirc"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "school-edu",
   "name": "学校の健やかさ",
   "summary": "学校・教育機関。青と若草で、健やかさと前向きさを出す",
   "mood": [
    "健やか",
    "前向き",
    "誠実"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#f5fbff",
     "surface": "#e8eff8",
     "ink": "#2b353e",
     "sub": "#586572",
     "line": "#c5d0dc",
     "accent": "#006e8c",
     "accent2": "#894c70",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#0f1317",
     "surface": "#181e23",
     "ink": "#c5d0dd",
     "sub": "#768390",
     "line": "#313a43",
     "accent": "#459cbc",
     "accent2": "#a06085",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Kaku Gothic New",
     "en": "Inter"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "verified",
     "source": "Ant Design borderRadiusLG"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "250ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium1 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "cram-school",
   "name": "学習塾の勢い",
   "summary": "塾・予備校。強い赤と太い見出しで、合格へ向かう熱を出す",
   "mood": [
    "熱い",
    "勢い",
    "目を引く"
   ],
   "fontClass": "装飾系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fff9ef",
     "surface": "#f9ecdf",
     "ink": "#3f3120",
     "sub": "#735f49",
     "line": "#d9c8b5",
     "accent": "#a8372e",
     "accent2": "#007383",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#17110b",
     "surface": "#241b11",
     "ink": "#deccb7",
     "sub": "#927e67",
     "line": "#433626",
     "accent": "#e56e61",
     "accent2": "#008091",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.99,
     "subOnBg": 5.79
    }
   },
   "font": {
    "heading": {
     "ja": "Dela Gothic One",
     "en": "Anton"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Work Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "6px",
     "provenance": "verified",
     "source": "Ant Design borderRadius (seed)"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "12px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-04 (0.75rem)"
    },
    "motion": {
     "duration": "150ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.01 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "nursery",
   "name": "保育のやわらかさ",
   "summary": "保育園・幼稚園。パステルと丸い形で、幼い子にも怖くない画面にする",
   "mood": [
    "かわいい",
    "やわらかい",
    "安心"
   ],
   "fontClass": "装飾系",
   "shapeClass": "丸い",
   "color": {
    "light": {
     "bg": "#fff9f3",
     "surface": "#f5ede5",
     "ink": "#3c3228",
     "sub": "#6d6153",
     "line": "#d8cdc1",
     "accent": "#874c74",
     "accent2": "#706416",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#16120e",
     "surface": "#211c16",
     "ink": "#d9cdc1",
     "sub": "#8c8071",
     "line": "#3f372d",
     "accent": "#bd7ea8",
     "accent2": "#81752a",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.77
    }
   },
   "font": {
    "heading": {
     "ja": "Mochiy Pop One",
     "en": "Righteous"
    },
    "body": {
     "ja": "Zen Maru Gothic",
     "en": "Nunito"
    }
   },
   "shape": {
    "radius": {
     "value": "9999px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.full"
    },
    "shadow": {
     "value": "0 1px 2px -2px rgba(0,0,0,0.16), 0 3px 6px 0 rgba(0,0,0,0.12), 0 5px 12px 4px rgba(0,0,0,0.09)",
     "provenance": "verified",
     "source": "Ant Design boxShadowCard"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "260ms",
     "easing": "cubic-bezier(0.22, 1, 0.36, 1)",
     "provenance": "verified",
     "source": "Base Web easeDecelerate (easeOutQuintic)"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "university",
   "name": "大学の学術性",
   "summary": "大学・研究機関。えんじ色と明朝で、学問の重みを出す",
   "mood": [
    "学術的",
    "重厚",
    "伝統"
   ],
   "fontClass": "明朝系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#7f565b",
     "accent2": "#6a6161",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#b3868b",
     "accent2": "#7b7272",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Old Mincho",
     "en": "EB Garamond"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "240ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "finance-bank",
   "name": "金融の堅牢さ",
   "summary": "銀行・証券。深い藍と直角で、揺るがない印象を作る",
   "mood": [
    "堅牢",
    "信頼",
    "フォーマル"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#f7fafe",
     "surface": "#eaeff4",
     "ink": "#2e343a",
     "sub": "#5d646c",
     "line": "#c5ccd3",
     "accent": "#4c6582",
     "accent2": "#5e646a",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#111315",
     "surface": "#1a1d21",
     "ink": "#c9d1d8",
     "sub": "#7b838b",
     "line": "#34393e",
     "accent": "#7a95b3",
     "accent2": "#6f757b",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.02,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "IBM Plex Sans JP",
     "en": "IBM Plex Sans"
    },
    "body": {
     "ja": "IBM Plex Sans JP",
     "en": "JetBrains Mono"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "insurance",
   "name": "保険の安心",
   "summary": "保険・共済。青緑と広い行間で、話を聞いてもらう落ち着きを作る",
   "mood": [
    "安心",
    "誠実",
    "落ち着き"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#f7fafe",
     "surface": "#eaeff4",
     "ink": "#2e343a",
     "sub": "#5d646c",
     "line": "#c5ccd3",
     "accent": "#3c6e68",
     "accent2": "#3f6a7b",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#111315",
     "surface": "#1a1d21",
     "ink": "#c9d1d8",
     "sub": "#7b838b",
     "line": "#34393e",
     "accent": "#699b95",
     "accent2": "#4f7b8c",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.02,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Kaku Gothic Antique",
     "en": "Archivo"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Source Sans 3"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "accounting",
   "name": "会計の几帳面さ",
   "summary": "会計事務所・記帳代行。無彩色に近い画面と細かい余白で、数字を読ませる",
   "mood": [
    "几帳面",
    "実直",
    "静か"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#466880",
     "accent2": "#636363",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#7497b0",
     "accent2": "#757575",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "IBM Plex Sans JP",
     "en": "IBM Plex Sans"
    },
    "body": {
     "ja": "IBM Plex Sans JP",
     "en": "JetBrains Mono"
    }
   },
   "shape": {
    "radius": {
     "value": "6px",
     "provenance": "verified",
     "source": "Ant Design borderRadius (seed)"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "12px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-04 (0.75rem)"
    },
    "motion": {
     "duration": "150ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.01 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "investment",
   "name": "投資の緊張感",
   "summary": "投資・資産運用。暗い画面に金色を差して、扱う額の重さを出す",
   "mood": [
    "緊張感",
    "高級感",
    "夜"
   ],
   "fontClass": "明朝系",
   "shapeClass": "角ばった",
   "color": {
    "light": null,
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#a38f6c",
     "accent2": "#78736c",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12,
     "subOnBg": 4.81
    }
   },
   "font": {
    "heading": {
     "ja": "Shippori Mincho B1",
     "en": "Cormorant Garamond"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "saas-product",
   "name": "SaaSの明快さ",
   "summary": "BtoB SaaS・業務ツール。青と均等な余白で、機能が並んでも散らからない",
   "mood": [
    "明快",
    "現代的",
    "整然"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#f5fbff",
     "surface": "#e8eff8",
     "ink": "#2b353e",
     "sub": "#586572",
     "line": "#c5d0dc",
     "accent": "#456299",
     "accent2": "#6d5590",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#0f1317",
     "surface": "#181e23",
     "ink": "#c5d0dd",
     "sub": "#768390",
     "line": "#313a43",
     "accent": "#7292cd",
     "accent2": "#8169a5",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "Murecho",
     "en": "Manrope"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "DM Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "verified",
     "source": "Ant Design borderRadiusLG"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "250ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium1 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "dev-agency",
   "name": "受託開発の実装力",
   "summary": "受託開発・制作会社。等幅と直角で、手を動かす会社に見せる",
   "mood": [
    "硬派",
    "無駄がない",
    "技術"
   ],
   "fontClass": "等幅系",
   "shapeClass": "角ばった",
   "color": {
    "light": null,
    "dark": {
     "bg": "#0f1317",
     "surface": "#181e23",
     "ink": "#c5d0dd",
     "sub": "#768390",
     "line": "#313a43",
     "accent": "#36a1a6",
     "accent2": "#a86060",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.94,
     "subOnBg": 4.81
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS 1 Code",
     "en": "JetBrains Mono"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Fira Code"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "security",
   "name": "セキュリティの警戒",
   "summary": "情報セキュリティ。暗い画面と鋭い赤で、守りの緊張感を出す",
   "mood": [
    "緊張感",
    "硬派",
    "夜"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "角ばった",
   "color": {
    "light": null,
    "dark": {
     "bg": "#0d131a",
     "surface": "#151e27",
     "ink": "#bed2e6",
     "sub": "#6f849a",
     "line": "#2c3a49",
     "accent": "#e56d71",
     "accent2": "#876e6e",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.04,
     "subOnBg": 4.84
    }
   },
   "font": {
    "heading": {
     "ja": "IBM Plex Sans JP",
     "en": "IBM Plex Sans"
    },
    "body": {
     "ja": "IBM Plex Sans JP",
     "en": "JetBrains Mono"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "ai-data",
   "name": "AI・データの先進性",
   "summary": "AI・データ分析。紫と暗い画面で、計算が走っている感じを出す",
   "mood": [
    "先進的",
    "知的",
    "夜"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": null,
    "dark": {
     "bg": "#0d131a",
     "surface": "#151e27",
     "ink": "#bed2e6",
     "sub": "#6f849a",
     "line": "#2c3a49",
     "accent": "#9983ea",
     "accent2": "#ab54a1",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.04,
     "subOnBg": 4.84
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS 2",
     "en": "Poppins"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "DM Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "verified",
     "source": "Ant Design borderRadiusLG"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "250ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium1 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "telecom",
   "name": "通信の広がり",
   "summary": "通信・インフラ。青からシアンへの広がりで、つながる感じを出す",
   "mood": [
    "広がり",
    "現代的",
    "明快"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#f5fbff",
     "surface": "#e8eff8",
     "ink": "#2b353e",
     "sub": "#586572",
     "line": "#c5d0dc",
     "accent": "#007087",
     "accent2": "#406499",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#0f1317",
     "surface": "#181e23",
     "ink": "#c5d0dd",
     "sub": "#768390",
     "line": "#313a43",
     "accent": "#3f9eb7",
     "accent2": "#5176ac",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS 2",
     "en": "Poppins"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "DM Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "verified",
     "source": "Ant Design borderRadiusLG"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "250ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium1 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "manufacturing",
   "name": "製造業の実直さ",
   "summary": "メーカー・工場。灰と青で、誇張しない実直さを出す",
   "mood": [
    "実直",
    "堅牢",
    "無駄がない"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#42697d",
     "accent2": "#636363",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#7098ae",
     "accent2": "#757575",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS 1",
     "en": "Oswald"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Barlow"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "construction",
   "name": "建設の力強さ",
   "summary": "建設・土木。黄と黒で、現場の視認性をそのまま画面に持ち込む",
   "mood": [
    "力強い",
    "現場",
    "目を引く"
   ],
   "fontClass": "装飾系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fff9ef",
     "surface": "#f9ecdf",
     "ink": "#3f3120",
     "sub": "#735f49",
     "line": "#d9c8b5",
     "accent": "#8e5600",
     "accent2": "#6e614f",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#17110b",
     "surface": "#241b11",
     "ink": "#deccb7",
     "sub": "#927e67",
     "line": "#433626",
     "accent": "#c78400",
     "accent2": "#807160",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.99,
     "subOnBg": 5.79
    }
   },
   "font": {
    "heading": {
     "ja": "Stick",
     "en": "Staatliches"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Barlow"
    }
   },
   "shape": {
    "radius": {
     "value": "6px",
     "provenance": "verified",
     "source": "Ant Design borderRadius (seed)"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "12px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-04 (0.75rem)"
    },
    "motion": {
     "duration": "150ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.01 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "logistics",
   "name": "物流の速さ",
   "summary": "物流・配送。橙と斜めの勢いで、動いている印象を作る",
   "mood": [
    "速い",
    "勢い",
    "明快"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#9b4b00",
     "accent2": "#006bad",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#d97b20",
     "accent2": "#007abe",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS 1",
     "en": "Oswald"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Barlow"
    }
   },
   "shape": {
    "radius": {
     "value": "6px",
     "provenance": "verified",
     "source": "Ant Design borderRadius (seed)"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "12px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-04 (0.75rem)"
    },
    "motion": {
     "duration": "150ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.01 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "agriculture",
   "name": "農業の実り",
   "summary": "農業・食品生産。土の茶と若葉で、育てている感じを出す",
   "mood": [
    "自然",
    "あたたかい",
    "実直"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fff9f3",
     "surface": "#f5ede5",
     "ink": "#3c3228",
     "sub": "#6d6153",
     "line": "#d8cdc1",
     "accent": "#5f6a24",
     "accent2": "#29734e",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#16120e",
     "surface": "#211c16",
     "ink": "#d9cdc1",
     "sub": "#8c8071",
     "line": "#3f372d",
     "accent": "#8b9953",
     "accent2": "#39815b",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.77
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Kaku Gothic Antique",
     "en": "Archivo"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Source Sans 3"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "energy-eco",
   "name": "環境・エネルギー",
   "summary": "再エネ・環境事業。青緑と広い余白で、澄んだ空気感を作る",
   "mood": [
    "自然",
    "澄んだ",
    "前向き"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#f5fbff",
     "surface": "#e8eff8",
     "ink": "#2b353e",
     "sub": "#586572",
     "line": "#c5d0dc",
     "accent": "#167459",
     "accent2": "#00727f",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#0f1317",
     "surface": "#181e23",
     "ink": "#c5d0dd",
     "sub": "#768390",
     "line": "#313a43",
     "accent": "#4ca284",
     "accent2": "#00818e",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "Murecho",
     "en": "Manrope"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "DM Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "restaurant",
   "name": "飲食店の食欲",
   "summary": "レストラン・定食。赤茶と暖色で、料理をおいしそうに見せる",
   "mood": [
    "食欲",
    "あたたかい",
    "にぎやか"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fff9ef",
     "surface": "#f9ecdf",
     "ink": "#3f3120",
     "sub": "#735f49",
     "line": "#d9c8b5",
     "accent": "#a73920",
     "accent2": "#8f5400",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#17110b",
     "surface": "#241b11",
     "ink": "#deccb7",
     "sub": "#927e67",
     "line": "#433626",
     "accent": "#e47056",
     "accent2": "#a76500",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.99,
     "subOnBg": 5.79
    }
   },
   "font": {
    "heading": {
     "ja": "Shippori Antique",
     "en": "Roboto Slab"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Bitter"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "verified",
     "source": "Ant Design borderRadiusLG"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "250ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium1 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "cafe",
   "name": "カフェの落ち着き",
   "summary": "カフェ・喫茶。ミルクブラウンと広い余白で、長居したくなる空気を作る",
   "mood": [
    "落ち着き",
    "あたたかい",
    "上品"
   ],
   "fontClass": "明朝系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#7a5c42",
     "accent2": "#69653f",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#ac8c71",
     "accent2": "#7a764f",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Kiwi Maru",
     "en": "Fraunces"
    },
    "body": {
     "ja": "Zen Maru Gothic",
     "en": "Nunito Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "izakaya",
   "name": "居酒屋のにぎわい",
   "summary": "居酒屋・酒場。提灯の赤と黒で、夜のにぎわいを出す",
   "mood": [
    "にぎやか",
    "夜",
    "力強い"
   ],
   "fontClass": "手書き・筆",
   "shapeClass": "角ばった",
   "color": {
    "light": null,
    "dark": {
     "bg": "#17110b",
     "surface": "#241b11",
     "ink": "#deccb7",
     "sub": "#927e67",
     "line": "#433626",
     "accent": "#e56d69",
     "accent2": "#876e6c",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 4.82
    }
   },
   "font": {
    "heading": {
     "ja": "Yuji Syuku",
     "en": "Cormorant"
    },
    "body": {
     "ja": "Sawarabi Mincho",
     "en": "EB Garamond"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "bakery",
   "name": "ベーカリーの香ばしさ",
   "summary": "パン屋・洋菓子。小麦色と丸みで、焼きたての感じを出す",
   "mood": [
    "あたたかい",
    "かわいい",
    "おいしそう"
   ],
   "fontClass": "丸ゴシック系",
   "shapeClass": "丸みのある",
   "color": {
    "light": {
     "bg": "#fff9f3",
     "surface": "#f5ede5",
     "ink": "#3c3228",
     "sub": "#6d6153",
     "line": "#d8cdc1",
     "accent": "#85581b",
     "accent2": "#67681d",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#16120e",
     "surface": "#211c16",
     "ink": "#d9cdc1",
     "sub": "#8c8071",
     "line": "#3f372d",
     "accent": "#b98a50",
     "accent2": "#77782f",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.77
    }
   },
   "font": {
    "heading": {
     "ja": "Tsukimi Rounded",
     "en": "Jost"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Mulish"
    }
   },
   "shape": {
    "radius": {
     "value": "16px",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 borderRadius3XLarge"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow8"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "300ms",
     "easing": "cubic-bezier(0.08, 0.82, 0.17, 1)",
     "provenance": "verified",
     "source": "Ant Design motionEaseOutCirc"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "hair-salon",
   "name": "美容室の洗練",
   "summary": "ヘアサロン。灰みの色と細い明朝で、垢抜けた印象を作る",
   "mood": [
    "洗練",
    "上品",
    "静か"
   ],
   "fontClass": "装飾系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#805659",
     "accent2": "#6a6161",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#b38789",
     "accent2": "#7b7272",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Hina Mincho",
     "en": "Bodoni Moda"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "240ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "beauty-salon",
   "name": "エステの上質さ",
   "summary": "エステ・ネイル。淡いピンクと広い余白で、丁寧に扱われる感じを出す",
   "mood": [
    "上品",
    "やさしい",
    "高級感"
   ],
   "fontClass": "明朝系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#7c5668",
     "accent2": "#805851",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#af8799",
     "accent2": "#936a63",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Shippori Mincho B1",
     "en": "Cormorant Garamond"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "fitness",
   "name": "フィットネスの躍動",
   "summary": "ジム・パーソナル。黒地に蛍光色で、追い込む熱を出す",
   "mood": [
    "躍動",
    "力強い",
    "夜"
   ],
   "fontClass": "装飾系",
   "shapeClass": "やわらか",
   "color": {
    "light": null,
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#6ca135",
     "accent2": "#975bb9",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.05,
     "subOnBg": 4.83
    }
   },
   "font": {
    "heading": {
     "ja": "Dela Gothic One",
     "en": "Anton"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Work Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "6px",
     "provenance": "verified",
     "source": "Ant Design borderRadius (seed)"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "12px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-04 (0.75rem)"
    },
    "motion": {
     "duration": "150ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.01 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "yoga",
   "name": "ヨガの静けさ",
   "summary": "ヨガ・ピラティス。くすんだ緑と長い余白で、呼吸の速さに合わせる",
   "mood": [
    "静か",
    "自然",
    "落ち着き"
   ],
   "fontClass": "丸ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#516b4e",
     "accent2": "#3d6e66",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#7e997a",
     "accent2": "#4c7d74",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Tsukimi Rounded",
     "en": "Jost"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Mulish"
    }
   },
   "shape": {
    "radius": {
     "value": "10px",
     "provenance": "verified",
     "source": "Adobe Spectrum corner-radius-700"
    },
    "shadow": {
     "value": "0 1px 3px rgba(0,0,0,0.05), 0 1px 2px rgba(0,0,0,0.1)",
     "provenance": "verified",
     "source": "Mantine shadows.xs"
    },
    "spacing": {
     "value": "40px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-08 (2.5rem)"
    },
    "motion": {
     "duration": "700ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.slow.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "apparel",
   "name": "アパレルの間",
   "summary": "アパレル・セレクト。ほぼ無彩色と大きな余白で、服そのものを見せる",
   "mood": [
    "洗練",
    "静か",
    "余白"
   ],
   "fontClass": "装飾系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#685c7e",
     "accent2": "#636363",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#988cb1",
     "accent2": "#757575",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "Hina Mincho",
     "en": "Bodoni Moda"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "240ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "ec-goods",
   "name": "雑貨ECの親しみ",
   "summary": "雑貨・生活用品EC。やわらかい色と丸みで、買い物を楽しくする",
   "mood": [
    "親しみ",
    "やわらかい",
    "にぎやか"
   ],
   "fontClass": "丸ゴシック系",
   "shapeClass": "丸みのある",
   "color": {
    "light": {
     "bg": "#fff9f3",
     "surface": "#f5ede5",
     "ink": "#3c3228",
     "sub": "#6d6153",
     "line": "#d8cdc1",
     "accent": "#904f38",
     "accent2": "#267450",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#16120e",
     "surface": "#211c16",
     "ink": "#d9cdc1",
     "sub": "#8c8071",
     "line": "#3f372d",
     "accent": "#c78067",
     "accent2": "#36815d",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.77
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Maru Gothic",
     "en": "Quicksand"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Nunito"
    }
   },
   "shape": {
    "radius": {
     "value": "16px",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 borderRadius3XLarge"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow8"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "300ms",
     "easing": "cubic-bezier(0.08, 0.82, 0.17, 1)",
     "provenance": "verified",
     "source": "Ant Design motionEaseOutCirc"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "cosmetics",
   "name": "コスメの艶",
   "summary": "化粧品。深い赤と艶のある影で、色そのものを主役にする",
   "mood": [
    "艶やか",
    "高級感",
    "目を引く"
   ],
   "fontClass": "明朝系",
   "shapeClass": "丸みのある",
   "color": {
    "light": {
     "bg": "#fff9ef",
     "surface": "#f9ecdf",
     "ink": "#3f3120",
     "sub": "#735f49",
     "line": "#d9c8b5",
     "accent": "#a13568",
     "accent2": "#735c64",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#17110b",
     "surface": "#241b11",
     "ink": "#deccb7",
     "sub": "#927e67",
     "line": "#433626",
     "accent": "#de6c9d",
     "accent2": "#856e76",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.99,
     "subOnBg": 5.79
    }
   },
   "font": {
    "heading": {
     "ja": "Shippori Mincho B1",
     "en": "Cormorant Garamond"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "24px",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 borderRadius4XLarge"
    },
    "shadow": {
     "value": "0 6px 16px 0 rgba(0,0,0,0.08), 0 3px 6px -4px rgba(0,0,0,0.12), 0 9px 28px 8px rgba(0,0,0,0.05)",
     "provenance": "verified",
     "source": "Ant Design boxShadow"
    },
    "spacing": {
     "value": "28px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-emphasized"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "jewelry",
   "name": "ジュエリーの静謐",
   "summary": "宝飾・時計。黒地に金で、明るさを落として石を光らせる",
   "mood": [
    "高級感",
    "静か",
    "夜"
   ],
   "fontClass": "明朝系",
   "shapeClass": "角ばった",
   "color": {
    "light": null,
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#a1906c",
     "accent2": "#77746c",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12,
     "subOnBg": 4.81
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Old Mincho",
     "en": "EB Garamond"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "240ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "furniture",
   "name": "家具の質感",
   "summary": "家具・インテリア。木の色と広い余白で、素材の手ざわりを想像させる",
   "mood": [
    "自然",
    "上品",
    "落ち着き"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#795d41",
     "accent2": "#676540",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#aa8c6f",
     "accent2": "#777650",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Kaku Gothic Antique",
     "en": "Archivo"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Source Sans 3"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "travel",
   "name": "旅行の高揚",
   "summary": "旅行・ツアー。空色と広い写真枠で、行きたくなる気分を作る",
   "mood": [
    "高揚",
    "広がり",
    "明るい"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "丸みのある",
   "color": {
    "light": {
     "bg": "#f2fbff",
     "surface": "#e4f0fd",
     "ink": "#253544",
     "sub": "#51657a",
     "line": "#bccde0",
     "accent": "#00758e",
     "accent2": "#a73920",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#0d131a",
     "surface": "#151e27",
     "ink": "#bed2e6",
     "sub": "#6f849a",
     "line": "#2c3a49",
     "accent": "#00a1be",
     "accent2": "#c15138",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.98,
     "subOnBg": 5.73
    }
   },
   "font": {
    "heading": {
     "ja": "Murecho",
     "en": "Manrope"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "DM Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "16px",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 borderRadius3XLarge"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow8"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "300ms",
     "easing": "cubic-bezier(0.08, 0.82, 0.17, 1)",
     "provenance": "verified",
     "source": "Ant Design motionEaseOutCirc"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "hotel",
   "name": "ホテルの品格",
   "summary": "ホテル・リゾート。深い緑と金で、静かなもてなしを出す",
   "mood": [
    "高級感",
    "静か",
    "フォーマル"
   ],
   "fontClass": "明朝系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#486d57",
     "accent2": "#5e6561",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#749b83",
     "accent2": "#6e7671",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Old Mincho",
     "en": "EB Garamond"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "240ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "ryokan",
   "name": "旅館の和み",
   "summary": "温泉旅館。墨と生成りで、和の落ち着きを出す",
   "mood": [
    "和",
    "静か",
    "上品"
   ],
   "fontClass": "明朝系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#7f594c",
     "accent2": "#6a615e",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#b2897b",
     "accent2": "#7b736f",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Antique",
     "en": "Marcellus"
    },
    "body": {
     "ja": "Sawarabi Mincho",
     "en": "Crimson Pro"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "240ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "wedding",
   "name": "ブライダルの祝祭",
   "summary": "結婚式・式場。淡い金と白で、晴れの日の華やぎを出す",
   "mood": [
    "祝祭",
    "上品",
    "やさしい"
   ],
   "fontClass": "明朝系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#75603f",
     "accent2": "#606843",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#a58e6c",
     "accent2": "#707853",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Shippori Mincho B1",
     "en": "Cormorant Garamond"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "10px",
     "provenance": "verified",
     "source": "Adobe Spectrum corner-radius-700"
    },
    "shadow": {
     "value": "0 1px 3px rgba(0,0,0,0.05), 0 1px 2px rgba(0,0,0,0.1)",
     "provenance": "verified",
     "source": "Mantine shadows.xs"
    },
    "spacing": {
     "value": "40px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-08 (2.5rem)"
    },
    "motion": {
     "duration": "700ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.slow.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "funeral",
   "name": "葬祭の静粛",
   "summary": "葬儀・法要。彩度をほぼ落とし、動きを遅くして、騒がない画面にする",
   "mood": [
    "静か",
    "フォーマル",
    "厳か"
   ],
   "fontClass": "明朝系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#f7fafe",
     "surface": "#eaeff4",
     "ink": "#2e343a",
     "sub": "#5d646c",
     "line": "#c5ccd3",
     "accent": "#645e80",
     "accent2": "#63626a",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#111315",
     "surface": "#1a1d21",
     "ink": "#c9d1d8",
     "sub": "#7b838b",
     "line": "#34393e",
     "accent": "#948eb3",
     "accent2": "#75737b",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.02,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "BIZ UDPMincho",
     "en": "Libre Baskerville"
    },
    "body": {
     "ja": "BIZ UDPGothic",
     "en": "PT Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "10px",
     "provenance": "verified",
     "source": "Adobe Spectrum corner-radius-700"
    },
    "shadow": {
     "value": "0 1px 3px rgba(0,0,0,0.05), 0 1px 2px rgba(0,0,0,0.1)",
     "provenance": "verified",
     "source": "Mantine shadows.xs"
    },
    "spacing": {
     "value": "40px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-08 (2.5rem)"
    },
    "motion": {
     "duration": "700ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.slow.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "shrine-temple",
   "name": "寺社の荘厳",
   "summary": "神社仏閣。朱と墨で、伝統の重みを出す",
   "mood": [
    "和",
    "厳か",
    "伝統"
   ],
   "fontClass": "手書き・筆",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#805851",
     "accent2": "#6a615f",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#b3877f",
     "accent2": "#7b7270",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Yuji Syuku",
     "en": "Cormorant"
    },
    "body": {
     "ja": "Sawarabi Mincho",
     "en": "EB Garamond"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "240ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "fortune",
   "name": "占いの神秘",
   "summary": "占い・スピリチュアル。紫と星の暗さで、神秘的な気配を作る",
   "mood": [
    "神秘的",
    "夜",
    "静か"
   ],
   "fontClass": "装飾系",
   "shapeClass": "やわらか",
   "color": {
    "light": null,
    "dark": {
     "bg": "#0f1317",
     "surface": "#181e23",
     "ink": "#c5d0dd",
     "sub": "#768390",
     "line": "#313a43",
     "accent": "#9e88c7",
     "accent2": "#9d6189",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.94,
     "subOnBg": 4.81
    }
   },
   "font": {
    "heading": {
     "ja": "Hina Mincho",
     "en": "Bodoni Moda"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "10px",
     "provenance": "verified",
     "source": "Adobe Spectrum corner-radius-700"
    },
    "shadow": {
     "value": "0 1px 3px rgba(0,0,0,0.05), 0 1px 2px rgba(0,0,0,0.1)",
     "provenance": "verified",
     "source": "Mantine shadows.xs"
    },
    "spacing": {
     "value": "40px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-08 (2.5rem)"
    },
    "motion": {
     "duration": "700ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.slow.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "pet",
   "name": "ペットのなごみ",
   "summary": "動物病院・ペット。黄緑と丸みで、飼い主の緊張をほどく",
   "mood": [
    "やさしい",
    "かわいい",
    "安心"
   ],
   "fontClass": "丸ゴシック系",
   "shapeClass": "丸みのある",
   "color": {
    "light": {
     "bg": "#fff9f3",
     "surface": "#f5ede5",
     "ink": "#3c3228",
     "sub": "#6d6153",
     "line": "#d8cdc1",
     "accent": "#65681f",
     "accent2": "#337348",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#16120e",
     "surface": "#211c16",
     "ink": "#d9cdc1",
     "sub": "#8c8071",
     "line": "#3f372d",
     "accent": "#92974f",
     "accent2": "#428156",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.77
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Maru Gothic",
     "en": "Quicksand"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Nunito"
    }
   },
   "shape": {
    "radius": {
     "value": "16px",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 borderRadius3XLarge"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow8"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "300ms",
     "easing": "cubic-bezier(0.08, 0.82, 0.17, 1)",
     "provenance": "verified",
     "source": "Ant Design motionEaseOutCirc"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "parenting",
   "name": "子育ての明るさ",
   "summary": "子育て支援・ママ向け。桃色と黄で、疲れていても明るく見える",
   "mood": [
    "明るい",
    "やさしい",
    "親しみ"
   ],
   "fontClass": "丸ゴシック系",
   "shapeClass": "丸い",
   "color": {
    "light": {
     "bg": "#fff9f3",
     "surface": "#f5ede5",
     "ink": "#3c3228",
     "sub": "#6d6153",
     "line": "#d8cdc1",
     "accent": "#924b4c",
     "accent2": "#44703b",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#16120e",
     "surface": "#211c16",
     "ink": "#d9cdc1",
     "sub": "#8c8071",
     "line": "#3f372d",
     "accent": "#ca7d7d",
     "accent2": "#537f49",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.77
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS Rounded 1c",
     "en": "Poppins"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Nunito Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "9999px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.full"
    },
    "shadow": {
     "value": "0 1px 2px -2px rgba(0,0,0,0.16), 0 3px 6px 0 rgba(0,0,0,0.12), 0 5px 12px 4px rgba(0,0,0,0.09)",
     "provenance": "verified",
     "source": "Ant Design boxShadowCard"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "260ms",
     "easing": "cubic-bezier(0.22, 1, 0.36, 1)",
     "provenance": "verified",
     "source": "Base Web easeDecelerate (easeOutQuintic)"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "senior",
   "name": "シニアの読みやすさ",
   "summary": "シニア向け。文字を大きく、コントラストを強くして、迷わせない",
   "mood": [
    "読みやすい",
    "誠実",
    "落ち着き"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#0e6c8f",
     "accent2": "#8e522e",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#4a9bc0",
     "accent2": "#a46642",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "BIZ UDPGothic",
     "en": "Public Sans"
    },
    "body": {
     "ja": "BIZ UDPGothic",
     "en": "Public Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "verified",
     "source": "Ant Design borderRadiusLG"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "250ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium1 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "npo",
   "name": "NPOの誠実さ",
   "summary": "NPO・社会貢献。青緑と素直な形で、飾らない誠実さを出す",
   "mood": [
    "誠実",
    "前向き",
    "やさしい"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#f5fbff",
     "surface": "#e8eff8",
     "ink": "#2b353e",
     "sub": "#586572",
     "line": "#c5d0dc",
     "accent": "#007461",
     "accent2": "#685793",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#0f1317",
     "surface": "#181e23",
     "ink": "#c5d0dd",
     "sub": "#768390",
     "line": "#313a43",
     "accent": "#42a28d",
     "accent2": "#7c6ba8",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Kaku Gothic New",
     "en": "Inter"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "verified",
     "source": "Ant Design borderRadiusLG"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "250ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium1 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "government",
   "name": "行政の公平さ",
   "summary": "自治体・公共。読みやすさ優先の書体と直角で、誰にでも同じに届ける",
   "mood": [
    "読みやすい",
    "フォーマル",
    "実直"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#f7fafe",
     "surface": "#eaeff4",
     "ink": "#2e343a",
     "sub": "#5d646c",
     "line": "#c5ccd3",
     "accent": "#486781",
     "accent2": "#5e646a",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#111315",
     "surface": "#1a1d21",
     "ink": "#c9d1d8",
     "sub": "#7b838b",
     "line": "#34393e",
     "accent": "#7596b2",
     "accent2": "#6f767b",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.02,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "BIZ UDPGothic",
     "en": "Public Sans"
    },
    "body": {
     "ja": "BIZ UDPGothic",
     "en": "Public Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "recruiting",
   "name": "採用の前向きさ",
   "summary": "採用・求人。明るい青と余白で、働く姿を想像しやすくする",
   "mood": [
    "前向き",
    "明るい",
    "誠実"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "丸みのある",
   "color": {
    "light": {
     "bg": "#f5fbff",
     "surface": "#e8eff8",
     "ink": "#2b353e",
     "sub": "#586572",
     "line": "#c5d0dc",
     "accent": "#1e6b92",
     "accent2": "#8c5328",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#0f1317",
     "surface": "#181e23",
     "ink": "#c5d0dd",
     "sub": "#768390",
     "line": "#313a43",
     "accent": "#5199c3",
     "accent2": "#a1673b",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "LINE Seed JP",
     "en": "Outfit"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "16px",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 borderRadius3XLarge"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow8"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "300ms",
     "easing": "cubic-bezier(0.08, 0.82, 0.17, 1)",
     "provenance": "verified",
     "source": "Ant Design motionEaseOutCirc"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "wa-modern",
   "name": "和モダン",
   "summary": "墨と生成りに朱を一点。余白を広く取り、和の間を残す",
   "mood": [
    "和",
    "静か",
    "上品"
   ],
   "fontClass": "装飾系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#805753",
     "accent2": "#6a6160",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#b48883",
     "accent2": "#7b7271",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Hina Mincho",
     "en": "Bodoni Moda"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "10px",
     "provenance": "verified",
     "source": "Adobe Spectrum corner-radius-700"
    },
    "shadow": {
     "value": "0 1px 3px rgba(0,0,0,0.05), 0 1px 2px rgba(0,0,0,0.1)",
     "provenance": "verified",
     "source": "Mantine shadows.xs"
    },
    "spacing": {
     "value": "40px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-08 (2.5rem)"
    },
    "motion": {
     "duration": "700ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.slow.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "wa-traditional",
   "name": "和の伝統",
   "summary": "藍と生成り。筆書きの見出しで、古くからある感じを出す",
   "mood": [
    "和",
    "伝統",
    "厳か"
   ],
   "fontClass": "手書き・筆",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#496781",
     "accent2": "#5e646a",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#7696b2",
     "accent2": "#6e757b",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Yuji Syuku",
     "en": "Cormorant"
    },
    "body": {
     "ja": "Sawarabi Mincho",
     "en": "EB Garamond"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "240ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "wabi-sabi",
   "name": "侘び寂び",
   "summary": "彩度をほぼ捨て、動きを遅く。足りなさをそのまま見せる",
   "mood": [
    "静か",
    "余白",
    "枯れた"
   ],
   "fontClass": "明朝系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#74603e",
     "accent2": "#67635c",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#a48f6c",
     "accent2": "#78746c",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Antique",
     "en": "Marcellus"
    },
    "body": {
     "ja": "Sawarabi Mincho",
     "en": "Crimson Pro"
    }
   },
   "shape": {
    "radius": {
     "value": "10px",
     "provenance": "verified",
     "source": "Adobe Spectrum corner-radius-700"
    },
    "shadow": {
     "value": "0 1px 3px rgba(0,0,0,0.05), 0 1px 2px rgba(0,0,0,0.1)",
     "provenance": "verified",
     "source": "Mantine shadows.xs"
    },
    "spacing": {
     "value": "40px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-08 (2.5rem)"
    },
    "motion": {
     "duration": "700ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.slow.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "nordic",
   "name": "北欧",
   "summary": "白木とくすんだ青。明るく、けれど騒がない",
   "mood": [
    "自然",
    "静か",
    "やわらかい"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#3a6c72",
     "accent2": "#496781",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#689ba1",
     "accent2": "#597893",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Murecho",
     "en": "Manrope"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "DM Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "midcentury",
   "name": "ミッドセンチュリー",
   "summary": "からし色とくすんだ橙。50〜60年代の家具の色を借りる",
   "mood": [
    "レトロ",
    "あたたかい",
    "上品"
   ],
   "fontClass": "装飾系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fff9f3",
     "surface": "#f5ede5",
     "ink": "#3c3228",
     "sub": "#6d6153",
     "line": "#d8cdc1",
     "accent": "#835a18",
     "accent2": "#3a6598",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#16120e",
     "surface": "#211c16",
     "ink": "#d9cdc1",
     "sub": "#8c8071",
     "line": "#3f372d",
     "accent": "#b68b4e",
     "accent2": "#4b76ab",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.77
    }
   },
   "font": {
    "heading": {
     "ja": "Aoboshi One",
     "en": "Prata"
    },
    "body": {
     "ja": "Sawarabi Gothic",
     "en": "Lora"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "verified",
     "source": "Ant Design borderRadiusLG"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "250ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium1 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "art-deco",
   "name": "アールデコ",
   "summary": "黒と金、細い線。左右対称の格式を出す",
   "mood": [
    "高級感",
    "装飾的",
    "フォーマル"
   ],
   "fontClass": "装飾系",
   "shapeClass": "角ばった",
   "color": {
    "light": null,
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#a3906c",
     "accent2": "#77746c",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12,
     "subOnBg": 4.81
    }
   },
   "font": {
    "heading": {
     "ja": "Hina Mincho",
     "en": "Bodoni Moda"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "bauhaus",
   "name": "バウハウス",
   "summary": "赤・青・黄の原色と直角。装飾を足さない",
   "mood": [
    "幾何学",
    "力強い",
    "無駄がない"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#0066b3",
     "accent2": "#a6344f",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#3d96ea",
     "accent2": "#c24d66",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS 2",
     "en": "Poppins"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "DM Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "swiss",
   "name": "スイススタイル",
   "summary": "赤一点と厳格な格子。文字の並びで見せる",
   "mood": [
    "整然",
    "無駄がない",
    "硬派"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#a83630",
     "accent2": "#636363",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#e66f64",
     "accent2": "#757575",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS 1",
     "en": "Oswald"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Barlow"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "brutalism",
   "name": "ブルータリズム",
   "summary": "太い枠と生の色。整えすぎない粗さを残す",
   "mood": [
    "粗い",
    "力強い",
    "目を引く"
   ],
   "fontClass": "装飾系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#796200",
     "accent2": "#4f56b7",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#ab9102",
     "accent2": "#616cce",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "Stick",
     "en": "Staatliches"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Barlow"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "minimal-quiet",
   "name": "静かなミニマル",
   "summary": "ほぼ無彩色。線一本と余白だけで構成する",
   "mood": [
    "静か",
    "余白",
    "無駄がない"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#4b6682",
     "accent2": "#636363",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#7a96b3",
     "accent2": "#757575",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Kaku Gothic New",
     "en": "Inter"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "240ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "maximal",
   "name": "マキシマリズム",
   "summary": "強い色を複数ぶつけ、余白を詰める。にぎやかさで勝負する",
   "mood": [
    "にぎやか",
    "目を引く",
    "派手"
   ],
   "fontClass": "装飾系",
   "shapeClass": "丸い",
   "color": {
    "light": {
     "bg": "#fff9ef",
     "surface": "#f9ecdf",
     "ink": "#3f3120",
     "sub": "#735f49",
     "line": "#d9c8b5",
     "accent": "#874197",
     "accent2": "#885800",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#17110b",
     "surface": "#241b11",
     "ink": "#deccb7",
     "sub": "#927e67",
     "line": "#433626",
     "accent": "#c076d0",
     "accent2": "#9f6800",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.99,
     "subOnBg": 5.79
    }
   },
   "font": {
    "heading": {
     "ja": "Dela Gothic One",
     "en": "Anton"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Work Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "9999px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.full"
    },
    "shadow": {
     "value": "0 1px 2px -2px rgba(0,0,0,0.16), 0 3px 6px 0 rgba(0,0,0,0.12), 0 5px 12px 4px rgba(0,0,0,0.09)",
     "provenance": "verified",
     "source": "Ant Design boxShadowCard"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "260ms",
     "easing": "cubic-bezier(0.22, 1, 0.36, 1)",
     "provenance": "verified",
     "source": "Base Web easeDecelerate (easeOutQuintic)"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "neumorphic",
   "name": "ニューモーフィズム",
   "summary": "背景と同じ色の面を、影のふくらみだけで浮かせる",
   "mood": [
    "やわらかい",
    "静か",
    "立体的"
   ],
   "fontClass": "丸ゴシック系",
   "shapeClass": "丸みのある",
   "color": {
    "light": {
     "bg": "#f7fafe",
     "surface": "#eaeff4",
     "ink": "#2e343a",
     "sub": "#5d646c",
     "line": "#c5ccd3",
     "accent": "#466880",
     "accent2": "#5d6082",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#111315",
     "surface": "#1a1d21",
     "ink": "#c9d1d8",
     "sub": "#7b838b",
     "line": "#34393e",
     "accent": "#7497b0",
     "accent2": "#6f7296",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.02,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "Tsukimi Rounded",
     "en": "Jost"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Mulish"
    }
   },
   "shape": {
    "radius": {
     "value": "16px",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 borderRadius3XLarge"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow8"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "300ms",
     "easing": "cubic-bezier(0.08, 0.82, 0.17, 1)",
     "provenance": "verified",
     "source": "Ant Design motionEaseOutCirc"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "glass-layer",
   "name": "すりガラス",
   "summary": "半透明の層を重ねる前提の配色。背景が透けても文字が沈まない濃さにする",
   "mood": [
    "透明感",
    "現代的",
    "立体的"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": null,
    "dark": {
     "bg": "#0f1317",
     "surface": "#181e23",
     "ink": "#c5d0dd",
     "sub": "#768390",
     "line": "#313a43",
     "accent": "#7990cd",
     "accent2": "#8768a2",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.94,
     "subOnBg": 4.81
    }
   },
   "font": {
    "heading": {
     "ja": "Murecho",
     "en": "Manrope"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "DM Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "cyberpunk",
   "name": "サイバーパンク",
   "summary": "黒地にマゼンタとシアン。夜の街の看板の色",
   "mood": [
    "夜",
    "派手",
    "近未来"
   ],
   "fontClass": "装飾系",
   "shapeClass": "角ばった",
   "color": {
    "light": null,
    "dark": {
     "bg": "#0d131a",
     "surface": "#151e27",
     "ink": "#bed2e6",
     "sub": "#6f849a",
     "line": "#2c3a49",
     "accent": "#ca73c3",
     "accent2": "#00863c",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.04,
     "subOnBg": 4.84
    }
   },
   "font": {
    "heading": {
     "ja": "DotGothic16",
     "en": "Space Mono"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Roboto Mono"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "retro-future",
   "name": "レトロフューチャー",
   "summary": "くすんだ橙と青緑。昔の人が想像した未来の色",
   "mood": [
    "レトロ",
    "近未来",
    "あたたかい"
   ],
   "fontClass": "装飾系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fff9f3",
     "surface": "#f5ede5",
     "ink": "#3c3228",
     "sub": "#6d6153",
     "line": "#d8cdc1",
     "accent": "#8d522c",
     "accent2": "#156c90",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#16120e",
     "surface": "#211c16",
     "ink": "#d9cdc1",
     "sub": "#8c8071",
     "line": "#3f372d",
     "accent": "#c3835c",
     "accent2": "#2c7ca1",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.77
    }
   },
   "font": {
    "heading": {
     "ja": "Reggae One",
     "en": "Alfa Slab One"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Bitter"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "verified",
     "source": "Ant Design borderRadiusLG"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "250ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium1 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "y2k",
   "name": "Y2K",
   "summary": "銀と水色と紫。2000年前後の光沢感を出す",
   "mood": [
    "派手",
    "近未来",
    "にぎやか"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "丸い",
   "color": {
    "light": {
     "bg": "#f2fbff",
     "surface": "#e4f0fd",
     "ink": "#253544",
     "sub": "#51657a",
     "line": "#bccde0",
     "accent": "#5554b6",
     "accent2": "#a63c0c",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#0d131a",
     "surface": "#151e27",
     "ink": "#bed2e6",
     "sub": "#6f849a",
     "line": "#2c3a49",
     "accent": "#8488ef",
     "accent2": "#bf532a",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.98,
     "subOnBg": 5.73
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS 2",
     "en": "Poppins"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "DM Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "9999px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.full"
    },
    "shadow": {
     "value": "0 1px 2px -2px rgba(0,0,0,0.16), 0 3px 6px 0 rgba(0,0,0,0.12), 0 5px 12px 4px rgba(0,0,0,0.09)",
     "provenance": "verified",
     "source": "Ant Design boxShadowCard"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "260ms",
     "easing": "cubic-bezier(0.22, 1, 0.36, 1)",
     "provenance": "verified",
     "source": "Base Web easeDecelerate (easeOutQuintic)"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "vaporwave",
   "name": "ヴェイパーウェイヴ",
   "summary": "桃色と水色のグラデーション。少し気だるい感じを残す",
   "mood": [
    "夜",
    "派手",
    "気だるい"
   ],
   "fontClass": "装飾系",
   "shapeClass": "やわらか",
   "color": {
    "light": null,
    "dark": {
     "bg": "#0f1317",
     "surface": "#181e23",
     "ink": "#c5d0dd",
     "sub": "#768390",
     "line": "#313a43",
     "accent": "#b182b9",
     "accent2": "#507f4b",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.94,
     "subOnBg": 4.81
    }
   },
   "font": {
    "heading": {
     "ja": "Aoboshi One",
     "en": "Prata"
    },
    "body": {
     "ja": "Sawarabi Gothic",
     "en": "Lora"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "verified",
     "source": "Ant Design borderRadiusLG"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "250ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium1 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "synthwave",
   "name": "シンセウェイヴ",
   "summary": "黒地に紫とオレンジ。地平線の格子を思わせる",
   "mood": [
    "夜",
    "近未来",
    "派手"
   ],
   "fontClass": "装飾系",
   "shapeClass": "角ばった",
   "color": {
    "light": null,
    "dark": {
     "bg": "#0d131a",
     "surface": "#151e27",
     "ink": "#bed2e6",
     "sub": "#6f849a",
     "line": "#2c3a49",
     "accent": "#9f80e7",
     "accent2": "#6e7b00",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.04,
     "subOnBg": 4.84
    }
   },
   "font": {
    "heading": {
     "ja": "Dela Gothic One",
     "en": "Anton"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Work Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "eighties",
   "name": "80年代",
   "summary": "原色に近い青とピンク。太い書体で当時の勢いを出す",
   "mood": [
    "レトロ",
    "派手",
    "にぎやか"
   ],
   "fontClass": "装飾系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#355db8",
     "accent2": "#845b00",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#6490ef",
     "accent2": "#9b6c00",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "Reggae One",
     "en": "Alfa Slab One"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Bitter"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "nineties",
   "name": "90年代",
   "summary": "くすんだ原色とドット。荒い印刷物の質感を借りる",
   "mood": [
    "レトロ",
    "粗い",
    "にぎやか"
   ],
   "fontClass": "装飾系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fff9f3",
     "surface": "#f5ede5",
     "ink": "#3c3228",
     "sub": "#6d6153",
     "line": "#d8cdc1",
     "accent": "#00746f",
     "accent2": "#74538c",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#16120e",
     "surface": "#211c16",
     "ink": "#d9cdc1",
     "sub": "#8c8071",
     "line": "#3f372d",
     "accent": "#38a29c",
     "accent2": "#8867a1",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.77
    }
   },
   "font": {
    "heading": {
     "ja": "DotGothic16",
     "en": "Space Mono"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Roboto Mono"
    }
   },
   "shape": {
    "radius": {
     "value": "6px",
     "provenance": "verified",
     "source": "Ant Design borderRadius (seed)"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "12px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-04 (0.75rem)"
    },
    "motion": {
     "duration": "150ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.01 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "vintage-print",
   "name": "ヴィンテージ印刷",
   "summary": "セピアとくすんだ赤。紙の焼けを想わせる",
   "mood": [
    "レトロ",
    "あたたかい",
    "枯れた"
   ],
   "fontClass": "装飾系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#7e5949",
     "accent2": "#72613e",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#b28978",
     "accent2": "#83724f",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Aoboshi One",
     "en": "Prata"
    },
    "body": {
     "ja": "Sawarabi Gothic",
     "en": "Lora"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "240ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "antique-paper",
   "name": "アンティーク",
   "summary": "羊皮紙の色と焦げ茶。細い罫線で古い書物に寄せる",
   "mood": [
    "伝統",
    "枯れた",
    "上品"
   ],
   "fontClass": "装飾系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#7c5b44",
     "accent2": "#69625d",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#ae8b73",
     "accent2": "#7a736e",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Aoboshi One",
     "en": "Prata"
    },
    "body": {
     "ja": "Sawarabi Gothic",
     "en": "Lora"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "industrial",
   "name": "インダストリアル",
   "summary": "鉄の灰と錆の橙。金属の質感を色で出す",
   "mood": [
    "硬派",
    "粗い",
    "力強い"
   ],
   "fontClass": "装飾系",
   "shapeClass": "角ばった",
   "color": {
    "light": null,
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#b28a78",
     "accent2": "#757575",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.05,
     "subOnBg": 4.83
    }
   },
   "font": {
    "heading": {
     "ja": "Stick",
     "en": "Staatliches"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Barlow"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "rustic",
   "name": "ラスティック",
   "summary": "土と麻の色。手仕事の素朴さを出す",
   "mood": [
    "自然",
    "あたたかい",
    "素朴"
   ],
   "fontClass": "手書き・筆",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#7b5c43",
     "accent2": "#6a643f",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#ad8c71",
     "accent2": "#7b744f",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Klee One",
     "en": "Caveat"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Cabin"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "botanical",
   "name": "ボタニカル",
   "summary": "葉の緑と生成り。植物のある部屋の明るさにする",
   "mood": [
    "自然",
    "やわらかい",
    "静か"
   ],
   "fontClass": "明朝系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#556b4b",
     "accent2": "#3f6e62",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#819877",
     "accent2": "#4e7d70",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Kiwi Maru",
     "en": "Fraunces"
    },
    "body": {
     "ja": "Zen Maru Gothic",
     "en": "Nunito Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "organic-clay",
   "name": "オーガニック",
   "summary": "陶土の色と丸い形。角をなくして人肌の感じを出す",
   "mood": [
    "やわらかい",
    "自然",
    "あたたかい"
   ],
   "fontClass": "丸ゴシック系",
   "shapeClass": "丸みのある",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#7f584c",
     "accent2": "#75603f",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#b2887b",
     "accent2": "#87714f",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Tsukimi Rounded",
     "en": "Jost"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Mulish"
    }
   },
   "shape": {
    "radius": {
     "value": "16px",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 borderRadius3XLarge"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow8"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "300ms",
     "easing": "cubic-bezier(0.08, 0.82, 0.17, 1)",
     "provenance": "verified",
     "source": "Ant Design motionEaseOutCirc"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "earth-tone",
   "name": "アースカラー",
   "summary": "赤土・砂・枯草。彩度を抑えた自然の色だけで組む",
   "mood": [
    "自然",
    "落ち着き",
    "あたたかい"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#7d5a47",
     "accent2": "#426e5e",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#b08a76",
     "accent2": "#507d6d",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Shippori Antique",
     "en": "Roboto Slab"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Bitter"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "pastel-soft",
   "name": "パステル",
   "summary": "淡い色だけで組む。強い色を使わず、それでも読める濃さを守る",
   "mood": [
    "やわらかい",
    "かわいい",
    "明るい"
   ],
   "fontClass": "丸ゴシック系",
   "shapeClass": "丸みのある",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#6d5b7b",
     "accent2": "#785e40",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#9e8aad",
     "accent2": "#8a6f51",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Maru Gothic",
     "en": "Quicksand"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Nunito"
    }
   },
   "shape": {
    "radius": {
     "value": "16px",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 borderRadius3XLarge"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow8"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "300ms",
     "easing": "cubic-bezier(0.08, 0.82, 0.17, 1)",
     "provenance": "verified",
     "source": "Ant Design motionEaseOutCirc"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "candy-pop",
   "name": "キャンディポップ",
   "summary": "飴のような透明感のある強い色。丸い形で甘さを出す",
   "mood": [
    "かわいい",
    "にぎやか",
    "明るい"
   ],
   "fontClass": "丸ゴシック系",
   "shapeClass": "丸い",
   "color": {
    "light": {
     "bg": "#fff9ef",
     "surface": "#f9ecdf",
     "ink": "#3f3120",
     "sub": "#735f49",
     "line": "#d9c8b5",
     "accent": "#9a3878",
     "accent2": "#706500",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#17110b",
     "surface": "#241b11",
     "ink": "#deccb7",
     "sub": "#927e67",
     "line": "#433626",
     "accent": "#d66eae",
     "accent2": "#817600",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.99,
     "subOnBg": 5.79
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS Rounded 1c",
     "en": "Poppins"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Nunito Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "9999px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.full"
    },
    "shadow": {
     "value": "0 1px 2px -2px rgba(0,0,0,0.16), 0 3px 6px 0 rgba(0,0,0,0.12), 0 5px 12px 4px rgba(0,0,0,0.09)",
     "provenance": "verified",
     "source": "Ant Design boxShadowCard"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "260ms",
     "easing": "cubic-bezier(0.22, 1, 0.36, 1)",
     "provenance": "verified",
     "source": "Base Web easeDecelerate (easeOutQuintic)"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "neon-night",
   "name": "ネオン",
   "summary": "黒地に発光色。暗いほど色が立つ配色",
   "mood": [
    "夜",
    "派手",
    "目を引く"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": null,
    "dark": {
     "bg": "#0d131a",
     "surface": "#151e27",
     "ink": "#bed2e6",
     "sub": "#6f849a",
     "line": "#2c3a49",
     "accent": "#19a765",
     "accent2": "#af529b",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.04,
     "subOnBg": 4.84
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS 2",
     "en": "Poppins"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "DM Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "verified",
     "source": "Ant Design borderRadiusLG"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "250ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium1 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "monochrome-strict",
   "name": "モノクローム",
   "summary": "色を一切使わない。濃淡と余白だけで階層を作る",
   "mood": [
    "無駄がない",
    "静か",
    "硬派"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#516483",
     "accent2": "#636363",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#7e93b5",
     "accent2": "#757575",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Kaku Gothic New",
     "en": "Inter"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "high-contrast",
   "name": "ハイコントラスト",
   "summary": "白と黒を振り切り、差し色を一つだけ。遠くからでも読める",
   "mood": [
    "読みやすい",
    "力強い",
    "無駄がない"
   ],
   "fontClass": "装飾系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#a8372a",
     "accent2": "#636363",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#e56f5e",
     "accent2": "#757575",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "Dela Gothic One",
     "en": "Anton"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Work Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "soft-gray",
   "name": "ソフトグレー",
   "summary": "灰の階調を細かく使う。主張を弱め、中身を前に出す",
   "mood": [
    "静か",
    "上品",
    "落ち着き"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#f7fafe",
     "surface": "#eaeff4",
     "ink": "#2e343a",
     "sub": "#5d646c",
     "line": "#c5ccd3",
     "accent": "#4b6682",
     "accent2": "#5e646a",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#111315",
     "surface": "#1a1d21",
     "ink": "#c9d1d8",
     "sub": "#7b838b",
     "line": "#34393e",
     "accent": "#7a96b3",
     "accent2": "#6f757b",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.02,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Kaku Gothic New",
     "en": "Inter"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "sepia-quiet",
   "name": "セピア",
   "summary": "全体を茶に寄せる。写真も文字も同じ空気になる",
   "mood": [
    "レトロ",
    "あたたかい",
    "静か"
   ],
   "fontClass": "装飾系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#7c5b45",
     "accent2": "#69625d",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#af8a73",
     "accent2": "#7a736e",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Aoboshi One",
     "en": "Prata"
    },
    "body": {
     "ja": "Sawarabi Gothic",
     "en": "Lora"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "blueprint",
   "name": "ブループリント",
   "summary": "青地に白線。設計図の見え方をそのまま使う",
   "mood": [
    "硬派",
    "整然",
    "技術"
   ],
   "fontClass": "等幅系",
   "shapeClass": "角ばった",
   "color": {
    "light": null,
    "dark": {
     "bg": "#0f1317",
     "surface": "#181e23",
     "ink": "#c5d0dd",
     "sub": "#768390",
     "line": "#313a43",
     "accent": "#6895cb",
     "accent2": "#6d7580",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.94,
     "subOnBg": 4.81
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS 1 Code",
     "en": "JetBrains Mono"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Fira Code"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "terracotta",
   "name": "テラコッタ",
   "summary": "素焼きの赤茶と生成り。南欧の壁の色",
   "mood": [
    "あたたかい",
    "自然",
    "上品"
   ],
   "fontClass": "明朝系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fff9f3",
     "surface": "#f5ede5",
     "ink": "#3c3228",
     "sub": "#6d6153",
     "line": "#d8cdc1",
     "accent": "#914e3c",
     "accent2": "#825b17",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#16120e",
     "surface": "#211c16",
     "ink": "#d9cdc1",
     "sub": "#8c8071",
     "line": "#3f372d",
     "accent": "#c9806c",
     "accent2": "#956d2e",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.77
    }
   },
   "font": {
    "heading": {
     "ja": "Kiwi Maru",
     "en": "Fraunces"
    },
    "body": {
     "ja": "Zen Maru Gothic",
     "en": "Nunito Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "sand-beige",
   "name": "サンドベージュ",
   "summary": "砂の明るさに近い背景。眩しすぎない白として使える",
   "mood": [
    "やわらかい",
    "落ち着き",
    "自然"
   ],
   "fontClass": "丸ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#785d41",
     "accent2": "#666640",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#aa8d6e",
     "accent2": "#777750",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Tsukimi Rounded",
     "en": "Jost"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Mulish"
    }
   },
   "shape": {
    "radius": {
     "value": "10px",
     "provenance": "verified",
     "source": "Adobe Spectrum corner-radius-700"
    },
    "shadow": {
     "value": "0 1px 3px rgba(0,0,0,0.05), 0 1px 2px rgba(0,0,0,0.1)",
     "provenance": "verified",
     "source": "Mantine shadows.xs"
    },
    "spacing": {
     "value": "40px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-08 (2.5rem)"
    },
    "motion": {
     "duration": "700ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.slow.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "forest-deep",
   "name": "フォレスト",
   "summary": "深い森の緑。暗い側に振って、落ち着きと奥行きを出す",
   "mood": [
    "自然",
    "静か",
    "夜"
   ],
   "fontClass": "明朝系",
   "shapeClass": "やわらか",
   "color": {
    "light": null,
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#799b7f",
     "accent2": "#4a7c79",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12,
     "subOnBg": 4.81
    }
   },
   "font": {
    "heading": {
     "ja": "Noto Serif JP",
     "en": "Playfair Display"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Source Sans 3"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "ocean-deep",
   "name": "オーシャン",
   "summary": "海の青の濃淡。深くなるほど暗くする",
   "mood": [
    "静か",
    "広がり",
    "夜"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": null,
    "dark": {
     "bg": "#0f1317",
     "surface": "#181e23",
     "ink": "#c5d0dd",
     "sub": "#768390",
     "line": "#313a43",
     "accent": "#429dba",
     "accent2": "#5674ad",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.94,
     "subOnBg": 4.81
    }
   },
   "font": {
    "heading": {
     "ja": "Murecho",
     "en": "Manrope"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "DM Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "sunset-warm",
   "name": "サンセット",
   "summary": "橙から紫へ。一日の終わりの空の移り変わりを使う",
   "mood": [
    "あたたかい",
    "やわらかい",
    "高揚"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fff9ef",
     "surface": "#f9ecdf",
     "ink": "#3f3120",
     "sub": "#735f49",
     "line": "#d9c8b5",
     "accent": "#a63d02",
     "accent2": "#007193",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#17110b",
     "surface": "#241b11",
     "ink": "#deccb7",
     "sub": "#927e67",
     "line": "#433626",
     "accent": "#e17346",
     "accent2": "#007ea4",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.99,
     "subOnBg": 5.79
    }
   },
   "font": {
    "heading": {
     "ja": "Murecho",
     "en": "Manrope"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "DM Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "aurora-cool",
   "name": "オーロラ",
   "summary": "暗い空に緑と紫。ゆっくり動く前提の配色",
   "mood": [
    "神秘的",
    "夜",
    "広がり"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": null,
    "dark": {
     "bg": "#0d131a",
     "surface": "#151e27",
     "ink": "#bed2e6",
     "sub": "#6f849a",
     "line": "#2c3a49",
     "accent": "#00a776",
     "accent2": "#6f68cc",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.04,
     "subOnBg": 4.84
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS 2",
     "en": "Poppins"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "DM Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "10px",
     "provenance": "verified",
     "source": "Adobe Spectrum corner-radius-700"
    },
    "shadow": {
     "value": "0 1px 3px rgba(0,0,0,0.05), 0 1px 2px rgba(0,0,0,0.1)",
     "provenance": "verified",
     "source": "Mantine shadows.xs"
    },
    "spacing": {
     "value": "40px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-08 (2.5rem)"
    },
    "motion": {
     "duration": "700ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.slow.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "lavender-calm",
   "name": "ラベンダー",
   "summary": "淡い紫。強すぎず、でも印象に残る中間の色で組む",
   "mood": [
    "やさしい",
    "静か",
    "上品"
   ],
   "fontClass": "丸ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#f7fafe",
     "surface": "#eaeff4",
     "ink": "#2e343a",
     "sub": "#5d646c",
     "line": "#c5ccd3",
     "accent": "#615e81",
     "accent2": "#755873",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#111315",
     "surface": "#1a1d21",
     "ink": "#c9d1d8",
     "sub": "#7b838b",
     "line": "#34393e",
     "accent": "#918eb4",
     "accent2": "#886b87",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.02,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "Tsukimi Rounded",
     "en": "Jost"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Mulish"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "sakura-soft",
   "name": "桜",
   "summary": "淡い桃と若草。春の短い明るさを出す",
   "mood": [
    "やさしい",
    "かわいい",
    "明るい"
   ],
   "fontClass": "明朝系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#7d5664",
     "accent2": "#616743",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#b18695",
     "accent2": "#717752",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Kiwi Maru",
     "en": "Fraunces"
    },
    "body": {
     "ja": "Zen Maru Gothic",
     "en": "Nunito Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "autumn-rich",
   "name": "オータム",
   "summary": "紅葉の赤と黄。暖色を重ねて厚みを作る",
   "mood": [
    "あたたかい",
    "豊か",
    "落ち着き"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fff9f3",
     "surface": "#f5ede5",
     "ink": "#3c3228",
     "sub": "#6d6153",
     "line": "#d8cdc1",
     "accent": "#8f5031",
     "accent2": "#7b5f13",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#16120e",
     "surface": "#211c16",
     "ink": "#d9cdc1",
     "sub": "#8c8071",
     "line": "#3f372d",
     "accent": "#c58262",
     "accent2": "#8e712a",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.77
    }
   },
   "font": {
    "heading": {
     "ja": "Shippori Antique",
     "en": "Roboto Slab"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Bitter"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "verified",
     "source": "Ant Design borderRadiusLG"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "250ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium1 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "winter-crisp",
   "name": "ウィンター",
   "summary": "白と薄氷の青。余白を多く取り、冷たい空気を出す",
   "mood": [
    "澄んだ",
    "静か",
    "冷たい"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#f7fafe",
     "surface": "#eaeff4",
     "ink": "#2e343a",
     "sub": "#5d646c",
     "line": "#c5ccd3",
     "accent": "#3b6c76",
     "accent2": "#4c6582",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#111315",
     "surface": "#1a1d21",
     "ink": "#c9d1d8",
     "sub": "#7b838b",
     "line": "#34393e",
     "accent": "#699aa4",
     "accent2": "#5d7694",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.02,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "Murecho",
     "en": "Manrope"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "DM Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "240ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "tropical",
   "name": "トロピカル",
   "summary": "青緑と黄。強い日差しの下の色をそのまま使う",
   "mood": [
    "明るい",
    "にぎやか",
    "高揚"
   ],
   "fontClass": "丸ゴシック系",
   "shapeClass": "丸みのある",
   "color": {
    "light": {
     "bg": "#fff9ef",
     "surface": "#f9ecdf",
     "ink": "#3f3120",
     "sub": "#735f49",
     "line": "#d9c8b5",
     "accent": "#007d5e",
     "accent2": "#674eb0",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#17110b",
     "surface": "#241b11",
     "ink": "#deccb7",
     "sub": "#927e67",
     "line": "#433626",
     "accent": "#00a684",
     "accent2": "#7c64c8",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.99,
     "subOnBg": 5.79
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS Rounded 1c",
     "en": "Poppins"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Nunito Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "16px",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 borderRadius3XLarge"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow8"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "300ms",
     "easing": "cubic-bezier(0.08, 0.82, 0.17, 1)",
     "provenance": "verified",
     "source": "Ant Design motionEaseOutCirc"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "desert-dry",
   "name": "デザート",
   "summary": "砂と乾いた空。彩度を落とした暖色と薄い青で組む",
   "mood": [
    "乾いた",
    "自然",
    "落ち着き"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#7a5d42",
     "accent2": "#486781",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#ac8c70",
     "accent2": "#587792",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS 1",
     "en": "Oswald"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Barlow"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "240ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "midnight",
   "name": "ミッドナイト",
   "summary": "ほぼ黒の紺。夜間に見ても目が疲れない濃さにする",
   "mood": [
    "夜",
    "静か",
    "落ち着き"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": null,
    "dark": {
     "bg": "#111315",
     "surface": "#1a1d21",
     "ink": "#c9d1d8",
     "sub": "#7b838b",
     "line": "#34393e",
     "accent": "#7e94b4",
     "accent2": "#7a6f93",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.05,
     "subOnBg": 4.84
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Kaku Gothic New",
     "en": "Inter"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "verified",
     "source": "Ant Design borderRadiusLG"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "250ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium1 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "gold-luxury",
   "name": "ゴールド",
   "summary": "黒に金。輝きは面積を小さくするほど効く",
   "mood": [
    "高級感",
    "夜",
    "フォーマル"
   ],
   "fontClass": "明朝系",
   "shapeClass": "角ばった",
   "color": {
    "light": null,
    "dark": {
     "bg": "#16120e",
     "surface": "#211c16",
     "ink": "#d9cdc1",
     "sub": "#8c8071",
     "line": "#3f372d",
     "accent": "#b28c4b",
     "accent2": "#7b7468",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.94,
     "subOnBg": 4.83
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Old Mincho",
     "en": "EB Garamond"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "240ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "silver-cool",
   "name": "シルバー",
   "summary": "青みの灰で金属感を出す。彩度を上げずに冷たさを作る",
   "mood": [
    "硬派",
    "冷たい",
    "上品"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#f7fafe",
     "surface": "#eaeff4",
     "ink": "#2e343a",
     "sub": "#5d646c",
     "line": "#c5ccd3",
     "accent": "#3f6a7b",
     "accent2": "#5c6569",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#111315",
     "surface": "#1a1d21",
     "ink": "#c9d1d8",
     "sub": "#7b838b",
     "line": "#34393e",
     "accent": "#6d99ab",
     "accent2": "#6d7579",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.02,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS 1",
     "en": "Oswald"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Barlow"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "240ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "a11y-high-contrast",
   "name": "弱視配慮の高コントラスト",
   "summary": "本文を極端に濃くし、面の差も強く取る。拡大表示でも崩れない",
   "mood": [
    "読みやすい",
    "力強い",
    "誠実"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#1d1d1d",
     "sub": "#525252",
     "line": "#cbcbcb",
     "accent": "#2f6896",
     "accent2": "#87571f",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#ededed",
     "sub": "#a4a4a4",
     "line": "#393939",
     "accent": "#5e97c9",
     "accent2": "#9c6a33",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 16.15,
     "subOnBg": 7.49
    }
   },
   "font": {
    "heading": {
     "ja": "BIZ UDPGothic",
     "en": "Public Sans"
    },
    "body": {
     "ja": "BIZ UDPGothic",
     "en": "Public Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "a11y-colorblind",
   "name": "色覚多様性への配慮",
   "summary": "赤と緑を同時に意味に使わない。青と橙で差をつけ、明るさでも区別する",
   "mood": [
    "読みやすい",
    "誠実",
    "明快"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#0071a3",
     "accent2": "#a24200",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#009ed7",
     "accent2": "#bb5900",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "BIZ UDPGothic",
     "en": "Public Sans"
    },
    "body": {
     "ja": "BIZ UDPGothic",
     "en": "Public Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "6px",
     "provenance": "verified",
     "source": "Ant Design borderRadius (seed)"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "12px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-04 (0.75rem)"
    },
    "motion": {
     "duration": "150ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.01 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "print-ready",
   "name": "印刷を前提にする",
   "summary": "白地に濃い文字。影を使わず、線と余白だけで構造を示す",
   "mood": [
    "読みやすい",
    "整然",
    "無駄がない"
   ],
   "fontClass": "明朝系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#7a5c42",
     "accent2": "#68625c",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#ac8c71",
     "accent2": "#7a736d",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Noto Serif JP",
     "en": "Playfair Display"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Source Sans 3"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "240ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "projector-bright",
   "name": "明るい会場での投影",
   "summary": "白飛びを避けるため背景をわずかに沈め、文字を強く。細い線を使わない",
   "mood": [
    "読みやすい",
    "力強い",
    "明快"
   ],
   "fontClass": "装飾系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#f5fbff",
     "surface": "#e8eff8",
     "ink": "#202a33",
     "sub": "#586572",
     "line": "#c5d0dc",
     "accent": "#096d8e",
     "accent2": "#8e5130",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#0f1317",
     "surface": "#181e23",
     "ink": "#d4e0ed",
     "sub": "#768390",
     "line": "#313a43",
     "accent": "#499cbe",
     "accent2": "#a46443",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 13.97,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "Dela Gothic One",
     "en": "Anton"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Work Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "projector-dark",
   "name": "暗い会場での投影",
   "summary": "暗い背景に中間の明るさの文字。真っ白は眩しくなるので避ける",
   "mood": [
    "夜",
    "落ち着き",
    "読みやすい"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": null,
    "dark": {
     "bg": "#111315",
     "surface": "#1a1d21",
     "ink": "#c9d1d8",
     "sub": "#7b838b",
     "line": "#34393e",
     "accent": "#7696b2",
     "accent2": "#727195",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.05,
     "subOnBg": 4.84
    }
   },
   "font": {
    "heading": {
     "ja": "BIZ UDPGothic",
     "en": "Public Sans"
    },
    "body": {
     "ja": "BIZ UDPGothic",
     "en": "Public Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "verified",
     "source": "Ant Design borderRadiusLG"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "250ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium1 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "long-reading",
   "name": "長文を読ませる",
   "summary": "行間を広く、コントラストを上げすぎない。目の疲れを減らす",
   "mood": [
    "静か",
    "読みやすい",
    "落ち着き"
   ],
   "fontClass": "明朝系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#7b5c43",
     "accent2": "#69625d",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#ad8c71",
     "accent2": "#7a736d",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Noto Serif JP",
     "en": "Playfair Display"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Source Sans 3"
    }
   },
   "shape": {
    "radius": {
     "value": "10px",
     "provenance": "verified",
     "source": "Adobe Spectrum corner-radius-700"
    },
    "shadow": {
     "value": "0 1px 3px rgba(0,0,0,0.05), 0 1px 2px rgba(0,0,0,0.1)",
     "provenance": "verified",
     "source": "Mantine shadows.xs"
    },
    "spacing": {
     "value": "40px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-08 (2.5rem)"
    },
    "motion": {
     "duration": "700ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.slow.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "data-dense",
   "name": "情報量の多い画面",
   "summary": "余白を詰め、罫線を細く。数字が並んでも視線が迷わない",
   "mood": [
    "整然",
    "几帳面",
    "無駄がない"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#f7fafe",
     "surface": "#eaeff4",
     "ink": "#2e343a",
     "sub": "#5d646c",
     "line": "#c5ccd3",
     "accent": "#45687f",
     "accent2": "#7b5c44",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#111315",
     "surface": "#1a1d21",
     "ink": "#c9d1d8",
     "sub": "#7b838b",
     "line": "#34393e",
     "accent": "#7297af",
     "accent2": "#8e6d55",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.02,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS 1",
     "en": "Oswald"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Barlow"
    }
   },
   "shape": {
    "radius": {
     "value": "6px",
     "provenance": "verified",
     "source": "Ant Design borderRadius (seed)"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "12px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-04 (0.75rem)"
    },
    "motion": {
     "duration": "150ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.01 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "dashboard-dark",
   "name": "ダッシュボード",
   "summary": "暗い画面に色の点で状態を示す。長時間見続ける前提の濃さにする",
   "mood": [
    "夜",
    "整然",
    "技術"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": null,
    "dark": {
     "bg": "#0f1317",
     "surface": "#181e23",
     "ink": "#c5d0dd",
     "sub": "#768390",
     "line": "#313a43",
     "accent": "#36a1a6",
     "accent2": "#90649a",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.94,
     "subOnBg": 4.81
    }
   },
   "font": {
    "heading": {
     "ja": "IBM Plex Sans JP",
     "en": "IBM Plex Sans"
    },
    "body": {
     "ja": "IBM Plex Sans JP",
     "en": "JetBrains Mono"
    }
   },
   "shape": {
    "radius": {
     "value": "6px",
     "provenance": "verified",
     "source": "Ant Design borderRadius (seed)"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "12px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-04 (0.75rem)"
    },
    "motion": {
     "duration": "150ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.01 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "report-formal",
   "name": "報告書・レポート",
   "summary": "白地に黒。見出しだけ色を差し、あとは階層を余白で作る",
   "mood": [
    "フォーマル",
    "整然",
    "実直"
   ],
   "fontClass": "明朝系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#4d6582",
     "accent2": "#636363",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#7c95b4",
     "accent2": "#757575",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "BIZ UDPMincho",
     "en": "Libre Baskerville"
    },
    "body": {
     "ja": "BIZ UDPGothic",
     "en": "PT Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "240ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "proposal-deck",
   "name": "提案書",
   "summary": "青を基調に、要点だけ暖色で拾う。決めてほしい箇所が目に入る",
   "mood": [
    "誠実",
    "明快",
    "前向き"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#f5fbff",
     "surface": "#e8eff8",
     "ink": "#2b353e",
     "sub": "#586572",
     "line": "#c5d0dc",
     "accent": "#266a94",
     "accent2": "#8a5524",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#0f1317",
     "surface": "#181e23",
     "ink": "#c5d0dd",
     "sub": "#768390",
     "line": "#313a43",
     "accent": "#5698c5",
     "accent2": "#9e6838",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Kaku Gothic New",
     "en": "Inter"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "verified",
     "source": "Ant Design borderRadiusLG"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "250ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium1 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "earnings-deck",
   "name": "決算説明",
   "summary": "彩度を抑え、増減だけ色で示す。数字以外を騒がせない",
   "mood": [
    "几帳面",
    "フォーマル",
    "静か"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#f7fafe",
     "surface": "#eaeff4",
     "ink": "#2e343a",
     "sub": "#5d646c",
     "line": "#c5ccd3",
     "accent": "#4a6681",
     "accent2": "#785d41",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#111315",
     "surface": "#1a1d21",
     "ink": "#c9d1d8",
     "sub": "#7b838b",
     "line": "#34393e",
     "accent": "#7896b3",
     "accent2": "#8b7052",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.02,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS 1",
     "en": "Oswald"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Barlow"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "240ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "recruit-session",
   "name": "採用説明会",
   "summary": "明るい青と写真の余白。堅すぎず、ふざけすぎない中間を取る",
   "mood": [
    "前向き",
    "明るい",
    "親しみ"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "丸みのある",
   "color": {
    "light": {
     "bg": "#f5fbff",
     "surface": "#e8eff8",
     "ink": "#2b353e",
     "sub": "#586572",
     "line": "#c5d0dc",
     "accent": "#006f88",
     "accent2": "#874c74",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#0f1317",
     "surface": "#181e23",
     "ink": "#c5d0dd",
     "sub": "#768390",
     "line": "#313a43",
     "accent": "#409db8",
     "accent2": "#9d6189",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "LINE Seed JP",
     "en": "Outfit"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "16px",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 borderRadius3XLarge"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow8"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "300ms",
     "easing": "cubic-bezier(0.08, 0.82, 0.17, 1)",
     "provenance": "verified",
     "source": "Ant Design motionEaseOutCirc"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "training-material",
   "name": "研修資料",
   "summary": "手順が追える色分け。1画面に色を3つまでに抑える",
   "mood": [
    "読みやすい",
    "整然",
    "誠実"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#167459",
     "accent2": "#8a4b6d",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#4ca284",
     "accent2": "#a26082",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "BIZ UDPGothic",
     "en": "Public Sans"
    },
    "body": {
     "ja": "BIZ UDPGothic",
     "en": "Public Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "verified",
     "source": "Ant Design borderRadiusLG"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "250ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium1 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "webinar",
   "name": "ウェビナー",
   "summary": "画面共有で潰れない太さの線と、暗所でも眩しくない背景にする",
   "mood": [
    "読みやすい",
    "落ち着き",
    "現代的"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": null,
    "dark": {
     "bg": "#0f1317",
     "surface": "#181e23",
     "ink": "#c5d0dd",
     "sub": "#768390",
     "line": "#313a43",
     "accent": "#918bcb",
     "accent2": "#966394",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.94,
     "subOnBg": 4.81
    }
   },
   "font": {
    "heading": {
     "ja": "Murecho",
     "en": "Manrope"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "DM Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "verified",
     "source": "Ant Design borderRadiusLG"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "250ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium1 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "exhibition-booth",
   "name": "展示会のパネル",
   "summary": "遠くから読ませる前提。文字を太く、色数を絞る",
   "mood": [
    "力強い",
    "目を引く",
    "明快"
   ],
   "fontClass": "装飾系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#a8353a",
     "accent2": "#636363",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#e66e6e",
     "accent2": "#757575",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "Dela Gothic One",
     "en": "Anton"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Work Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "6px",
     "provenance": "verified",
     "source": "Ant Design borderRadius (seed)"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "12px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-04 (0.75rem)"
    },
    "motion": {
     "duration": "150ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.01 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "video-thumb",
   "name": "動画サムネイル",
   "summary": "縮小されても潰れない色差。縁取り前提で主役色を強くする",
   "mood": [
    "目を引く",
    "派手",
    "力強い"
   ],
   "fontClass": "装飾系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fff9ef",
     "surface": "#f9ecdf",
     "ink": "#3f3120",
     "sub": "#735f49",
     "line": "#d9c8b5",
     "accent": "#a6344c",
     "accent2": "#007673",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#17110b",
     "surface": "#241b11",
     "ink": "#deccb7",
     "sub": "#927e67",
     "line": "#433626",
     "accent": "#e46b7e",
     "accent2": "#00827f",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.99,
     "subOnBg": 5.79
    }
   },
   "font": {
    "heading": {
     "ja": "Dela Gothic One",
     "en": "Anton"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Work Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "short-video",
   "name": "ショート動画の字幕",
   "summary": "小さい画面で読ませる。背景に負けない濃さと、はっきりした差し色",
   "mood": [
    "目を引く",
    "読みやすい",
    "にぎやか"
   ],
   "fontClass": "装飾系",
   "shapeClass": "丸い",
   "color": {
    "light": null,
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#b68d00",
     "accent2": "#516fce",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.05,
     "subOnBg": 4.83
    }
   },
   "font": {
    "heading": {
     "ja": "Dela Gothic One",
     "en": "Anton"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Work Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "9999px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.full"
    },
    "shadow": {
     "value": "0 1px 2px -2px rgba(0,0,0,0.16), 0 3px 6px 0 rgba(0,0,0,0.12), 0 5px 12px 4px rgba(0,0,0,0.09)",
     "provenance": "verified",
     "source": "Ant Design boxShadowCard"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "260ms",
     "easing": "cubic-bezier(0.22, 1, 0.36, 1)",
     "provenance": "verified",
     "source": "Base Web easeDecelerate (easeOutQuintic)"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "sns-post",
   "name": "SNS投稿の画像",
   "summary": "タイムラインで指を止める強さ。1枚に主役の色を1つだけ置く",
   "mood": [
    "目を引く",
    "明るい",
    "にぎやか"
   ],
   "fontClass": "丸ゴシック系",
   "shapeClass": "丸みのある",
   "color": {
    "light": {
     "bg": "#fff9ef",
     "surface": "#f9ecdf",
     "ink": "#3f3120",
     "sub": "#735f49",
     "line": "#d9c8b5",
     "accent": "#8f3d8e",
     "accent2": "#805d00",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#17110b",
     "surface": "#241b11",
     "ink": "#deccb7",
     "sub": "#927e67",
     "line": "#433626",
     "accent": "#c873c6",
     "accent2": "#956d00",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.99,
     "subOnBg": 5.79
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS Rounded 1c",
     "en": "Poppins"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Nunito Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "16px",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 borderRadius3XLarge"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow8"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "300ms",
     "easing": "cubic-bezier(0.08, 0.82, 0.17, 1)",
     "provenance": "verified",
     "source": "Ant Design motionEaseOutCirc"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "banner-ad",
   "name": "バナー広告",
   "summary": "小さい面積で伝える。文字を詰め、押せる場所を色で明示する",
   "mood": [
    "目を引く",
    "勢い",
    "明快"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#a73920",
     "accent2": "#00728a",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#e47056",
     "accent2": "#007f99",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS 1",
     "en": "Oswald"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Barlow"
    }
   },
   "shape": {
    "radius": {
     "value": "6px",
     "provenance": "verified",
     "source": "Ant Design borderRadius (seed)"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "12px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-04 (0.75rem)"
    },
    "motion": {
     "duration": "150ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.01 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "lp-aggressive",
   "name": "LP・訴求を強く",
   "summary": "赤系の主役色と大きなボタン。迷わせず次の行動に運ぶ",
   "mood": [
    "勢い",
    "目を引く",
    "力強い"
   ],
   "fontClass": "装飾系",
   "shapeClass": "丸みのある",
   "color": {
    "light": {
     "bg": "#fff9ef",
     "surface": "#f9ecdf",
     "ink": "#3f3120",
     "sub": "#735f49",
     "line": "#d9c8b5",
     "accent": "#a83441",
     "accent2": "#007579",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#17110b",
     "surface": "#241b11",
     "ink": "#deccb7",
     "sub": "#927e67",
     "line": "#433626",
     "accent": "#e56c74",
     "accent2": "#008186",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.99,
     "subOnBg": 5.79
    }
   },
   "font": {
    "heading": {
     "ja": "Dela Gothic One",
     "en": "Anton"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Work Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "16px",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 borderRadius3XLarge"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow8"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "300ms",
     "easing": "cubic-bezier(0.08, 0.82, 0.17, 1)",
     "provenance": "verified",
     "source": "Ant Design motionEaseOutCirc"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "lp-trust",
   "name": "LP・信頼を重く",
   "summary": "青と広い余白。煽らずに、実績と根拠を読ませる",
   "mood": [
    "誠実",
    "落ち着き",
    "フォーマル"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#f7fafe",
     "surface": "#eaeff4",
     "ink": "#2e343a",
     "sub": "#5d646c",
     "line": "#c5ccd3",
     "accent": "#486781",
     "accent2": "#5f5f82",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#111315",
     "surface": "#1a1d21",
     "ink": "#c9d1d8",
     "sub": "#7b838b",
     "line": "#34393e",
     "accent": "#7596b2",
     "accent2": "#717195",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.02,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Kaku Gothic Antique",
     "en": "Archivo"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Source Sans 3"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "pricing-table",
   "name": "価格表",
   "summary": "おすすめの列だけ色で持ち上げ、他は静かにする",
   "mood": [
    "整然",
    "明快",
    "誠実"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#007461",
     "accent2": "#8d4b65",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#42a28d",
     "accent2": "#a45f7a",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Kaku Gothic New",
     "en": "Inter"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "verified",
     "source": "Ant Design borderRadiusLG"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "250ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium1 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "comparison",
   "name": "比較表",
   "summary": "○×だけでなく色でも差を出す。行の背景を交互に薄く敷く",
   "mood": [
    "整然",
    "読みやすい",
    "明快"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#00727f",
     "accent2": "#924c44",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#38a0ae",
     "accent2": "#a96158",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "BIZ UDPGothic",
     "en": "Public Sans"
    },
    "body": {
     "ja": "BIZ UDPGothic",
     "en": "Public Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "6px",
     "provenance": "verified",
     "source": "Ant Design borderRadius (seed)"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "12px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-04 (0.75rem)"
    },
    "motion": {
     "duration": "150ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.01 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "faq-page",
   "name": "FAQ",
   "summary": "質問と答えの階層を色の濃さで分ける。開閉の動きは短く",
   "mood": [
    "読みやすい",
    "落ち着き",
    "整然"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#f7fafe",
     "surface": "#eaeff4",
     "ink": "#2e343a",
     "sub": "#5d646c",
     "line": "#c5ccd3",
     "accent": "#3a6d6d",
     "accent2": "#44687f",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#111315",
     "surface": "#1a1d21",
     "ink": "#c9d1d8",
     "sub": "#7b838b",
     "line": "#34393e",
     "accent": "#689b9b",
     "accent2": "#537990",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.02,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Kaku Gothic New",
     "en": "Inter"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "verified",
     "source": "Ant Design borderRadiusLG"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "250ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium1 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "legal-terms",
   "name": "利用規約・約款",
   "summary": "装飾を捨て、番号と余白だけで読ませる。彩度は最小限",
   "mood": [
    "フォーマル",
    "静か",
    "几帳面"
   ],
   "fontClass": "明朝系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#f7fafe",
     "surface": "#eaeff4",
     "ink": "#2e343a",
     "sub": "#5d646c",
     "line": "#c5ccd3",
     "accent": "#42697d",
     "accent2": "#5d6569",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#111315",
     "surface": "#1a1d21",
     "ink": "#c9d1d8",
     "sub": "#7b838b",
     "line": "#34393e",
     "accent": "#6f97ad",
     "accent2": "#6d757a",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.02,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "BIZ UDPMincho",
     "en": "Libre Baskerville"
    },
    "body": {
     "ja": "BIZ UDPGothic",
     "en": "PT Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "state-warning",
   "name": "警告・注意喚起",
   "summary": "黄と黒。他のどの画面とも違って見えることを優先する",
   "mood": [
    "緊張感",
    "目を引く",
    "力強い"
   ],
   "fontClass": "装飾系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fff9ef",
     "surface": "#f9ecdf",
     "ink": "#3f3120",
     "sub": "#735f49",
     "line": "#d9c8b5",
     "accent": "#7d6000",
     "accent2": "#6a634f",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#17110b",
     "surface": "#241b11",
     "ink": "#deccb7",
     "sub": "#927e67",
     "line": "#433626",
     "accent": "#b18f01",
     "accent2": "#7a735f",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.99,
     "subOnBg": 5.79
    }
   },
   "font": {
    "heading": {
     "ja": "Stick",
     "en": "Staatliches"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Barlow"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "state-success",
   "name": "達成・完了",
   "summary": "緑と軽い弾み。終わったことが一目で分かる",
   "mood": [
    "前向き",
    "明るい",
    "軽快"
   ],
   "fontClass": "丸ゴシック系",
   "shapeClass": "丸い",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#087826",
     "accent2": "#00776d",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#46a652",
     "accent2": "#008379",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Maru Gothic",
     "en": "Quicksand"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Nunito"
    }
   },
   "shape": {
    "radius": {
     "value": "9999px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.full"
    },
    "shadow": {
     "value": "0 1px 2px -2px rgba(0,0,0,0.16), 0 3px 6px 0 rgba(0,0,0,0.12), 0 5px 12px 4px rgba(0,0,0,0.09)",
     "provenance": "verified",
     "source": "Ant Design boxShadowCard"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "260ms",
     "easing": "cubic-bezier(0.22, 1, 0.36, 1)",
     "provenance": "verified",
     "source": "Base Web easeDecelerate (easeOutQuintic)"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "state-urgent",
   "name": "緊急・障害",
   "summary": "赤を面で使い、動きを速くする。落ち着かせない方が正しい場面向け",
   "mood": [
    "緊張感",
    "勢い",
    "目を引く"
   ],
   "fontClass": "装飾系",
   "shapeClass": "角ばった",
   "color": {
    "light": null,
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#e66e67",
     "accent2": "#757575",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.05,
     "subOnBg": 4.83
    }
   },
   "font": {
    "heading": {
     "ja": "Dela Gothic One",
     "en": "Anton"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Work Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "240ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "focus-quiet",
   "name": "集中を切らさない",
   "summary": "動きを最小限にし、色数を2つに絞る。作業画面向け",
   "mood": [
    "静か",
    "無駄がない",
    "落ち着き"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#f7fafe",
     "surface": "#eaeff4",
     "ink": "#2e343a",
     "sub": "#5d646c",
     "line": "#c5ccd3",
     "accent": "#3b6d6a",
     "accent2": "#5c6665",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#111315",
     "surface": "#1a1d21",
     "ink": "#c9d1d8",
     "sub": "#7b838b",
     "line": "#34393e",
     "accent": "#689c98",
     "accent2": "#6d7676",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.02,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Kaku Gothic New",
     "en": "Inter"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "10px",
     "provenance": "verified",
     "source": "Adobe Spectrum corner-radius-700"
    },
    "shadow": {
     "value": "0 1px 3px rgba(0,0,0,0.05), 0 1px 2px rgba(0,0,0,0.1)",
     "provenance": "verified",
     "source": "Mantine shadows.xs"
    },
    "spacing": {
     "value": "40px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-08 (2.5rem)"
    },
    "motion": {
     "duration": "700ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.slow.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "kids-large",
   "name": "子ども向けの大きな字",
   "summary": "文字を大きく、色を明るく。ひらがなが多い前提の行間にする",
   "mood": [
    "かわいい",
    "明るい",
    "読みやすい"
   ],
   "fontClass": "装飾系",
   "shapeClass": "丸い",
   "color": {
    "light": {
     "bg": "#fff9ef",
     "surface": "#f9ecdf",
     "ink": "#3f3120",
     "sub": "#735f49",
     "line": "#d9c8b5",
     "accent": "#00777e",
     "accent2": "#874197",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#17110b",
     "surface": "#241b11",
     "ink": "#deccb7",
     "sub": "#927e67",
     "line": "#433626",
     "accent": "#00a4ac",
     "accent2": "#9f57af",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.99,
     "subOnBg": 5.79
    }
   },
   "font": {
    "heading": {
     "ja": "Mochiy Pop One",
     "en": "Righteous"
    },
    "body": {
     "ja": "Zen Maru Gothic",
     "en": "Nunito"
    }
   },
   "shape": {
    "radius": {
     "value": "9999px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.full"
    },
    "shadow": {
     "value": "0 1px 2px -2px rgba(0,0,0,0.16), 0 3px 6px 0 rgba(0,0,0,0.12), 0 5px 12px 4px rgba(0,0,0,0.09)",
     "provenance": "verified",
     "source": "Ant Design boxShadowCard"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "260ms",
     "easing": "cubic-bezier(0.22, 1, 0.36, 1)",
     "provenance": "verified",
     "source": "Base Web easeDecelerate (easeOutQuintic)"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "multilingual",
   "name": "多言語併記",
   "summary": "和文と欧文が並ぶ前提。書体の骨格をそろえ、行の高さを共通にする",
   "mood": [
    "整然",
    "読みやすい",
    "誠実"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#3c6b77",
     "accent2": "#4f6583",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#699aa7",
     "accent2": "#607695",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Kaku Gothic New",
     "en": "Inter"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "3px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.small"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "300ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium2 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "vertical-writing",
   "name": "縦書き主体",
   "summary": "縦組みの余白の取り方に合わせる。罫線は細く、行間を広く",
   "mood": [
    "和",
    "静か",
    "上品"
   ],
   "fontClass": "明朝系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#805850",
     "accent2": "#6a615f",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#b3887f",
     "accent2": "#7c7270",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Antique",
     "en": "Marcellus"
    },
    "body": {
     "ja": "Sawarabi Mincho",
     "en": "Crimson Pro"
    }
   },
   "shape": {
    "radius": {
     "value": "10px",
     "provenance": "verified",
     "source": "Adobe Spectrum corner-radius-700"
    },
    "shadow": {
     "value": "0 1px 3px rgba(0,0,0,0.05), 0 1px 2px rgba(0,0,0,0.1)",
     "provenance": "verified",
     "source": "Mantine shadows.xs"
    },
    "spacing": {
     "value": "40px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-08 (2.5rem)"
    },
    "motion": {
     "duration": "700ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.slow.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "tech-docs",
   "name": "技術文書・コード",
   "summary": "等幅を主役にし、コードの背景を一段沈める。長時間読める濃さにする",
   "mood": [
    "技術",
    "整然",
    "落ち着き"
   ],
   "fontClass": "等幅系",
   "shapeClass": "やわらか",
   "color": {
    "light": null,
    "dark": {
     "bg": "#0f1317",
     "surface": "#181e23",
     "ink": "#c5d0dd",
     "sub": "#768390",
     "line": "#313a43",
     "accent": "#36a0aa",
     "accent2": "#936397",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.94,
     "subOnBg": 4.81
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS 1 Code",
     "en": "JetBrains Mono"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Fira Code"
    }
   },
   "shape": {
    "radius": {
     "value": "6px",
     "provenance": "verified",
     "source": "Ant Design borderRadius (seed)"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "12px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-04 (0.75rem)"
    },
    "motion": {
     "duration": "150ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.01 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "academic",
   "name": "学術・論文",
   "summary": "白地に黒、図表は無彩色。主張ではなく内容で読ませる",
   "mood": [
    "学術的",
    "静か",
    "几帳面"
   ],
   "fontClass": "明朝系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#805658",
     "accent2": "#6a6161",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#b38789",
     "accent2": "#7c7272",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Old Mincho",
     "en": "EB Garamond"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "map-location",
   "name": "地図・位置情報",
   "summary": "背景を薄く保ち、目的地だけ強い色にする。地図に負けない差し色",
   "mood": [
    "明快",
    "整然",
    "現代的"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "丸みのある",
   "color": {
    "light": {
     "bg": "#f2fbff",
     "surface": "#e4f0fd",
     "ink": "#253544",
     "sub": "#51657a",
     "line": "#bccde0",
     "accent": "#007c48",
     "accent2": "#963a80",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#0d131a",
     "surface": "#151e27",
     "ink": "#bed2e6",
     "sub": "#6f849a",
     "line": "#2c3a49",
     "accent": "#05a769",
     "accent2": "#b05298",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.98,
     "subOnBg": 5.73
    }
   },
   "font": {
    "heading": {
     "ja": "Murecho",
     "en": "Manrope"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "DM Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "16px",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 borderRadius3XLarge"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow8"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "300ms",
     "easing": "cubic-bezier(0.08, 0.82, 0.17, 1)",
     "provenance": "verified",
     "source": "Ant Design motionEaseOutCirc"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "timeline-history",
   "name": "年表・沿革",
   "summary": "軸の線を細く、節目だけ色を置く。時間の流れを余白で表す",
   "mood": [
    "整然",
    "落ち着き",
    "伝統"
   ],
   "fontClass": "明朝系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#7e5949",
     "accent2": "#6a615e",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#b28978",
     "accent2": "#7b726f",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Noto Serif JP",
     "en": "Playfair Display"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Source Sans 3"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "org-chart",
   "name": "組織図",
   "summary": "階層を面の濃さで分け、線は目立たせない。名前が主役",
   "mood": [
    "整然",
    "フォーマル",
    "読みやすい"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#3a6d6f",
     "accent2": "#636363",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#689b9c",
     "accent2": "#757575",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Kaku Gothic New",
     "en": "Inter"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "process-flow",
   "name": "工程・フロー図",
   "summary": "手順の色を順に変え、現在地だけ強くする。矢印は細く",
   "mood": [
    "明快",
    "整然",
    "前向き"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#007469",
     "accent2": "#6f558f",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#3ca195",
     "accent2": "#8369a5",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS 2",
     "en": "Poppins"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "DM Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "verified",
     "source": "Ant Design borderRadiusLG"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "250ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium1 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "quiz-game",
   "name": "クイズ・ゲーム",
   "summary": "正誤の色をはっきり分け、弾む動きにする。反応が返る感じを出す",
   "mood": [
    "にぎやか",
    "軽快",
    "目を引く"
   ],
   "fontClass": "丸ゴシック系",
   "shapeClass": "丸い",
   "color": {
    "light": null,
    "dark": {
     "bg": "#0d131a",
     "surface": "#151e27",
     "ink": "#bed2e6",
     "sub": "#6f849a",
     "line": "#2c3a49",
     "accent": "#6d8eef",
     "accent2": "#c24f45",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.04,
     "subOnBg": 4.84
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS Rounded 1c",
     "en": "Poppins"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Nunito Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "9999px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.full"
    },
    "shadow": {
     "value": "0 1px 2px -2px rgba(0,0,0,0.16), 0 3px 6px 0 rgba(0,0,0,0.12), 0 5px 12px 4px rgba(0,0,0,0.09)",
     "provenance": "verified",
     "source": "Ant Design boxShadowCard"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "260ms",
     "easing": "cubic-bezier(0.22, 1, 0.36, 1)",
     "provenance": "verified",
     "source": "Base Web easeDecelerate (easeOutQuintic)"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "portfolio",
   "name": "ポートフォリオ",
   "summary": "作品を邪魔しない。画面はほぼ無彩色で、作品の色を主役にする",
   "mood": [
    "静か",
    "余白",
    "洗練"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": null,
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#8692b5",
     "accent2": "#757575",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.05,
     "subOnBg": 4.83
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Kaku Gothic New",
     "en": "Inter"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "6px",
     "provenance": "verified",
     "source": "Ant Design borderRadius (seed)"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "12px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-04 (0.75rem)"
    },
    "motion": {
     "duration": "150ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.01 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "personal-blog",
   "name": "個人ブログ",
   "summary": "手書き見出しとやわらかい背景。書いている人の顔が見える",
   "mood": [
    "親しみ",
    "あたたかい",
    "やわらかい"
   ],
   "fontClass": "手書き・筆",
   "shapeClass": "丸みのある",
   "color": {
    "light": {
     "bg": "#fdf9f6",
     "surface": "#f2eee9",
     "ink": "#38322c",
     "sub": "#69625a",
     "line": "#d1cac3",
     "accent": "#7d5b46",
     "accent2": "#6e633e",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#141210",
     "surface": "#201c19",
     "ink": "#d5cec7",
     "sub": "#888077",
     "line": "#3d3732",
     "accent": "#af8b75",
     "accent2": "#80744e",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.08,
     "subOnBg": 5.74
    }
   },
   "font": {
    "heading": {
     "ja": "Klee One",
     "en": "Caveat"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Cabin"
    }
   },
   "shape": {
    "radius": {
     "value": "16px",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 borderRadius3XLarge"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow8"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "300ms",
     "easing": "cubic-bezier(0.08, 0.82, 0.17, 1)",
     "provenance": "verified",
     "source": "Ant Design motionEaseOutCirc"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "newsletter",
   "name": "メールマガジン",
   "summary": "本文が主役。見出しと本文の差を大きさで作り、色は控える",
   "mood": [
    "読みやすい",
    "静か",
    "誠実"
   ],
   "fontClass": "明朝系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#43697e",
     "accent2": "#636363",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#7198ae",
     "accent2": "#757575",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "Noto Serif JP",
     "en": "Playfair Display"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Source Sans 3"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "release-note",
   "name": "リリースノート",
   "summary": "追加・変更・修正を色で分け、日付を淡く。差分が拾いやすい",
   "mood": [
    "整然",
    "技術",
    "明快"
   ],
   "fontClass": "等幅系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#f5fbff",
     "surface": "#e8eff8",
     "ink": "#2b353e",
     "sub": "#586572",
     "line": "#c5d0dc",
     "accent": "#30734a",
     "accent2": "#535e99",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#0f1317",
     "surface": "#181e23",
     "ink": "#c5d0dd",
     "sub": "#768390",
     "line": "#313a43",
     "accent": "#5ea074",
     "accent2": "#6471ad",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "M PLUS 1 Code",
     "en": "JetBrains Mono"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Fira Code"
    }
   },
   "shape": {
    "radius": {
     "value": "6px",
     "provenance": "verified",
     "source": "Ant Design borderRadius (seed)"
    },
    "shadow": {
     "value": "none",
     "provenance": "composed"
    },
    "spacing": {
     "value": "12px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-04 (0.75rem)"
    },
    "motion": {
     "duration": "150ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.moderate.01 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "onboarding",
   "name": "初回案内・チュートリアル",
   "summary": "1画面に1つだけ強調する。進捗を淡い色で常に見せる",
   "mood": [
    "やさしい",
    "明快",
    "前向き"
   ],
   "fontClass": "丸ゴシック系",
   "shapeClass": "丸みのある",
   "color": {
    "light": {
     "bg": "#f5fbff",
     "surface": "#e8eff8",
     "ink": "#2b353e",
     "sub": "#586572",
     "line": "#c5d0dc",
     "accent": "#3a6598",
     "accent2": "#665894",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#0f1317",
     "surface": "#181e23",
     "ink": "#c5d0dd",
     "sub": "#768390",
     "line": "#313a43",
     "accent": "#6895cb",
     "accent2": "#796ba9",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.97,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Maru Gothic",
     "en": "Quicksand"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Nunito"
    }
   },
   "shape": {
    "radius": {
     "value": "16px",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 borderRadius3XLarge"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow8"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "300ms",
     "easing": "cubic-bezier(0.08, 0.82, 0.17, 1)",
     "provenance": "verified",
     "source": "Ant Design motionEaseOutCirc"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "survey-form",
   "name": "アンケート・入力",
   "summary": "入力欄を面で囲み、必須だけ色を差す。答え終わるまで気を散らさない",
   "mood": [
    "整然",
    "読みやすい",
    "静か"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#f7fafe",
     "surface": "#eaeff4",
     "ink": "#2e343a",
     "sub": "#5d646c",
     "line": "#c5ccd3",
     "accent": "#3a6d71",
     "accent2": "#805755",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#111315",
     "surface": "#1a1d21",
     "ink": "#c9d1d8",
     "sub": "#7b838b",
     "line": "#34393e",
     "accent": "#689b9f",
     "accent2": "#946967",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.02,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "BIZ UDPGothic",
     "en": "Public Sans"
    },
    "body": {
     "ja": "BIZ UDPGothic",
     "en": "Public Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "8px",
     "provenance": "verified",
     "source": "Ant Design borderRadiusLG"
    },
    "shadow": {
     "value": "0px 1px 1px rgba(30,31,33,0.25), 0px 0px 1px rgba(30,31,33,0.31)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.raised"
    },
    "spacing": {
     "value": "24px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-06 (1.5rem)"
    },
    "motion": {
     "duration": "250ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium1 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "coupon-campaign",
   "name": "クーポン・キャンペーン",
   "summary": "期限と割引を最大にする。地色を強くして、切り取り線の勢いを出す",
   "mood": [
    "勢い",
    "目を引く",
    "にぎやか"
   ],
   "fontClass": "装飾系",
   "shapeClass": "丸い",
   "color": {
    "light": {
     "bg": "#fff9ef",
     "surface": "#f9ecdf",
     "ink": "#3f3120",
     "sub": "#735f49",
     "line": "#d9c8b5",
     "accent": "#a53453",
     "accent2": "#00766f",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#17110b",
     "surface": "#241b11",
     "ink": "#deccb7",
     "sub": "#927e67",
     "line": "#433626",
     "accent": "#e36b86",
     "accent2": "#00837a",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.99,
     "subOnBg": 5.79
    }
   },
   "font": {
    "heading": {
     "ja": "Dela Gothic One",
     "en": "Anton"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Work Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "9999px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.full"
    },
    "shadow": {
     "value": "0 1px 2px -2px rgba(0,0,0,0.16), 0 3px 6px 0 rgba(0,0,0,0.12), 0 5px 12px 4px rgba(0,0,0,0.09)",
     "provenance": "verified",
     "source": "Ant Design boxShadowCard"
    },
    "spacing": {
     "value": "20px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "260ms",
     "easing": "cubic-bezier(0.22, 1, 0.36, 1)",
     "provenance": "verified",
     "source": "Base Web easeDecelerate (easeOutQuintic)"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "membership",
   "name": "会員・特典",
   "summary": "深い色に金の差し色。持っている人だけの感じを出す",
   "mood": [
    "高級感",
    "フォーマル",
    "夜"
   ],
   "fontClass": "明朝系",
   "shapeClass": "丸みのある",
   "color": {
    "light": null,
    "dark": {
     "bg": "#111315",
     "surface": "#1a1d21",
     "ink": "#c9d1d8",
     "sub": "#7b838b",
     "line": "#34393e",
     "accent": "#928eb4",
     "accent2": "#74737b",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.05,
     "subOnBg": 4.84
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Old Mincho",
     "en": "EB Garamond"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Inter"
    }
   },
   "shape": {
    "radius": {
     "value": "24px",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 borderRadius4XLarge"
    },
    "shadow": {
     "value": "0 6px 16px 0 rgba(0,0,0,0.08), 0 3px 6px -4px rgba(0,0,0,0.12), 0 9px 28px 8px rgba(0,0,0,0.05)",
     "provenance": "verified",
     "source": "Ant Design boxShadow"
    },
    "spacing": {
     "value": "28px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-emphasized"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "case-study",
   "name": "導入事例",
   "summary": "写真と数字を並べる前提。引用部分だけ背景を沈める",
   "mood": [
    "誠実",
    "整然",
    "落ち着き"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "やわらか",
   "color": {
    "light": {
     "bg": "#f7fafe",
     "surface": "#eaeff4",
     "ink": "#2e343a",
     "sub": "#5d646c",
     "line": "#c5ccd3",
     "accent": "#3b6c76",
     "accent2": "#805850",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#111315",
     "surface": "#1a1d21",
     "ink": "#c9d1d8",
     "sub": "#7b838b",
     "line": "#34393e",
     "accent": "#699aa4",
     "accent2": "#946b62",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.02,
     "subOnBg": 5.72
    }
   },
   "font": {
    "heading": {
     "ja": "Zen Kaku Gothic Antique",
     "en": "Archivo"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Source Sans 3"
    }
   },
   "shape": {
    "radius": {
     "value": "12px",
     "provenance": "verified",
     "source": "GitHub Primer borderRadius.large"
    },
    "shadow": {
     "value": "0 0 8px rgba(30,31,33,0.16), 0 0 1px rgba(30,31,33,0.12)",
     "provenance": "verified",
     "source": "Atlassian elevation.shadow.overflow"
    },
    "spacing": {
     "value": "32px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-07 (2rem)"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-standard"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "podcast-audio",
   "name": "音声・ポッドキャスト",
   "summary": "波形が映える暗い背景。再生まわりだけ明るい色にする",
   "mood": [
    "夜",
    "落ち着き",
    "現代的"
   ],
   "fontClass": "ゴシック系",
   "shapeClass": "丸みのある",
   "color": {
    "light": null,
    "dark": {
     "bg": "#0f1317",
     "surface": "#181e23",
     "ink": "#c5d0dd",
     "sub": "#768390",
     "line": "#313a43",
     "accent": "#838ece",
     "accent2": "#8d659d",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 11.94,
     "subOnBg": 4.81
    }
   },
   "font": {
    "heading": {
     "ja": "Murecho",
     "en": "Manrope"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "DM Sans"
    }
   },
   "shape": {
    "radius": {
     "value": "24px",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 borderRadius4XLarge"
    },
    "shadow": {
     "value": "0 6px 16px 0 rgba(0,0,0,0.08), 0 3px 6px -4px rgba(0,0,0,0.12), 0 9px 28px 8px rgba(0,0,0,0.05)",
     "provenance": "verified",
     "source": "Ant Design boxShadow"
    },
    "spacing": {
     "value": "28px",
     "provenance": "composed"
    },
    "motion": {
     "duration": "400ms",
     "easing": "cubic-bezier(0.2, 0, 0, 1)",
     "provenance": "verified",
     "source": "Material Design 3 duration-medium4 + easing-emphasized"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  },
  {
   "id": "print-poster",
   "name": "掲示ポスター",
   "summary": "1メートル先から読ませる。文字を極端に大きくし、色を2色に絞る",
   "mood": [
    "力強い",
    "目を引く",
    "無駄がない"
   ],
   "fontClass": "装飾系",
   "shapeClass": "角ばった",
   "color": {
    "light": {
     "bg": "#fafafa",
     "surface": "#eeeeee",
     "ink": "#333333",
     "sub": "#636363",
     "line": "#cbcbcb",
     "accent": "#9e366f",
     "accent2": "#636363",
     "onAccent": "#ffffff",
     "onAccent2": "#ffffff"
    },
    "dark": {
     "bg": "#131313",
     "surface": "#1d1d1d",
     "ink": "#d0d0d0",
     "sub": "#828282",
     "line": "#393939",
     "accent": "#db6da5",
     "accent2": "#757575",
     "onAccent": "#0b0d10",
     "onAccent2": "#ffffff"
    },
    "contrast": {
     "inkOnBg": 12.1,
     "subOnBg": 5.76
    }
   },
   "font": {
    "heading": {
     "ja": "Stick",
     "en": "Staatliches"
    },
    "body": {
     "ja": "Noto Sans JP",
     "en": "Barlow"
    }
   },
   "shape": {
    "radius": {
     "value": "0px",
     "provenance": "verified",
     "source": "IBM Carbon（テーマトークンに角丸が1件も無いことをSCSS実測で確認）"
    },
    "shadow": {
     "value": "0 0 2px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.14)",
     "provenance": "verified",
     "source": "Microsoft Fluent 2 shadow2"
    },
    "spacing": {
     "value": "16px",
     "provenance": "verified",
     "source": "IBM Carbon spacing-05 (1rem)"
    },
    "motion": {
     "duration": "110ms",
     "easing": "cubic-bezier(0.2, 0, 0.38, 0.9)",
     "provenance": "verified",
     "source": "IBM Carbon duration.fast.02 + standard-productive"
    }
   },
   "provenance": {
    "type": "original",
    "source": "色相と明るさを指定して計算（コントラストは機械で保証）"
   }
  }
 ]
}