motion-web について
motion-webは、クリエイティブ・マーケティング向けWebサイトを構想から仕上げまで扱うデザイン・構築スキルです。動きの設計だけでなく、ページデザインや公開前の調整も重視します。
主な機能
- 01クリエイティブサイトの一貫構築
- 02モーション概念と操作演出の設計
- 03ページ構成、コピー、コンポーネントの策定
- 04本番品質、アクセシビリティ、性能の監査
活用シーン
- 01短い依頼からランディングページを制作
- 02参考サイトをもとに新しいページを構築
- 03モーションと静止画デザインを点検
- 04ページ状態とメタデータを仕上げる
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ feitangyuan/ motion-web --skill motion-webインストール後、Claude Code で/motion-webを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSE.gitignoreREADME.mdcases/AUTHORING.mdindex.htmlcases/char-curtain/README.mdindex.htmlcases/ink-crowd/README.mdindex.htmlcases/lyre-crows/README.mdindex.htmlcases/press-stack/README.mdindex.htmlcases/string-clock/README.mdindex.htmlcases/toy-flipbook/README.mdindex.htmlcases/wheel-rail/README.mdindex.htmldata/visual-bank.jsonreferences/baseline-ui.mdbuild-mode.mdaffordance.mdchoreography-arc.mdcomponents.mddesign-slop.mdcomposition-guide.mdimage-asset-pipeline.mdhandfeel.mdlight-3d.md詳細
motion-web
モーションを中心としたクリエイティブなウェブ制作。このスキルは、参考資料 → コンセプト → 仕様 → 構築 → 監査のすべての段階に対応します。
このスキルはウェブページ全体を構築します。 ページの良さを生み出すのはモーションですが、仕事はそれだけではありません。モーションについて何も触れていない依頼でも――「ランディングページを作って」「この公式サイトを作って」――このスキルの対象であり、成果物は完成したサイトです。スタック、トークン、セクション、コピー、コンポーネント、状態、メタデータ、デプロイまで含みます。
優先順位 — 1 と 2 は同等です:
- モーションのコンセプトとインタラクションの振り付け
- ページデザイン — 構造、文字のスケール、配色、余白のリズム、何も動いていない状態での見た目
- 構築済み成果物としてのページ — セクションとそのコピー、コンポーネントの語彙、トークンレイヤー、通常の操作経路から外れた状態(
page-blueprints.md、components.md、project-setup.md、production-polish.md) - ページを引き立てる場合に限り、軽めの 3D またはキャンバスを使用する
- パフォーマンス、アクセシビリティ、モーション低減時の代替表示
デフォルトのような見た目のページに優れた仕掛けを載せても、失敗です。 モーションは強みであり、言い訳ではありません。このスキルで最もよくある失敗は、誰もデザインしていないレイアウトに、気の利いたインタラクションを 1 つだけ貼り付けて公開することです。モーションをオフにしたときに見せるのが恥ずかしいページなら、完成ではありません。スプリングの調整をどれだけ重ねても解決しません。デザインは時間的な手順の 2 番目ではなく、最終的に必ず満たすべきもう 1 つの要件です。→ references/page-design.md、references/design-slop.md
これは、クリエイティブなウェブサイトとマーケティングサイトの一群を対象にした、デザインと構築のスキルです。ランディングページ、製品ページ、ポートフォリオ、スタジオサイト、キャンペーン、エディトリアル、軽めのドキュメントなどをエンドツーエンドで構築します。ダッシュボード/管理画面/データ密度の高いアプリ UIを対象としたスキルではなく、本格的な 3D シーン生成ツールでもありません(それらは 3d-scene-studio が担当します)。価格表、サインイン画面、コンソールのスクリーンショットなど、アプリのような要素を含むクリエイティブページは対象内ですが、ログイン後の製品インターフェースは対象外です。
エージェントの意図検出(重要 — まずお読みください)
ユーザーの指示はごく短いことがよくあります。最小限の入力から意図を検出し、自律的に行動してください。
シグナル → 意図の対応表
| ユーザーの入力 | 検出された意図 | 対応 |
|---|---|---|
| 「ウェブページを作って」/「ランディングページ/公式サイト/ポートフォリオを作って」、トピックはあるが参考資料はない | full-build | 仕掛けだけでなく、サイト全体を作ります。 page-blueprints.md → project-setup.md → page-design.md → ビルド → components.md → production-polish.md |
| 「このページには何を載せる?」/「どんなセクションが必要?」/「情報設計」/「コピーはどう書く?」 | blueprint | page-blueprints.md — 軸となる構成を選び、実際のコピーを書き、創作した事実にはすべて印を付けます |
| 「ナビゲーション」/「ボタン」/「フォーム」/「カード」/「フッター」/「FAQ」/「料金表」/「モーダル」/「コンポーネント」 | component | components.md — まず表現の使い分け表を確認し、次に状態マトリクスを確認します。各状態がなければ、コンポーネントは完成ではありません |
| 「どの技術スタックを使う?」/「Astro と Next のどちら?」/「プロジェクトの始め方」/「design token」/「フォント」/「デプロイ」 | setup | project-setup.md — ページの段階 ≠ モーションの段階です。段階 0 から始めて、順に進みます |
| 「デモっぽくて完成品に見えない」/「OG プレビューが空」/「favicon がない」/「404」/「空の状態」/「ダークモード」/「フォームの検証がない」 | polish | production-polish.md — すべて検証可能です。推測せずに §9 を実行します |
| URL のみ(ほかのテキストなし) | url-drop | 開いて分解します(Replicate Mode の手順 1–2)。次に、これを再構築するのか、それともユーザー自身のコンテンツの参考にするのかを尋ねます |
| URL +「ウェブページを作って」または「これを参考にして」 | replicate → build | まず URL を分解し(Replicate Mode)、次にユーザー自身のコンテンツ向けにモーションのコンセプトを提案します |
| 参考資料 +「再現して case として登録」/「skill に保存」/「事例にする」 | case-authoring | cases/AUTHORING.md — まず Phase 0 のゲートを通します。参考資料から画像を取り除き、それでも何も残らない場合は、構築後ではなく構築前に素材を確定します |
| URL +「再現」/「似たものを作って」/「これを参考に作って」 | replicate | 分解 → パターンに対応付け → すぐに構築します。 |
| 論文/記事/ブログの URL | doc-drop | 読んで、抽出可能な値を伴う手法を挙げ、求められたらそのうち 1 つを使って構築します(以下の Document / Article Drop を参照) |
| 曖昧な依頼(「かっこいいウェブページを作って」/「ポートフォリオを作って」) | freeform-build | composition-guide.md を通じて進めます → スタイルと展開をそれぞれ独立して選びます |
| トピックのみ(「AI に関するランディングページを作って」) | spec → build | composition-guide.md を通じて進めます → ビジュアルの方向性を提案し、すぐに構築します |
| 参考資料付きの詳細な依頼 | spec → build | MOTION_SPEC.md を作成 → 承認を得る → 構築します |
| 「レビューして」/「問題はある?」/「gap」 | audit | design-slop.md に従い、静止フレームも含めて、既存の制作物におけるモーション/パフォーマンス/アクセシビリティの不足を調べます |
| 「見栄えが悪い」/「ダサい」/「AI が作ったみたい」/「デザイン性がない」/「普通」 | design-audit | モーションをオフにしてスクリーンショットを撮り、design-slop.md のゲートを実行します。スプリングは調整しません — 問題は静止フレームにあります |
| 「レイアウト」/「組版」/「文字が小さすぎる」/「余白」/「構成」/「各セクションがみな同じ長さ」 | design | page-design.md — マクロ構造、文字サイズのスケール、余白のリズムを、現時点のアワード受賞作と比較して検討します |
| 既存ページに「追加して…」 | incremental-build | 新しいモーションを追加して、現在の実装を拡張します |
| 動画の参考資料(Pinterest/Dribbble/X のクリップ) | video-ref | 停止 — コードを書く前に、以下の Video Reference Protocol を実行します |
| 既存のモーションが「手触りが悪い」/「ぎこちない」/「追従が遅い」/「単調」 | handfeel-tune | handfeel.md に照らして監査します — スプリング、速度カップリング、セカンダリモーション |
| 何かに追従するもの(カメラ、カーソル、レール、ツールチップ)が「追従はするが、あと少し足りない」/「カクカクする」/フレームレートによって手触りが変わる | handfeel-tune | §1 のスプリングではありません — handfeel.md §7:1-exp(-k·dt)、speed/k の先行項、フィルター後の補正は行わないこと |
| 「GSAP を使わずにできる?」/入場アニメーションや視差だけ/もっと軽くしたい | build | まず段階 1.5 を確認します — ネイティブの animation-timeline / animation-trigger / sibling-index() → build-mode.md の段階表 + pattern-recipes.md #16。Firefox では静的な最終状態を表示します |
| 素材が実在する場所の実写/スキャンで、その中に入っていく必要がある | build | 段階 5.5 — モデルより先に 3D Gaussian splats を使います → build-mode.md の段階表 |
| カード/画像を曲げる、旗、ページめくり、スクリーンショットを立体面に貼り付ける、「skew では足りない」 | warp | コーナーピン・ホモグラフィ → pattern-recipes.md #17。すべての四角形をガードし、エッジの傾きを asin(h/w) に制限します — ガードされていない四角形は、エラーもなく画面サイズのブロックを描画します |
| 既存のモーションについて「クリックできない」/「1 つしかクリックできない」/「誰も気づかない」/「見えない」 | affordance-audit | まずヒットテストのコードには触れません。 affordance.md に照らして監査します — 通常、仕組みには問題がなく、ユーザーを促す要素が不足しているか、表示されなくなっています |
| 画像素材が大量にあり、「3D シーンにして」/「奥行きを出して」/「カメラが中に入れるようにして」 | image-plane-3d | モデルには手を出しません。 実際の透視カメラ内に平面を配置してシーンを作ります → image-plane-3d.md(段階表の段階 5) |
| レンダリング済みのシーンについて「継ぎ目が目立つ」/「なじんでいない」/「貼り付けたように見える」 | image-plane-3d | アートに触れる前に測定します:アセットバッチごとの平均 R−B と輝度、接触シャドウの有無 → image-plane-3d.md §6–7 |
| 「これは何で描くべき?」/「DOM と canvas のどちら?」/ページが div とシステムフォントしか出力できない/参考資料が明らかに DOM では作れない | render-layer | 仕組みより先にレイヤーを決めます → render-layer.md §1。レイヤーは宣言であり、case README に記載し、verify_case.py --layer で検証します |
| 手描き/インク線/輪郭線スタイルの 3D、「レンダリングではなく描いたように見える」、boil/線の揺れ/紙のテクスチャ | ink-render | render-layer.md §3 — 深度の不連続部分の輪郭線(法線の折れ目は無効化)、静的な warp と動的な boil を分離、60fps レンダリングに対して boil のクロックは 11Hz |
| 切り抜きが必要な raw plates/レンダリング、「画像切り抜き」、「素材をシーンにどう入れる?」、「画像がぼやける」 | asset-pipeline | 画像自身の背景をキーイングし、アルファ境界ボックスに合わせてトリミングし、メタデータをスクリプトで記述し、要素ごとの解像度予算を出力します → image-asset-pipeline.md |
| ヘッドレスの検証全般、数値が目視結果と一致しない、「どう検証する?」 | verify | まずプローブ用のサーフェスを構築します — 固定可能なクロック、__seek、__hold、状態の終了 — その後に測定します → verification-harness.md |
| スクロールタイムラインについて「この部分では何も起きない」/「リズムが悪い」/「文字が一気に大量に表示される」 | timeline-audit | すべてのトラックを 1 つのスクロール軸に並べます。間延びする箇所は、1 つのレイヤーが遅いのではなく、プラトーが重なっている状態です → timeline-orchestration.md |
| 多数のアセットを含む長いスクロールシーン、「カクつく」、「読み込みが遅い」、「メモリがあふれる」、大量の plate | scene-streaming | 画面範囲に基づいて有効化し、大きなアップロードを分割し、スキャン中に処理を譲り、完全に破棄します → scene-streaming.md |
| BGM、環境音、インタラクションの効果音、「効果音が少なすぎる」、「雰囲気音が聞こえにくいが、うるさくするのも避けたい」など、音が関わるもの | scene-audio | 3 つのバス(bgm/hand/world)、シーンごとのカーブ、大きなベッド音に重ねる離散イベントを使います → scene-audio.md |
| どのモードを使うか、ユーザーに尋ねてはいけません。 モードを判別して、そのまま進めてください。まったく異なる成果物が2つ考えられ、概要が本当に曖昧な場合に限り、作業を止めてください(例:仕様書と、すぐに構築を始めること)。 |
動画リファレンスのプロトコル(硬规则 — 不许猜)
適用条件:実際に視聴できない動画がリファレンスの場合 — Pinterest のピン、Dribbble のショット、X の動画、站外短链。タイトルや説明文から動きはわかりません。
- ライブページがないと結論づける前に、スレッドを読んでください。 作者はほぼ必ず返信に URL を投稿しています。また、返信を読めば、その作品がそもそもウェブページなのかどうかもわかります。2026-09-02 の実測:前のセッションでは、動画リファレンスに URL がないと判断し、Phase 1 でフレーム計測に時間を費やしました。7件すべてにライブサイトがあり、投稿者本人が掲載していました。さらに、ある投稿の4本の動画のうち3本は Jitter / Figma Motion / Rive で制作されたもので、ウェブ上には実装がありませんでした(
cases/AUTHORING.mdPhase 1)。safe-x tweet <url> --jsonを実行し、返信内のt.coリンクをすべて解決してください。 - 推測で動きを実装してはいけません。 抽出できたのがタイトルや説明文だけなら、わかるのはテーマであり、動きではありません。それでも実装すると、イテレーションを丸ごと1回無駄にします。これは記録に残っている失敗例です(2026-07-06、海鮮ヒーロー:動きが「軌道」だと推測したが、実際は上昇する斜線で、2回作り直すことになった)。
- 主要なキーフレームを2~3枚、すぐに依頼してください。 一文で:「这个视频我打不开,截 2-3 帧关键画面(入场/中间/离场)发我」。
- コーディングの前に、動きの軌道を明確な幾何学として示し、確認を得てください。
- アンカーポイント:要素がどこから入場し、頂点に達し、どこへ退場するか(隅、3分割位置)
- 姿勢:回転が軌道の接線に沿うか、一定に保たれるか、遅れて追従するか
- 二次的な反応:背景の図形、線、テキストなど、ほかに何がどのように動くか
- 例:「右下から入場 → 中央 → 左上へ退場する上昇斜線。魚の頭は常に左上を向く」— 推測の誤りはコード内ではなく、ここで見つけます。
- その後に限り、pattern-recipes / handfeel.md を参照して実装します。
スクリーンショット1枚の場合も同じルールに従います。1フレームでわかるのは姿勢であり、軌道ではありません。経路が重要なら、フレームを追加で依頼してください。
複製モード(复刻模式)
ユーザーが「复刻」/「做一个类似的」/「能不能做这种效果」と添えて URL を送った場合は、内容を分解してから構築してください。保存の工程はなく、成果物はページです。
実行パスの再現
-
ページを開き、3つのレイヤーとして読み取ります。利用できるブラウザツール(Claude Preview、
browser-use、Playwright)を使います。スタック(ライブラリ、イージング、キーフレーム、CSS 変数。バンドルから特定できます)、スクロール演出(どの要素がどの範囲で固定されるか、レールとその px 距離、パララックスの速度、スクラブされるプロパティ、出現ポイント。スクロール位置を約9か所サンプリングし、その間のgetBoundingClientRectと計算済みスタイルの差分を確認します)、そして WebGL レイヤー(プログラム数、描画呼び出し数、カスタム uniform 名。シェーダーソースが必要な場合は、ページスクリプトの実行前にgetContextをラップします)。測定可能な2つの側面は、次のスクリプトで確認できます。静的なページの情報(セクション、ナビゲーション、ボタン、トークンのスケール、メディア、メタ情報、モバイルでのオーバーフロー)はscripts/measure_structure.py <url>、実際にホイール操作したときにページのどの程度が動くかはscripts/measure_churn.py <url>で確認します。 URL には必ず対象のサイトそのものを指定してください。ギャラリーの一覧ページ(awwwards.com/sites/<slug>)は使わないでください。一覧ページではギャラリー独自の装飾が表示され、異なる6つの受賞サイトを調べても、同じライブラリ、同じキーフレーム、同じフォントが返ってきます。 -
分解する — 確認した内容を示し、印象ではなく数値を引用します。
- 「GSAP 3.12 + ScrollTrigger + Lenis。.home-animate__wrapper は 0.25–0.50 の範囲で固定され、その間に
.iconが +1545px 横移動します。出現アニメーションは 0.25/0.38/0.62 の3段階の stagger です」 - 「背景はネイティブ WebGL2 で、14 個の program、944 回の描画呼び出しがあります。uniform には bloomStrength/blurTexture1-5 と cloudCoverage/cloudDensity があり、UnrealBloom + 体積雲が使われています」
コンテキストだけを根拠に「WebGL が使われている」と報告してはいけません。サイズが指定されていない 300×150 のコンテキストで、リンク済みプログラムがない場合は、シーンではなく Modernizr のような機能検出です。リンク済みプログラム数と描画呼び出し数を数えてください。
- 「GSAP 3.12 + ScrollTrigger + Lenis。.home-animate__wrapper は 0.25–0.50 の範囲で固定され、その間に
-
pattern-recipes に当てはめる —
references/pattern-recipes.mdから最も近いレシピを探します。 -
不足を補う — 参照先で使われていてレシピにないものは、抽出した値をもとに一から実装します。
-
すぐに構築する — ページのひな形を作成して実行し、見た目を確認します。
-
報告する — 「[site] の主要な動きを再現しました。[X] を使って [Y] を実装し、オリジナルとの違いは [Z] です」
再現 ≠ コピー
- 行うこと:インタラクションのパターン、動きの特徴、タイミングの感覚を再現します。
- 行わないこと:独自のブランドカラー、正確なコピー文、特定可能な製品 UI をコピーしません。
- 行うこと:ユーザー独自のコンテンツや配色に合わせて手法を応用します。
- 報告では、どの部分を応用し、どの部分をオリジナルに忠実に再現したかを明記します。
自由形式の構築モード(ユーザーから指定がない場合)
ユーザーが「做个网页」/「随便做」/「自己想一个主题」と言った場合、または簡単で曖昧なテーマ(例:「做一个AI agent平台落地页」)を示した場合、創造性を発揮するよう求められています。 汎用テンプレートを使わず、固定的な1対1のルーティングマッピングも行わず、確認の質問もしないでください。
フリーフォームのアクションパス(ランタイム・クリエイティブループ — 創造は実行中に生まれ、ドキュメントの中にはない)
ユーザーに参考資料を提示してもらう必要は、絶対にありません。しかし、新しさもこのドキュメントを読むことで生まれるわけではありません。ドキュメントは制約と物理法則であり、答えではありません。 新しさは、実行時に新鮮な入力をサンプリングすることと、自分自身が批評家となるビルド・テスト・キルのループから生まれます。次を実行してください。
- 現在の状況をサンプリングする(記憶ではなく、実行時の入力です):今月の
Awwwards SOTD/Godly/SiteInspire の一覧を開き、受賞ページそのものを3~5件見てください。作品を見るのであって、ギャラリーページを見てはいけません。模倣するのではなく、現在の最前線を把握し、それを超えるためです。2分間。
エフェクトだけでなく、構成と文字のスケールを見てください。ページが今らしく見えるかを決めるのは、その半分です(
page-design.md§1)。 - トピック自体の物理法則から、生成オペレーター(composition-guide §5)を使って3つの候補メカニクスを考案してください。墓場にあるもの、または手順1で見たものに似ている候補はすべて破棄します。
- 決める前にスケッチする:シグネチャーとなるインタラクションを、最小限の単一ファイルのプロトタイプとして作成します(div 1つ、rAF ループ1つ、ダミーコンテンツ、15分未満)。 ページ全体ではなく、メカニクスだけです。
- 自分でテストする:現在利用できるブラウザツールを使って実行し、操作します。まず Claude Preview(
preview_start→preview_eval/preview_click→preview_screenshot)、使えない場合はbrowser-useを使います。マウスを動かし、ホイールを素早く回し、極端な状態でスクリーンショットを撮り、それから証拠を確認します。次のように考えてください。 10秒も遊べば飽きてしまうのではないか? 2枚のフレームを見せただけで、インタラクションのルールを推測できるか? うまくいかなければ、オペレーターを変えるか、次の候補を選んでください。ユーザーに目の代わりを頼んではいけません。 - ページをデザインする — メカニクスを組み込む前に、独立した工程として行います。
「パレットを選んでコーディングを始める」ことではありません。順番に、次の3つを作成します。
(a) ブループリントと実際のコピー →
references/page-blueprints.md— どのセクションがあり、実際に何を書くのか。 (b) マクロ構成、文字のスケール、間隔のリズム →references/page-design.md。具体的な値はdata/visual-bank.jsonに記載します。 (c) トークンレイヤーとスケール →references/project-setup.md§2~§5。すでに機能するページにメカニクスを配置します。これは「デザインされていないページに、壊れた動きを貼り付ける」という結果を生む順序とは正反対です。 - 実装する:コンポーネントとその状態マトリクスは
references/components.md、スプリングはreferences/motion-tokens.md、ページ全体の連携は handfeel.md に従います。 - デザインゲート — 何かを見せる前に実行してください。 ページのすべての動きを無効にして(
prefers-reduced-motionを使うか、メカニクスをコメントアウトして)スクリーンショットを撮り、その静止画だけを見て判断します。- アニメーションがまったくなくても、この静止画は Awwwards に掲載されるでしょうか? 正直な答えが「中央揃えの見出しと3枚のカード」なら、デザインはまだ完成していません。
references/design-slop.mdのスロップゲートを実行します。1つでも該当したら、出荷ではなく修正してください。- その後で初めて、動きに関する質問をします。10秒も遊べば飽きてしまうのではないか? 2枚のフレームを見れば、インタラクションのルールを推測できるか? 手順4に合格し、ここで不合格になるページは、このループで防ごうとしている、文書化された失敗パターンです。手順4でテストしたのは、メカニクスだけです。
- 仕上げる:
references/production-polish.md— head、OG、favicon、404、通常の利用経路から外れた状態、そして §9 の10項目の手動チェックを確認します。ここまで終えなければ、成果物ではなくデモです。 - メカニクスを葬る:composition-guide の墓場に1行追記し、二度と再利用できないようにします。これでループの新鮮さが保たれます。
生き残った候補が2つあり、方向性が本当に異なる場合に限り、ユーザーに提案してください。それ以外の場合は、最善の候補をそのまま実装し、あとからメタファーを説明します。
ドキュメント/記事のドロップ
ユーザーが論文、記事、デザインブログをドロップした場合は、内容を読み、抽出可能な価値(ライブラリ、イージング、タイミング、シェーダーのアイデア、レイアウトルールなど)を含むテクニックを2〜3個挙げ、質問を1つします。「今すぐそのうちの1つを使って構築しますか? それともブリーフを続けますか?」と尋ねます。構築すると答えた場合、最も特徴的なパターンをページの主要なモーションコンセプトとして採用し、他のすべてと同じビルド順序に従います。何も保存されません。重要なテクニックは、リリース後に pattern-recipes.md に記録します。
モード(ユーザーから明示的に指示された場合)
spec:ブリーフと参考資料から、実装可能なMOTION_SPEC.mdを作成するbuild:承認済みのモーション重視のウェブ体験を実装するaudit:既存のモーション重視のページまたは実装を確認し、不足点を調べるdesign-audit:問題が動き方ではなく、見た目にある場合 — まず静止画のフレームを評価するreplicate:参考ページを数値で分解し、そのパターンをユーザーのコンテンツで再構築するfreeform-build:ユーザーから指示がない場合 → 独自にクリエイティブな判断を行うfull-build:サイト全体を0から構築する — ブループリント+コピー、スタック+トークン、デザイン、コンポーネント、モーション、仕上げblueprint:ページに必要なセクションを決め、そのコピーを書くcomponent:特定のコンポーネントを状態マトリクスとともに設計/構築するsetup:ページのスタックを選び、プロジェクトのひな形を作成し、トークン/タイプ/フォントのレイヤーを整えるpolish:仕上げの工程 — メタ情報、OG、404、想定外の状態、ダークモード、リリース前のチェック
ビルド順序(必ず従うこと)
- ページのスタックを選ぶ →
references/project-setup.md§1 — HTML ファイル 1 つ/Vite/Astro/Next。これはモーションのスタックとは 別の段階です。互いに選択を左右させないでください。段階 0 から始めます。 0.5 モーションのスタックの段階を選ぶ →references/build-mode.mdTech Stack Decision Ladder — 目標を達成できる最も低い段階を選びます。リファレンスが「3D に見える」からといって R3F をデフォルトにせず、シーンに奥行きが必要だからといって モデル をデフォルトにしないでください(段階 5 ではシーン全体を画像で構築します)。 - ブループリントを選び、コピーを書く →
references/page-blueprints.md— どのセクションをどの順序で配置するか、そして各セクションに実際にどんな言葉を載せるかを決めます。レイアウトは実際のテキストに応じて決まります。プレースホルダーのコピーを使っているなら、ページはまだデザインされていません。次にアークの種類を選びます →references/choreography-arc.md - ページをデザインする →
references/page-design.md— マクロ構造、文字サイズのスケール、パレット、余白のリズムを決めます。具体的な値はdata/visual-bank.jsonにあります。これは独自の成果物を伴う実際の工程であり、単なる作業項目の一つではありません。モーションをオフにした状態でページがどう見えるかを決め、その静止画だけでも納得できるようにしてください。 2.5 トークン層とスケールを構築する →references/project-setup.md§2–§5 — 3 段階のトークン、実際に段差のある流動的な文字サイズのスケール、スペースのスケール、メトリクスのオーバーライドを設定したフォント、@layerの順序を整えます。コンポーネントを作った後に行うと、すべてのコンポーネントを編集することになります。 - モーションのトークンを選ぶ →
references/motion-tokens.md(デュレーション、イージング、スプリング) 3.5 コンポーネントの語彙を構築する →references/components.md— 表現の方向性を選びます(クリエイティブ向けとプロダクト向けは、測定可能なほど異なるシステムです)。次に、各インタラクティブコンポーネントの状態マトリクスをすべて定義します。:focus-visible、エラー状態、空の状態のいずれかが欠けていることが、「デモのように見える」最も一般的な原因です。 - パターンライブラリを確認する → 再利用可能な実装については
references/pattern-recipes.mdを参照します。 - シーンを画像アセットから構築する場合は、ランタイムの前にアセットパイプラインを実行する →
references/image-asset-pipeline.md。切り抜き、スクリプトによるメタデータ、要素ごとの解像度予算を整えます。背景のキーイングを間違えたアセットや、0.83 倍に拡大されているアセットは、どれだけシェーダーを工夫しても修正できません。同時にトポロジー(カメラを動かすか、ワールドを動かすか →image-plane-3d.md§12)を決め、シーンが長い場合はストリーミングポリシーも決めます →references/scene-streaming.md references/build-mode.mdに従って実装しながら、プローブ用サーフェスも構築する →references/verification-harness.md§1(__seek/__hold/ピン留め可能なクロックの後付けは、最初から構築するより手間がかかります)- 複数トラックのスクロールタイムラインでは、トラックを横方向に配置します →
references/timeline-orchestration.md。ページにサウンドがある場合は →references/scene-audio.md - 明らかなボタンではないインタラクティブ要素には、
references/affordance.mdに従って操作の手がかりを示します。 - モーションのチェックより先にデザインのチェックを行う →
references/design-slop.md。すべてのモーションを無効にしたスクリーンショットを撮り、まずそのフレームを評価します。動いている間だけ成立するページは、デザインされたとは言えません。 - 仕上げる →
references/production-polish.md— head/OG/favicon、404、通常の操作経路から外れた状態、ダークモードの方針、§9 の 10 項目の手動チェックを完了します。ここを省くと、優れたページもデモのように見えてしまいます。 - デスクトップ+モバイル+モーション低減+操作の手がかりのチェックリストと数値的な判定基準を確認します。
必須の事前確認 — 任意ではなく、推奨でもありません: GSAP、Framer Motion、Three.js/R3F のコードを一行でも書く前に、references/build-mode.md の該当するフレームワークのセクション(Framework-Specific Rules)と「Failure Patterns to Avoid」表を開いてください。そのパターンを覚えている自信があっても、必ず確認します。この表は、覚えているパターンが気づかないうちに後退する事態を防ぐために存在します(たとえば、React StrictMode で gsap.context()/.revert() を使わない GSAP の .from())。この手順を省略し、すでに記載されている修正方法を一から考え直すのは、スタイルの選択ではなくプロセス上の失敗です。
必要なものだけを読み込む
| モード | 参照するドキュメント |
|---|---|
spec | motion-spec.md + baseline-ui.md + choreography-arc.md |
| 例外なく、すべてのビルド | page-design.md + design-slop.md — 静止画も成果物の半分です |
| ケースのクラスに該当する概要がある場合、または仕組みが必要な場合 | まずケースの README.md(可以照搬/不许照搬 の区分があります)、次にその index.html |
| すべての 0→1 サイト構築 | page-blueprints.md + project-setup.md + components.md + production-polish.md — セクションとコピー、技術スタックとトークン、コンポーネントの状態、仕上げ |
参照なしの full-build / 「做个网页」 | page-blueprints.md + project-setup.md + page-design.md + design-slop.md + composition-guide.md + components.md + production-polish.md |
blueprint / 「该有哪些 section」 / 情報設計 / コピー | page-blueprints.md + page-design.md §1 |
component / ナビゲーション / フォーム / カード / フッター / ポップアップ | components.md + baseline-ui.md + (明白なボタンでない場合は affordance.md) |
setup / 技術スタック / トークン / フォント / デプロイ | project-setup.md(+ モーションスタックについては build-mode.md の段階) |
polish / デモのように見える / OG / favicon / 404 / 空の状態 / ダークモード | production-polish.md + baseline-ui.md |
build | build-mode.md + motion-tokens.md + pattern-recipes.md + (canvas/WebGL の場合は light-3d.md) |
image-plane-3d / 画像アセットから構築したシーン / 「つなぎ目が目立つ」 | image-asset-pipeline.md + image-plane-3d.md + light-3d.md + verification-harness.md + (長い場合は scene-streaming.md、シーン内にクリック可能な要素がある場合は affordance.md) |
scene-streaming / 長いスクロールの大きなシーン / カクつく / 読み込みが遅い | scene-streaming.md + image-asset-pipeline.md §6, §9 |
asset-pipeline / 切り抜き / 素材メタデータ / 画像がぼやける | image-asset-pipeline.md(+ ランタイムでの使用方法については image-plane-3d.md §2) |
verify / オラクルの構築 / 指標と見た目が一致しない | verification-harness.md + affordance.md §9 |
timeline-audit / スクロール駆動の多拍編成 / 「この区間では何も起きない」 | timeline-orchestration.md + choreography-arc.md |
scene-audio / BGM / 環境音 / インタラクション効果音 | scene-audio.md + verification-harness.md §3 |
freeform-build | page-design.md + design-slop.md + composition-guide.md + choreography-arc.md + visual-bank.json + motion-tokens.md + pattern-recipes.md |
audit | build-mode.md + motion-tokens.md |
handfeel-tune / 「操作についてこない」という不満 | handfeel.md + motion-tokens.md |
affordance-audit / 「クリックできない」/「見つけられない」という不満 | affordance.md + handfeel.md |
video-ref | (上記のプロトコル)、続いて handfeel.md + pattern-recipes.md |
replicate / url-drop | pattern-recipes.md + handfeel.md + page-design.md + design-slop.md |
| ポートフォリオ/個人サイト | page-blueprints.md(ポートフォリオのブループリント)+ components.md |
基本ルール
- モーションは最終的な仕上げレイヤーではなく、主要なデザイン素材です。
- 何かの後を追うものは、スプリングで解決する問題ではありません。 カメラ、カーソル、レール、ツールチップは、到着して停止する必要があります。移動する対象に対する定常状態の遅れは
speed / kで、これは調整の失敗ではなく算術です。フィルターの後に書いた補正は、次のフレームで元に戻されます(handfeel.md§7)。 - 「ふわふわ」は静止率であり、イージングカーブではありません。 イージングはソースの読み取り速度を変えますが、新しい状態が現れる頻度は変えません。カーブに手を加える前に、ほぼ同一の隣接フレームの割合を測定してください(
timeline-orchestration.md§11)。 - 4段目ではなく、1.5段目から段階を上げてください。 リビール、視差バンド、スタガー、スクロールスパイナビゲーションは、今やネイティブCSSです。まず完成状態を作成し、タイムラインは
@supportsの後ろに置いてください。Firefoxはそのいずれも実装していません(build-mode.mdの段階表、pattern-recipes.md#16)。 - ビルドできること ≠ 見つけられること。 インタラクションは動けば完成ではありません。初めての訪問者が、説明されなくても見つけられたときに完成です。明らかなボタンではないインタラクティブ要素はすべて、
references/affordance.md§1 の3つの質問に答える必要があります。 - テストには、あなたが想定するユーザーの不満ではなく、ユーザーの不満そのものを反映させる必要があります。 ユーザーが「開けない」と言っているのに、チェックが「開ける」と判定するなら、別のものを測っています。まずユーザーの質問を見つけてください。
- 何を示す数値があれば証明になるかを決めてから、その数値を出力してください。 スクリーンショットはコストが高く、何も決着させません。カバレッジスイープ、ハンドオフサイズの誤差、安全領域への収まり、表示時間と滞在時間の比較は、すべてヘッドレス実行1回で測れます(
references/affordance.md§9)。 - 汎用的な品質スコアは、テストがないより悪いものです。 すべてのオラクルは、明示された不満を1つ反映させる必要があります。美的な評価は、実物を見る人間に委ねてください(
verification-harness.md§0)。 - ランタイムより先にアセットを整えてください。 画像から構築するシーンでは、メタデータはビルド成果物であり、手作業で編集するものではありません。何かを正しい位置に見せるために
baselineを微調整しているなら、バグは上流にあります(image-asset-pipeline.md)。 - 動きのない区間は、1つの遅いレイヤーではなく、複数レイヤーの平坦な区間が同時に重なって発生します。 スクロールスケジュールは横方向に読んでください(
timeline-orchestration.md§1)。 - 納品物はページであり、仕掛けではありません。 モーションの指定がないブリーフでも、このスキルの対象です。仕事は完成したサイトを作ることです。実際のコピーを含むセクション、各状態を備えたコンポーネントの語彙、トークンレイヤー、メタ情報、404ページが必要です。美しいインタラクションを1つと、その周りのテンプレートを返すことは、このスキルのデザイン面全体が防ごうとしている失敗です。
- 2つのコンポーネントの作法は、測定可能なほど異なるシステムです。 クリエイティブページは、半径の中央値が1、影付き要素が0、ボタンの37%が大文字、ナビゲーションCTAなし、フッターは2列です。プロダクトページは、半径の中央値が8、影付き要素が約18個、大文字は1%、ナビゲーションCTAが2つ、リンク35個の5列フッターです(n=32、
components.md§1)。どちらかを選び、一貫性を保ってください。プロダクト向けコンポーネントでクリエイティブページを作ることこそ、「AIが作ったみたい」という不満の原因です。 - 状態のないコンポーネントは、作られたとは言えません。 hover /
:focus-visible/ active / disabled / loading / error / empty / success。欠けている状態は、ほぼ決まってユーザーが気づく状態です(components.md§2)。 - レイアウトより先にコピーを用意してください。 レイアウトは実際のテキストの長さに応じて決まります。プレースホルダーのコピーをもとに組んだページは、作り直す必要があります。ユーザーから事実が提供されていない場合は、下書きを作成し、創作した箇所すべてに
[…]を付けてください。証拠を捏造してはいけません(page-blueprints.md§4、design-slop.mdA8)。 - 受賞歴があることと、きちんと作られていることは別です。 同じ32サイトの調査では、受賞サイト18件のうち2件に390px幅で横方向のオーバーフローがあり、5件には
<h1>がなく、画像のうち表示領域を確保していたのはわずか37%でした。デザイン言語は参考にしても、品質管理の不備は真似しないでください(production-polish.md)。 - 射影変換には成立条件があり、それに違反すると何も通知されずに失敗します。 コーナーピン(
matrix3d)は、変換先の四角形が凸である間だけ正常に動作します。それを超えるとホモグラフィが無限遠を通って反転し、コンソールエラーなしで画面サイズのブロックが描画されます。四角形を検証し、さらに辺の傾きをasin(h/w)に制限してください。検証だけでは目に見えるスナップが発生します(pattern-recipes.md#17)。 cases/からは仕組みだけを取り入れ、外観は真似しないでください。 ソース全体を収録しているのは、ソルバーを一から作り直すのが無駄だからです。しかし、配色、文字の値、グリッド、セクションの順序、コピーはそのケース固有のものです。ロゴを差し替えただけのケースページは、近道ではなく失敗例です。- イベントハンドラーを通らないプローブは、誰も使わない経路をテストしています。 あるケースは、プローブ主導のすべてのチェックを通過しました。着地誤差は0.0000°、すべてのスロットに到達可能で、両端でクランプされました。それでも、実際のスクロールホイールにはまったく反応しませんでした。すべてのオラクルは、少なくとも1つの実際のジェスチャーを実行する必要があります。
verify_case.pyは今ではすべてのページでこれを実行します。 - プレースホルダーの形状は、すべてのオラクルを通過しても、何も伝わらない見た目のままです。 写真の代わりに置いたグレーのグラデーション矩形は、文字比率、動きのない区間、状態マトリックスのチェックを通過しても、技術図のように見えます。これを検出する指標はありませんし、作るべきでもありません。制作後ではなく、制作前にアートワークを用意できるか判断してください(
cases/AUTHORING.mdPhase 0)。 - 入力を固定して収束させるオラクルでは、誰もが実際に使うページをテストできていません。
--stringsのすべてのアサーションは、当初、固定時計に対して実行されていました。固定を外すと、終点のずれや、いつまでも揺れが止まらないボディは、どのアサーションでも検出できません。仕掛けが何によって動くにせよ、自由に動かすパスを追加してください。(そして、ライブ表示が不穏な値を示すときは、まずループが動いているか確認してください。非表示のブラウザータブではrequestAnimationFrameが停止し、シミュレーションが固まると、もっともらしいものの完全に誤った数値が出ます。cases/string-clockが踏んだ落とし穴 #7。) - インラインスタイルの宣言は、
:hoverを含むスタイルシート内のすべてのルールより優先されます。el.style.zIndexでスタック順を指定すると、.thing:hover{z-index:…}がひそかに無効になります。勝ったルールと同じルールによる色の変化があるため、ホバー自体は動いているように見えます。そのため、前面への移動は起きず、何も通知されません。要素ごとの状態はカスタムプロパティ(el.style.setProperty('--z', n))として設定し、ルール側でその値を読み取ってください。 - 自分で開ける参考資料を要約したものから作り始めないでください。 以前、引き継ぎ用に動画を1文に圧縮したセッションがありました。その文から作った結果、参考動画にはないリサイズ可能なウィンドウ、参考動画にはないイージング付きの登場、1フレームあたりの移動量が0pxのスクロールするマーキーができました。動画はずっとディスク上にありました。コンタクトシートからはポーズが分かりますが、軌道、リズム、静止が分かるのはフレームだけです 。
- オラクルのしきい値は、測定値か、明示できるデザイン要件から決めてください。好みで決めてはいけません。 最近傍のCVが [0.08, 0.40] の範囲にあれば「固まっていない」とする基準はもっともらしく見えましたが、参考例自体のスコアは0.507でした。ランダムに配置され、カードは大きく重なっています。本当の契約は別にありました。Z順は到着順であり、最新のカードが埋もれることはない。こちらはアサーションに値します。
- ページが何で描かれているかを、何をするか決める前に決めてください。 7つのケースがDOM + CSSとシステムフォントスタックで実装されていた一方、参考例はすべて別のものでした。スキル内でこの質問が一度もされなかったため、どのブリーフも既定でdivに落ち着いていました。レイヤーはケースのREADMEで宣言し、
verify_case.py --layerで検証してください(references/render-layer.md§1、cases/ink-crowd)。 - ソースにしか存在しない数値もあります。 フレームが手描きに見えるかを決める11 Hzのボイルクロックは、フレーム差分では見えません。カメラ移動中の変位はサブピクセルで、フレームの95%に差分があり、自己相関は平坦です。ピクセルを測っていたら、自信満々に誤った答えを出していたでしょう。バンドルを取得して中身を読んでください(
cases/ink-crowd§1)。 - 「レイアウトではなく、雰囲気を取り入れる」とは、まずモーションを取り入れることです。 参考例の配色と粒状感を取り入れ、静的なページを出荷したビルドは、最低限のすべてのゲートを通過しました。ページは見た目こそ正しくても、何もしませんでした。デザインに手をつける前に、レイヤーごとの速度と、何かが動いている時間の割合を数値で記録し、参考例のモーションを特徴づけてください。入力なしでも動いていることをアサートしてください。
- フレーム全体の相関では、複数レイヤーのシーンを測定できません。 異なる速度で、時には反対方向に動くレイヤーは、相殺し合って中央値の移動量が0になります。代わりに、レイヤーごとに色または特徴のマスクを追跡してください。
- タイル状テクスチャの周期は、近くにある反復要素のすべての寸法と照合してください。 1440pxのキャンバス上で、11本の帯(1本あたり130.9px)に128pxのノイズタイルを重ねると、縦の筋が発生します。これはフィルムグレインには決してないアーティファクトです。ノイズをピクセルに書き込めば、この種の問題全体を避けられます。
- 3Dシーンに向けるポインターは、地面ではなく、コンテンツがある平面と交差させてください。 フィギュアの高さは1.75単位です。人物に向けたレイを
y = 0と交差させると、人物のはるか後ろに着地し、地平線近くでは完全に逸れていきます。症状は「少しずれている」ではありません。画面の一部の範囲でだけ動き、ほかの場所では完全に反応しないのに、カウンターは活動中を示す仕掛けです(cases/ink-crowd§4、verify_case.py --follow)。 - 「画面を固定する」方法は2つあり、互いに両立しません。 ホイールを乗っ取り、レールを移動させる場合、進捗は自由に計算できます。しかし祖先要素が変換されているため
position:stickyは決して発火せず、固定する子要素はすべて手動で配置する必要があります。スクロールをそのままにしてsticky; top:0; height:100vhの画面を積み重ねる場合、固定は自動で行われ、進捗は(scrollY - offsetTop) / innerHeightとしてドキュメントから取得する必要があります。レイアウトを始める前に選択してください。一方にもう一方を後付けするには、書き直しが必要です(cases/wheel-rail§2、cases/press-stack§2)。 - 1ビューポートずつ固定するスタックでは、滞在時間がまったくありません。 各画面が完全に見えるのはスクロール位置がちょうど1つのときだけです。そのため、画面内のアニメーションは、すでに半分覆われている間にすべて再生され、スクロールは動きのないものに見えます。各画面に
margin-bottom: 100vhを設定すると、ボックスのサイズを変えずに1ビューポート分の滞在時間を確保できます。その後、進捗を分けます。画面全体が見えている間はコンテンツに(scrollY - top) / vhを使い、退出時の効果にのみ(scrollY - top - vh) / vhを使います(cases/press-stack§2)。 - オラクルではレイアウトを読み取り、決めつけてはいけません。
--stackは「1ビューポートにつき1画面」とハードコードしていたため、レイアウトに滞在時間が加わった途端、8画面中1画面が固定されていると報告しました。ページではなくチェックが原因で、合格から不合格に変わったのです。セクションの位置はプローブから取得してください(cases/press-stack§3)。 - 固定スタックでは、まず画面の下部が隠れます。 次の画面が下からせり上がるため、
margin-top:autoで配置したものが最初に覆われます。この理由だけで、最初のビルドでは見出し、大きな数字、セクション区切り線がすべて消えました。コンテンツは上部3分の2に配置してください(cases/press-stack§2)。 - アルバムジャケットは描画できますが、人間は描画できません。 ジャケットは色面と2つの図形、1行の文字でできています。レコードは同心円状の溝と、細いスペキュラー反射弧2本で構成されます。ディスク全体に広い光沢をかけると、金のプレートのように見えます。どちらもグレーの矩形でごまかすより、生成したほうがよいでしょう。ポートレートや手は別です。スロットを省いて、その周りを再設計してください。プリミティブを積み重ねて人物を作ってはいけません(
cases/press-stack§4)。 - 密度はデザイン手法であり、その下地によって生まれます。 参考例にあるモーションの仕組みをすべて実装しても、ページが薄く感じられることがあります。参考例の584要素に対し、こちらは184要素でした。足りなかったのはコピーではありません。参考例がすべての下に敷いている技術図の下地、つまり細いグリッド、動作を示すルール、範囲マーカーでした。自ら描画し、ポインターを追跡する要素を20個加えるだけで、同じ画面でも参考例のワイヤーフレームのようには見えなくなります(
cases/wheel-rail§3)。 - ディスク上の参考動画は、ライブサイトより優先されます。
blink.tradeのヘッドレススクリーンショットをもとに作ったこのケースは、配色、文字、スクロールの仕掛けを再現しても、「ぼんやりした丸いものがまったく変化しない」と言われました。動画を見ると、特徴的な要素はレーダースイープだと分かりました。点線のリングの上を針が回り、柔らかい扇形の跡が0.92秒で閉じて消えます。静止画では、ページの特徴となる唯一の要素を表現できません。動画があるなら、ライブサイトにアクセスできても、制作前に必ず視聴してください(cases/wheel-rail§2b — これで作り直しになったのは2回目です)。 - 入力駆動と環境的な動きは、どちらか一方を選ぶものではありません。 「インタラクションのモーションとは、マウスが生み出す動き」という修正は、何が欠けているかを指摘するものであり、環境的なレイヤーを取り除いてよいという許可ではありません。参考例には両方あります。ホイールとポインターがレイアウトとすべてのリビールを動かし、スイープはそれとは無関係に回り続けます。両方をアサートしてください。実入力による変化と、入力がなくても動作していることです(
verify_case.py --rail)。 - レールが移動するだけでは、振り付けとは言えません。 ホイールを乗っ取ってレールを動かしても、子要素がすべて静止したままなら、衣装を着ただけのスクロールバーです。それでも、誰かが目視する前に
--railの4つのアサーションを通過しました。実際のホイール入力によって何個の要素が変化するかを測定してください。参考例では64%が動きましたが、却下されたビルドは13%でした。変化率をアサートし、さらに要素の一部が遷移の途中にあることもアサートしてください。そうしないと、状態間でスナップするだけのページでも数を満たし、スライドショーのように見えてしまいます(cases/wheel-rail§3)。 - テキストを分割しなければ、ページにはアニメーションさせるものがありません。 参考例ではすべての単語がインラインブロックのspanで囲まれており、その数は296個です。
translateY(8px)/opacity 0、transition-duration: 0sが設定され、CSSに任せず、値をフレームごとに書き込んでいます。この1つの決定が、64%の大部分を占めます。値を自分で書き込むことで、ホイールを逆方向に動かしたときにリビールも逆戻りします(cases/wheel-rail§2)。 - すでに画面上にある要素のスクロール連動リビールは、1フレーム目で「完了」状態になります。 ヒーロー図の描画演出は一度も再生されませんでした。静止時点でセクションの
topが0となり、進捗が即座に1にクランプされたためです。静止時点ですでに見えている要素には、独自の読み込み用クロックが必要です。スクロールに連動させられるのは、画面下から始まる要素だけです(cases/wheel-rail§2)。 - インタラクションのモーションとは、マウスが生み出す動きです。 ホイールとポインターだけで、それ以外はありません。マウスが止まっていても独自のクロックで漂い、呼吸し、溶けていくページはスクリーンセーバーです。「モーションを追加」というブリーフには応えても、本当の要望には応えられません。制作前に、どの入力で動くのかを確認してください(
cases/wheel-rail§0)。 - コードが書き込んだ値を読み取るプローブでは、画面に何が表示されているか分かりません。 瞬時に切り替わることを検証するオラクルが
el.style.opacityを読み取っていました。これはループが設定するインライン値です。ところが、コピーにtransition: opacity 250msを追加しても、完璧なパラパラ漫画だと判定しました。トランジションはインライン値間を補間しますが、インライン値の読み取り結果は目標値へ直接飛ぶためです。getComputedStyleなら、60サンプル中19サンプルで遷移途中を検出します。これはさらに一段深い、プローブだけの教訓です。最初のバージョンがテストするのは描画ではなく意図です(cases/toy-flipbook§5 #2)。 - 発生確率の低い効果には、しきい値を超えるドライバーが必要です。そうでなければ、アサーションは実行されていません。 デスクトイのキックは
|v| > 2.2のときだけ発生し、その後に6%の確率で実行されます。ポインターのスイープはちょうど2.2がピークだったため、該当テストは0/5となり、仕組みの故障と、テストが一度も発動しなかったケースを区別できませんでした。しきい値を超える入力で動かし、ピーク値を出力し、しきい値を超えなかった場合は失敗させてください。実行されなかったテストは、黙って合格にも不合格にもせず、実行されなかったと報告する必要があります(cases/toy-flipbook§5 #3)。 - コメントには、コードが一度も実現していない動作が書かれていることがあります。 出荷済みコードに
s.v = s.v < -30 ? -s.v * 0.35 : 0があり、コメントには「跳ね返ってから止まる」と書かれていました。落下中のs.vは正なので、この分岐は一度も実行されず、すべてのトイが接触と同時に停止していました。見た目には問題ありませんでした。そこに跳ね返りがあるべきだと知らなければ、気づけないのです。動きをアサートするのではなく、その結果であるスクワッシュをアサートしてください。そうすれば、動かない分岐がすぐに見つかります(cases/toy-flipbook§5 #1)。 file://ではCSSマスクが拒否され、<img>は許可されるため、ページの一部だけが照らされ、ほぼ正しく見えてしまうことがあります。mask-image: url(img/x.webp)は、オリジンnullからのCORSフェッチです。写真は読み込まれますが、ライティングはひそかに失敗し、証拠はコンソールの3行だけです。マスクをdata:URIとしてインライン化し、表示画像は外部のままにしてください。マスクが持つのはアルファ値だけなので、320pxでRGBがフラットなら約4 KBです。切り抜きに使う写真の75 KBに比べて小さく済みます。- オラクルの基準値は、待って得るのではなく、静止状態を測定してください。固定の待機時間を使った結果、ポインターからの力がZEROに設定されたコピーがすべてのアサーションを通過しました。
verify_case.pyはスモークテストで実際のホイールを1回動かします。ホイールを減衰するインパルスに変換するページでは、ハードコードされた2.6秒の待機が2.7秒の減衰時間内に収まり、ページは自力で動き続けていました。そのため、それ以降の変位はすべてポインターによるものとして計上されました。プローブで動きがしきい値未満になるまでポーリングし、収束しなければ失敗させてください。今日の十分な待機時間は、誰かが登場演出を追加した瞬間に不十分になります(cases/char-curtain§5 #1)。 - 構造に左右される比率では、その構造を生んだ力をテストできません。 異方性のポインター押し(xは最大、yは0.35)を「水平変位が垂直変位を大きく上回るか」としてテストできるように見えました。実際のケースでは7.9倍でした。しかし、バイアスを1.0に設定したコピーでは8.8倍となり、さらに大きくなりました。垂直方向のリンクが、糸に沿ってノードを滑らせることでy方向の動きを吸収するためです。代わりに、コードが実際に主張する構造上の性質をアサートしてください。1列を押しても、離れた列には影響しないことです(
cases/char-curtain§5 #2)。 - フレームごとに一度計算するレート制限は、レート制限ではありません。 予算は9つのエミッターを処理するループの前に読み込まれ、フラグとして渡されていたため、同じフレームで9つすべてが発火できました。上限を4としていたのに6回発生し、9回まで許されていました。ループ内で予算を再読み込みし、プッシュの直前にも再度ガードしてください。目視では分からない超過なので、オラクルでしか見つけられません(
cases/lyre-crows§5 #1)。 - アサーションが、構造上ページに生成できない文字列と一致することがあります。 完全に正常なページに対し、置換後の文全体をチェックしたところ失敗しました。末尾のノード数が固定され、それより長いものは切り捨てられるためです。変更後の値が厳密に1つの値であることを確認するのではなく、インタラクション前に取得したスナップショットと比較し、状態が変化したことをアサートしてください(
cases/lyre-crows§5 #2)。 - Canvasだけのページは、フロアの入力チェックには見えません。それはチェックではなくページ側の問題です。 変更のシグネチャは
scrollY、計算済みスタイル、innerTextです。Canvasのピクセルはそのどれにも含まれません。<canvas>1つだけのデモはモーションにあふれていても、「実際のホイールイベントで何も変化しない」という判定に失敗することがあります。また、まだ操作していない訪問者やスクリーンリーダーの利用者にも、チェッカーと同じくほとんど情報がありません。DOMに小さなライブ表示を追加すれば、両方を一度に解決できます(cases/char-curtain§5 #3)。 - 100回に1回の不安定なフェッチでも、スイート全体の信頼性は損なわれます。通常の原因はCDNフォントです。 2つのケースでは、似た書体に置き換えるとデザインの移植ではなく変更になってしまうため、Google Fontsの
<link>を残していました。筋の通った理由ですが、誤った結論です。スイート全体の実行でconsole/page errorsが1回だけ失敗し、意図的に12回再実行したところすべて正常でした。再現できない断続的な失敗は、一貫した失敗よりも悪質です。最初に行われるのは、スイートを信頼しなくなることだからです。本来の書体は維持したまま、ネットワークをなくしてください。OFLの原本を取得し、各ページが描画する文字だけにサブセット化します(可変セリフ体なら65.8 → 40.9 KB)。そのうえでインライン化してください。 - オラクルの正しさは、ケースを意図的に壊して証明してください。
--railの乗っ取りアサーションはpreventDefault()を削除したコピーでも通過しました。overflow:hiddenがすでにscrollYを固定していたためです。チェックには意味がなく、そのままでは永遠に意味のないままでした。新しいオラクルを登録する前に、必ずそのケースを意図的に壊したコピーに対して実行してください(cases/wheel-rail§3)。 position:stickyは、変換された祖先要素の中では動作しません。 乗っ取ったレール内で固定する要素は、レールのオフセットに合わせて手動で配置する必要があります。これはデバッグすべきバグではなく、仕様です(cases/wheel-rail§2)。- ポストプロセスには、デバッグ用チャンネルを付けて出荷してください。そうでなければデバッグ不能です。 「頭部が黒い塊になる」と言われ、カプセルメッシュを調べ始めました。生のカラーバッファをひと目見たところ、人物の上に影がありました。カメラの基底が反転していたのです。最初に書くフレームから、生カラー、線形深度、エッジ強度を公開してください(
cases/ink-crowd§4)。 - 静止状態も仕様の一部です。 参考例の504フレーム中444フレームでは、変化したピクセルが0個です。モーションの予算全体が「何かがいつ現れるか」に割り当てられています。ページの個性が断続的な動きなら、アサーションは
document.getAnimations()が空であることと、イベント間で矩形がビット単位で一致することです。イージングカーブではありません。 - スタイルシートは解析に失敗してもエラーにならず、復旧処理に移り、その復旧処理が次のブロックを飲み込むことがあります。
バナーコメント内に書いた1つの
*/がコメントを早く閉じ、パーサーはその後の:root{}を、そのゴミのようなルールの本体として読み込みました。その結果、23個のトークンが未定義になり、background: var(--ground)は computed-value時点で無効になり、font:の一括指定全体がTimes 16pxに置き換わりました。それでもページはverify_case.pyのすべてのチェックを通過しました (cases/string-clockが踏んだ落とし穴 #1)。コメント内に*/を書いてはいけません。フロアでは今、参照されている未定義カスタムプロパティと、透明なbodyがあれば失敗します。 - 色は
<image>ではないため、宣言全体を無効にします。background-image: <gradient>, #eae3d3は無効で、宣言全体が取り除かれます。背景色は何もログに残さず、描画されないままです。色はbackground-colorに置き、グラデーションの下に重ねてください。 - 一致するものがないスクリプト編集でも、成功と報告されることがあります。 あるセッションでは、ファイルのパターンが変わっていたため、2つの
str.replace呼び出しが、何も変更しなかったのにひそかに成功しました。スクリプトによる編集のたびに、ファイルが実際に変更されたことを検証してください。そうしなければ、次のチェックで古いページを測定することになります。 - transform内のパーセンテージは、コンテナではなく、常に要素自身のボックスを基準に計算されます。
64pxの数字に対する
translateY(-40%)は26pxであり、ダイヤルの40%ではありません。幅とtransformの引数の両方に使うトークン(--dial: min(74vh, 100%, 760px))は、使われる場所によって異なる値に解決されます。そのため、1つの宣言があるブレークポイントでは正しくても、別のブレークポイントでは間違っていることがあります。 - 離散的なコントロールは、インパルスではなく状態を確定させて動かします。 デテント付きダイヤルのホイールノッチは「次のスロット」を意味し、「速度を加える」ことではありません。マウスは
deltaY120を報告し、トラックパッドは600以上を報告します。さらに、常に元の位置へ戻ろうとするスプリングがあると、実際の移動量は予測不能になります。また、ホイールを無条件にpreventDefault()してはいけません。コントロールの端ではスクロールをページに戻さないと、ページをスクロールできなくなります。 - モーションで、弱い情報階層、読みにくいテキスト、コンテンツの欠落を覆い隠さないでください。
- 静止フレームも納品物の半分です。 モーションを無効にした状態でスクリーンショットを撮り、そのフレーム単体でも擁護できるか確かめてください。「見栄えが悪い/AIが作ったみたい」という不満は、モーション調整の問題であることはほとんどありません。最初にスプリングに手をつけるのは、間違ったやり方だと記録されています(
design-slop.md)。 - 仕掛けを入れる前にページをデザインしてください。 マクロ構造、文字のスケール、配色は、それ自体で成果を生み出す工程であり、ビルド工程の一節ではありません。すでに機能しているページに仕掛けを配置するのは、テンプレートを装飾するのとは逆の順序です。そして、それが正しい順序です。
- 可能な場合は、実際のモーション値を抽出します。トリガー、時間、イージング、スタガー、transform、メディア、ライブラリ、モーション低減時の動作です。
- 実際のページを調査するまでは、Xの投稿、動画、スクリーンショットはトピック情報としてのみ扱ってください(Video Reference Protocol)。
- 軽量な3Dは、Webページの一部である場合にのみここで扱います。ヒーローシーン、製品のステージング、シェーダープレーン、スクロールカメラ、空間カード、軽量なWebGLの雰囲気表現などです。
- シェーダーが必要なのは、実行時に画像を変化させる場合だけです。 閲覧者が画像の中を移動するだけなら、シーン全体を、ライティングなしの
MeshBasicMaterialプレーンで作れます。SBS The Boat は、117個のアプリモジュール全体でShaderMaterialを1つも使わず、独自のブレンドもrenderOrderも使っていません(image-plane-3d.md§14)。最初のマテリアルを書く前に、どちらを作るのか決めてください。 - 深度にジオメトリは必要ありません。
PerspectiveCameraにとって、(x,y,z)にあるものがメッシュかテクスチャ付きプレーンかは関係ありません。どちらも遠近感がつき、遮蔽され、順序付けられ、投影されます。モデルを提案する前に、実際に何を回転させる必要があるのかを考えてください。答えが「カメラが動くだけで、何も回転しない」なら、シーン全体を平面画像で構成できます(references/image-plane-3d.md)。コラージュとの違いを生むのは、アートではなく測定です。 - 完全な3Dシーン、ゲームのような環境、生成モデル、物理演算が重いシーン、マテリアル/ライティングのパイプラインは、まず段階5を除外してから
3d-scene-studioに案内してください。 - 複雑なビルドでは
MOTION_SPEC.mdをビルド契約として使用してください。手早く自由に作る場合は省略します。 - デスクトップ、モバイル、モーション低減、パフォーマンス、ビルド/型チェックの検証が完了するまで、実装は完了ではありません。
- R3FとDOMの同期:WebGLキャンバスが背景にあり(
pointer-events: none)、state.pointerが機能しない場合は、グローバルなwindow.addEventListener('pointermove')を使用してNDC座標を取得してください。 - 視差と逆投影:DOM要素をWebGLメッシュに追従させる場合、
Vector3.unproject(camera)は移動する視差カメラと競合します。別個の静的なダミーカメラを使って逆投影してください。 - スクロールに伴うモーフィング:CanvasにCSS
clip-pathを使用しないでください。Canvasは100vw/100vhのままにし、getBoundingClientRect()で透明なDOMプレースホルダーを追跡し、メッシュの位置/スケールをlerpしてください。角丸には実際のジオメトリではなく、シェーダーSDFを使用してください。
データ
data/visual-bank.json— 静的要素を優先したビジュアルデザインライブラリです。7種類のパレットの類型、5種類のタイポグラフィシステム、5種類のレイアウトグリッドがあり、それぞれに具体的な値(clamp()のスケール、字間、グリッド CSS)が含まれています。page-design.mdとdesign-slop.mdの A4 はここを参照しています。類型を1つ選んで徹底し、2つを混ぜないでください。components.md§1、page-blueprints.md、production-polish.md、page-design.md§2 に記載された測定値は、scripts/measure_structure.pyを使い、1440×900 と 390×844 の解像度で32サイト(受賞歴のあるクリエイティブ系18サイト、プロダクトマーケティング系14サイト)を対象に、2026-08 にヘッドレス実行して得られたものです。概要は各ファイルに記載されています。このリリースにはサイトごとの記録は含まれていません。最新のベースラインが必要な場合は、新しい URL セットを使ってスクリプトを再実行してください。
ケース
cases/ には動作確認済みのソースコード全体が含まれています。技術的な分析だけを収録したライブラリとは異なり、ページ全体が揃っていて、実際に動作します。だからこそ、次のルールが重要です。
仕組みの層はそのまま取り入れ、表層は一切流用しないでください。 仕組み――ソルバー、数式、ガード、プローブ用のサーフェス、
@supportsの記述順序――はエンジニアリングであり、美的な特徴ではありません。そのまま取り入れてください。ホモグラフィを手作業で導き直すのは無駄です。 表層――パレット、タイポグラフィの値、グリッド、セクションの順序、コピー、創作したブランド――は、そのケース固有のアイデンティティです。それを再利用すると、別のロゴを付けただけで、このケースだと一目でわかるページになってしまいます。これは、このスキルの他の部分が防ごうとしているテンプレート的な振る舞いそのものです。
各ケースの index.html ではコメントのバナーで境界が示され、README.md には、理由とともに2つのリスト(そのまま流用できるもの/流用してはいけないもの)が明記されています。引き継ぐべきなのは、その値ではなく、その理由です。
| ケース | 学べること | スタック |
|---|---|---|
cases/string-clock/ | 柔らかいボディと正確な端点 — 両端を固定したたるみのある弾性ひもとしての時計の針、ストロークがずれても読み取り値が正確に保たれる硬い先端スプリング、退化ケースとして実装された Rods、そして方言的な発見(クリエイティブなキャンバス上のプロダクト制御) | 単一の HTML ファイル、rAF |
cases/ink-crowd/ | インクのレンダリングレイヤー — 手書きの WebGL2(フレームワークも CDN も不使用):620 個のインスタンス化されたカプセルを MRT と深度ターゲットに描画し、その後、深度の不連続だけから線を描く全画面パスを実行(内部の折り目はオフ)。ノイズは 2 種類で、図形ごとに固定されたものと、60 fps のレンダリングに対して11 Hz の沸き立ちクロックで動くもの。影の円盤と虚無は同じプリミティブ。2 色のパレット、インラインの可変フォント | 単一の HTML ファイル、WebGL2、rAF |
cases/press-stack/ | 粘着スタック — wheel-rail とは正反対のアプローチです。ネイティブスクロールには手を加えず、9 つの画面それぞれに position:sticky;top:0;height:100vh を設定して、次の画面が前の画面に重なります。進行状況は累積するのではなく、ドキュメントから読み戻します((scrollY - offsetTop) / innerHeight)。タイプワイプで、読み順に単語を 0.22 → 1 で点灯させます。スリーブもレコードもすべてキャンバスに描画し、ビットマップは使いません | 単一の HTML ファイル、DOM + Canvas 2D、rAF |
cases/wheel-rail/ | 入力駆動の振り付け — タイマーで再生するものはありません。wheel を横取りして {passive:false} を指定し、変換されたレール上でイージングします(window.scrollY は 0 のまま)。ポインターで深度比 7 倍の 3 つの平面を動かします。ラベル付きノードは getPointAtLength で曲線上に固定されます。変換された祖先要素の中では position:sticky が機能しないため、アクト 4 の曲線フィールドは手動で配置されています | 単一の HTML ファイル、DOM + インライン SVG、rAF |
cases/toy-flipbook/ | レンダラーなしで奥行きのある回転を表現 — 厳選した 4 つの事前レンダリング済みヨーフレームを、トランジションを一切使わず、スプリングの値を Math.round してハードカットします。60 fps のレンダリングに対して保持された 11 Hz のジッタークロックで動作します。1 つの正規化されたドライバーが各レイヤーに個別のゲインを与え、1 つの見出し内にある 2 行には逆符号のゲインも適用します | 単一の HTML ファイル、rAF |
cases/char-curtain/ | メッシュではなく、ひもの集合としての布 — 24 本の Verlet 列上に 576 個のグリフを配置し、水平方向のリンクはゼロです。これが唯一の理由で、ポインターが布をへこませるのではなく、押し分けます。固定ではなくスプリング式のアンカーを使い、oldX を反転させて跳ね返します。速度を色とアルファにマッピングするため、静止画でも波紋の位置が分かります | 単一の HTML ファイル、Canvas 2D、rAF |
cases/lyre-crows/ | タイムラインではなく、因果関係に基づく生態系 — 弦を弾くと単語が放たれ、それを操舵するカラスが追いかけ、捕まえたものを使って自分の尾を再構成します。ループがノイズになるのを防ぐのは、発生源でのレート制限と、生成物に対する無条件の減衰です。操舵で制限するのは速度ではなく力であり、これによって旋回に半径が生まれます | 単一の HTML ファイル、Canvas 2D、rAF |
すべてのケースで同じ最低限の合格基準を満たし、README にその内容を記載しています。コンソールエラーがないこと、320/375/414/768/1440 で横方向のオーバーフローがないこと、<h1> が 1 つであること、lang が設定されていること、表示文字と本文文字の比率が 4 倍以上であること、異なるセクション形状が 3 種類以上あること、参照されているカスタムプロパティに未定義のものがないこと、ボディが独自の地面を描画すること、そして動きを減らす設定のときに何も非表示のまま固定されないことです。単一画面のヒーロー(toy-flipbook)は --min-shapes 1 で動作します。これはヒーローデモに対する例外であり、実際のページには適用されません。各ケースにはドメイン固有のオラクルが加わります。--beats と --detent は、ケースに紐づけずに残しています。どちらもページ側でプローブの契約を公開する必要があるため、任意のページに適用できるチェックではなく、これを基に構築するパターンです:
| フラグ | 検証内容 | 使用例 |
|---|---|---|
--beats | スクロール軸を走査し、各トラックを個別の範囲で正規化して、どのトラックも動かなかった最長区間を報告します。これがデッドビートの実用上の定義です | 該当ケースなし — __probe.seek/tracks が必要です |
--detent | 36 か所で離したとき、スナップするコントロールがスロットから ≤ 0.02° の位置に着地して静止し、すべてのスロットに到達して両端でクランプされることを検証します | 該当ケースなし — デテントプローブが必要です |
--strings | 互いに相反する2 つのアサーションを検証します。すべての針の先端が実際の角度から ≤ 1.5° の位置にあること、かつすべての針が弦長の ≥ 1.12 倍のたわみを保つことです。さらに、1 ステップあたり 12/60/240 px の実ポインターによるフリングでは、伸びが 3.2 倍を超えず、枠外にも出ないこと、そして時計を固定しない連続実行パスを検証します | string-clock |
--stack | スティッキー動作の契約を検証します。window.scrollY が増え続ける間、すべての画面で top: 0 に固定されること(window.scrollY が 0 のままであることを要求する --rail とは逆です)、異なる接地面が ≥3 つあること、そしてタイプワイプがある時点でグラデーションを表示し、かつ一度も 0.12 を下回らないことを検証します。すべてを一度に点灯するページは 2 つ目のテストに合格し、ゼロからフェードするページは 1 つ目に合格します。両方に合格するのはリファレンスのデバイスだけです。また、ビットマップを読み込む要素がある場合も失敗します | press-stack |
--rail | 要素の変化、アイドル時の動作に加え、ホイールの乗っ取りも検証します。マウスを 1.5 秒間完全に静止させたとき、少なくとも 2 つの要素が変化し続ける必要があります。入力を待つすべての動きが止まっているページは、誰かが触れるまで静止画像と変わらないからです。次に、実際の 8 回のホイール操作全体で、要素の少なくとも 35%が transform、opacity、または stroke-dashoffset を変化させ、少なくとも 4 つが遷移の途中で捉えられる必要があります。1 つ目のアサーションは、子要素がすべて静止したまま移動するレールを検出し、2 つ目は状態が瞬時に切り替わるものを検出します。また、以前と同様に、ホイール操作は乗っ取られ、ポインターは奥行きを伝えます。実際のホイール操作でレールが動く一方、window.scrollY は 0 のままで、ホイールイベントがキャンセルされる必要があります(overflow:hidden だけでも scrollY は固定されますが、オーバースクロールは発生します)。レールが 1 フレーム後に測定可能なほどターゲットから遅れ、1 秒後には静止する必要があります。また、ポインターを隅から隅まで動かしたとき、奥の平面が手前の平面の少なくとも 1.5 倍動く必要があります | wheel-rail |
--layer <dom|svg|canvas2d|webgl> | 説明文を信頼するのではなく、実際のキャンバスコンテキストとインライン SVG の図形数を調べ、README で宣言された描画レイヤーを検証します。webgl と主張しながら div を使っているケースは失敗します。ウェブフォントのゲートも含みます。@font-face が 0 件でフォントのプリロードもない場合は失敗です。システムフォントのスタックは、他のゲートでは検出できない生成ページの特徴だからです(独自の字形を描画するページには --draws-own-type を使います) | ink-crowd |
--follow | ポインターに追従する動きを検証します。キャンバス上の 5 か所を狙います。その中には地面だけの場所も含まれ、どの場所からでも群衆の重心が狙った位置に近づく必要があります。追従カウンターが増えても、何かが歩いた証拠にはなりません。ある帯域では機能するものの、ほかの場所では反応しない仕組みは、ほかのすべてのチェックに合格してしまいます | ink-crowd |
--flipbook | 互いに相反する2 つのアサーションを検証します。実際のポインターで 60 サンプル分スイープしたとき、すべてのフレームが完全に点灯しているか、完全に消灯していること(クロスフェードは失敗します)。かつ、スイープでフレームを飛ばさずに順番どおりすべて訪れること(最後のポーズへ瞬時に切り替わるコントロールは失敗します)。さらに、ジッターが毎秒 4~25 回の頻度で再抽選され、ホイールをしきい値を超えて回したとき、机上のおもちゃが跳ね上がり、着地時に押しつぶされることを検証します。テスト用スクリプトは最大駆動量を出力し、しきい値を超えていなければ失敗するため、トリガーされないテストが黙って合格することはありません | toy-flipbook |
--curtain | 互いに相反する2 つのアサーションを検証します。実際のポインタースイープで、中央の列が横方向に ≥ 6px 動くこと、かつ、1 つの列をつついたとき、布の反対側の動きがその 20%未満にとどまることです。動かない布は 1 つ目に失敗します。横方向のリンクがある布は 1 つ目に合格して 2 つ目に失敗します。さらに、リンクが静止時の長さから 35%を超えてずれず、すべてのアンカーがペグから 2px 以内の位置に戻ることを検証します。布が測定可能なほど静止するまで基準状態をポーリングします。時間経過をただ待つのではありません — 上記の教訓を参照してください | char-curtain |
--lyre | 互いに相反する2 つのアサーションを検証します。実際に 14 回弦を弾くスイープで単語が放たれること、かつ、操作を続けても空中にある単語の数がページに記載された上限を決して超えないことです。装飾用の楽器は上限を満たしますが、無制限に放出すると溢れます(壊れたコピーでは 440 個に達しました)。さらに、獲物が空中にいるときカラスが狩りの状態に入り、距離を ≥ 30%縮めること、そして捕獲を数えた際にそのカラスの尾が変化し、捕らえた単語が尾に残ることを検証します | lyre-crows |
verify_case.py を通過するまでは、新しいケースとはみなされません。 |
ケースを作成する場合は、まず cases/AUTHORING.md を読んでください。 そこには 参考 → 复刻 → 收录 の手順が記載されています。取り込みゲート(参照元から画像を取り除いても成立するか)、計測スクリプト、4つの分類判断、ビルドルール、オラクル、README に記載すべき内容 — デザインシステム + モーションシステム + 判定基準 + 模倣してよいもの/いけないもの + 実際に遭遇した問題 — が含まれています。
ケースを読むタイミング:ユーザーの依頼がその分類に当てはまる場合、仕組みを把握する必要がある場合、またはドキュメントのルールを実際に適用した例が必要な場合です。「まずこれを基に始める」ためにケースを開いてはいけません — page-blueprints.md から始め、必要な仕組みを取り入れてください。
参照ファイル
| ファイル | 内容 |
|---|---|
references/choreography-arc.md | ページレベルのアークタイプ5種とモーショントークン |
references/motion-tokens.md | 時間スケール、イージング辞書、スプリング設定の早見表、スタガーパターン、変形の予算 |
references/pattern-recipes.md | すぐに使えるモーションパターンの実装(Vanilla + Framer + GSAP) — ここに書かれた数を鵜呑みにせず、自分で数えてください。#17のコーナーピンワープ(真形变,不是 skew)と、それを基にした#18のVerletカードチェーンを含みます |
references/affordance.md | クリックできる ≠ クリックできると分かる:招待の監査、window-vs-dwell、描画済みbboxマーク、downで記録してupで決定、数値オラクル、見えない引き継ぎ |
references/handfeel.md | インタラクションの手触り:減衰不足スプリング、速度に応じた傾き、ホイールの慣性ガード、ゼリーのような揺れ、平面画像の擬似ライティング — さらに§7では 追従する 半分(フレームレートに依存しない exp(-k·dt)、定常状態の遅れ speed/k とそのリード項、フィルター後の補正がなぜハンチングを起こすのか、加速度駆動の臨界減衰)を扱い、§8では画面揺れを扱います |
references/build-mode.md | 実装ルール、パフォーマンスルール、検証チェックリスト |
references/page-design.md | モーションページの設計方法:マクロ構造の選択、モーションに場所を譲るレイアウト、現在の受賞サイトから測定した文字サイズの階層と配色の規模、スクロールストーリーテリングの分割、モバイル向けの劣化対応 |
references/design-slop.md | モーションページ専用のAIらしさを防ぐゲート:モーションを止めた静止画の確認、デフォルトのヒーロー、3列の特長カード、紫のグラデーション、デザインの代わりの装飾、すべての要素を一律に持ち上げるホバー、ページ全体のfade-up、ファーストビューで予算を使い切ること |
references/page-blueprints.md | このページに何を置くか:セクションの語彙、7つのブループリント(プロダクト/ポートフォリオ/スタジオ/キャンペーン/エディトリアル/インデックス/ドキュメント)、順序のロジック、各セクションに必要な実際のコピー、情報アーキテクチャ、測定したセクション数と形状の多様性の数値 |
references/components.md | コンポーネントレベルの作り込み:測定可能な違いのある2つのコンポーネント表現(クリエイティブ系とプロダクト系 — 角丸、シャドウ、大文字表記、ナビゲーションCTA、フッターの規模)、各コンポーネントに必要な状態マトリクス、ナビゲーション/ヒーロー/ボタン/タグ/カード/メディア/フォーム/アコーディオン/ダイアログ/インデックス/プルーフ/フッター |
references/project-setup.md | エンジニアリングの0→1:ページスタックの段階(HTMLファイル1つ → Vite → Astro → Next)、3段階のトークンレイヤーとTailwind v4の@theme、clamp()式を使った流動的な文字サイズと余白のスケール、メトリクス上書きを使ったフォント読み込み、@layerの順序、ファイル構成、画像、予算、デプロイ |
references/production-polish.md | 動く状態から完成品へ:headブロック全体、OG画像、404、正常系以外の状態、ちらつきのないダークモード、小さな「完成」のディテール、機械可読な構造、アナリティクス、出荷前の手動チェック10項目 |
references/baseline-ui.md | アクセシビリティとユーザビリティの最低基準(フォーカス、タッチターゲット、ホバー不要のモバイル対応)— デザインではなく、あくまで 最低基準 です |
references/motion-spec.md | MOTION_SPEC.mdのテンプレートと各項目の定義 |
references/composition-guide.md | 硬直したテンプレートを使わずに、カスタムデザインとモーションをどのように組み立てるか |
references/shaders-spec.md | WebGL GLSLシェーダー、シンプレックスノイズ、レンダリング最適化 — さらに§6では見過ごされがちな失敗を扱います。intとfloatのリテラルの違いでプログラムが停止する問題、tonemapping/colorspaceのインクルード漏れ、DepthTextureのフィルタリング、高周波のディテールに対する距離減衰、空間的に整合したインスタンス化風表現 |
references/tactile-texture.md | SVGの粘性フィルター、CSS Houdini、OffscreenCanvas、canvasのグレインパターン |
references/image-asset-pipeline.md | 画像アセットの作り方:画像自体の背景に合わせたキーイング、coverageゲート、bboxクロップ、線画のアルファ、スクリプトによるcx/baseline、誰も記録しないクラウンアンカー、要素ごとの解像度予算、テクスチャ密度と表示距離、来歴 |
references/scene-streaming.md | 大きなシーンを収める方法:画面ウィンドウによるアクティベーション、協調スキャン、DOM変更のスロットリング、完全な破棄、分割したテクスチャアップロード、可聴性に応じた音声ストリーミング |
references/verification-harness.md | 判定用ハーネス:プローブの契約(__seek/__hold/固定可能なクロック/状態の終了)、オン・オフ差分、テレポートと画面差分が誤解を招く理由、前提条件としての決定性、サンプリングレート、ものさしの解像度の下限 — そして複合品質スコアがテストなしよりも悪い理由 |
references/timeline-orchestration.md | 複数トラックのスクロールタイムライン:スケジュールを横方向に読む、イージングレイヤーは1つ、目が読み取る内容に重みを付ける、1つのウィンドウに1つのイベント、速度ゼロのキーフレーム、コンテンツが消えても残る仕組み、決め手となるフレーム、しきい値マップのヒストグラム |
references/scene-audio.md | シーンの音声:3つのバス(bgm/hand/world)、アクトごとのLUFSカーブ、ダッキング、より大きなベッド音に重ねる個別イベント、連続量がアンビエンスとして聞こえる理由、RESTオラクル、20 dBを食うフィルター |
references/image-plane-3d.md | 画像アセットで本物の奥行きを作る:平面の切り抜きを実際の透視カメラ内の平面として配置 — アセットメタデータの契約、長焦点レンズ、シルエットの噛み合わせ、手作業で並べ替える透明要素、解析的な接触影、「貼り合わせ感」を解消する色温度 |
references/light-3d.md | Three.js/R3F/canvasの統合ルールと、動くシーン上のDOM |
スクリプト
# ── MEASURE STRUCTURE (the static-page half: sections, components, tokens, polish) ─
# Answers "how is it built as a page": sections, nav, buttons, token scales, forms, media, meta, mobile overflow.
python3 scripts/measure_structure.py https://example.com
python3 scripts/measure_structure.py --urls-file urls.txt --out data/structure-bank.json
# Skips URLs already present in the out file, so a killed run resumes.
# ── DECONSTRUCT A VIDEO REFERENCE (no URL to open) ────────────────────────────
# measure_structure needs a loadable page. A clip has none.
python3 scripts/measure_frames.py sheet ref.mp4 # contact sheet — ALWAYS look first
python3 scripts/measure_frames.py palette ref.mp4 -t 8 # ground %, accents, mid-grey scale
python3 scripts/measure_frames.py bands ref.mp4 -t 8 # control heights/widths off the pixels
python3 scripts/measure_frames.py trace ref.mp4 --color red # arc/chord per frame
python3 scripts/measure_frames.py grounds ref.mp4 # section changes + which way the new screen arrives
python3 scripts/measure_frames.py wipe ref.mp4 --from 7.9 --to 10.1 --dark
# ^ the schedule of a per-word reveal, and the one number a still frame cannot give
# you: whether unlit type is hidden (0.00) or merely dimmed (side-b: 0.22).
# ── VERIFY A CASE / ANY BUILT PAGE ────────────────────────────────────────────
# The acceptance floor every case's README claims. Re-runnable, so the claim can't rot.
python3 scripts/verify_case.py cases/string-clock/index.html --strings # exact tip, sagging body
python3 scripts/verify_case.py cases/ink-crowd/index.html --layer webgl --follow # declared layer + pointer-led crowd
python3 scripts/verify_case.py cases/wheel-rail/index.html --rail # hijacked wheel + depth + churn
python3 scripts/verify_case.py cases/press-stack/index.html --stack # sticky dwell + type wipe + drawn art
python3 scripts/verify_case.py cases/toy-flipbook/index.html --min-shapes 1 --flipbook # hard cut AND continuous scrub
python3 scripts/verify_case.py cases/char-curtain/index.html --min-shapes 1 --curtain # parts AND stays independent
python3 scripts/verify_case.py cases/lyre-crows/index.html --min-shapes 1 --lyre # releases AND stays limited
python3 scripts/verify_case.py http://localhost:5173 # works on a dev server too
# ── DOES ANYTHING ACTUALLY MOVE? ──────────────────────────────────────────────
# The check that caught what every oracle above missed twice: a page with all the
# right mechanisms that reads as dead. Drives a REAL wheel; scrollTo teleports
# past the arriving-and-leaving window where the motion lives.
python3 scripts/measure_churn.py https://a-reference.com # characterise it first
python3 scripts/measure_churn.py cases/foo/index.html --against https://a-reference.com
# ── SHIP REAL TYPE, NOT THE SYSTEM STACK ──────────────────────────────────────
# 0 @font-face is the loudest generated-page tell (render-layer.md §2).
python3 scripts/subset_fonts.py list
python3 scripts/subset_fonts.py pack --out /tmp/faces.css \
Grot=Inter-Variable Ital=InstrumentSerif-Italic Mono=IBMPlexMono-Regular
セルフチェック(scripts/ または任意のケースを編集した後、あるいはユーザーからこのスキルの「体检」を依頼されたときに実行します):
cd ~/.claude/skills/motion-web
python3 -c "import json;json.load(open('data/visual-bank.json'))" && echo "json OK"
python3 -m py_compile scripts/*.py && echo "syntax OK"
# then the seven verify_case.py lines above — every one must print VERDICT: PASS
zsh では変数が分割されません。 flags="--layer webgl"; verify "$f" $flags は文字列全体を1つの引数として渡すため、argparse は unrecognized arguments と報告します。フラグを個別に記述するか、${=flags} を使ってください。
出力の規約
仕様書を作成する場合:references/motion-spec.md のテンプレートから、簡潔な MOTION_SPEC.md を作成します。
自由形式でビルドする場合:仕様書は省略し、すぐにビルドします。完了後、ユーザーに次の内容を伝えてください。
- コンセプト名と、それを選んだ理由
- アークの種類と、それがページのリズムに与える影響
- 最も重要なモーションに関する決定3つ
- 確認すべき項目(reduced-motion、モバイル、FPS)
full-build の場合:選択したブループリントとその理由、ページスタックの段階、コンポーネントの表現スタイル(クリエイティブ系またはプロダクト系)、モーションのコンセプト、独自に考案する必要があった事実スロットのすべて(明示的に列挙)、および production-polish.md §9 の結果(合格したチェックと実行できなかったチェック)を報告します。
すべてのビルドで:完了を報告する前に、ローカルで検証してください。該当する場合は、ビルドと型チェックを実行します。変更内容、検証した内容、残っているリスクを報告してください。