スケートボードショップ
GRIND DISTRICT 板場
街を降りながら、 板を組む。
架空ブランドを立てて制作したデザインデモです(2026-08-29 公開)。
実際のサイトを見る 別タブで開きます
縁石で板。レールでトラック。階段でウィール。障害物ごとに合う物を置いたスケートボードショップ。降りて、拾って、店で組む。組み立て無料。
全ページビュー
このサイトの作られ方
実際の発注内容
ビルドの起点になった設計方針です。人が書いたものではなく、AI が毎朝生成した7案のうち選ばれた1案をそのまま載せています。
コンセプト GRIND DISTRICT 板場 — 街の縁石・レール・階段を降りる途中でデッキやパーツに遭遇する、遊具型スケートボードショップ
- スタイル
- 都市の縦断面を降りる物理プレイグラウンド・UI も商品も「障害物」
- レイアウト
- 縦のストリート断面(1本の縦スクロールが curb → rail → stair → shop の 4 スポットで構成される)。商品は棚に並べず各障害物に紐づけて出す(このレールにはこのトラック幅、この路面にはこのウィール硬度)。見出し・ボタンも床に置かれた重さのある物として扱う
- タイポグラフィ
- ultra-condensed sans display+stencil の注記+可変幅数字(wdth 軸を衝突の強さ、wght 軸を床の傾きで動かす)。見出しは「削れる」— グラインド中は文字の下端が stencil のように欠ける
- モーション
- 慣性物理。自前の 2D verlet 物理(canvas、依存追加なし)で、入力は ①ドラッグ/DeviceOrientation の傾き ②スクロール速度(速いほどデッキが滑走し、止まると失速して着地)。運動語彙を「擦れる / 跳ねる / 失速する / 着地する」の 4 種に固定し、各スポットに 1 種ずつ割り当てる。タイプも UI も同じ 4 語彙に連動(擦れる=文字が欠ける、跳ねる=ボタンが弾む)。衝突音は物理に連動、prefers-reduced-motion では傾き 0・スクロール非依存の静止配置に固定。物理の本命はレールの 1 スポットに絞る
- 配色
- 路面の白線ホワイト地×アスファルト黒の帯×反射ベスト黄。降りていくほど黒の帯の面積が増え、shop に着くと黄の面が最大になる。パステルは使わない(No.6 と分離)
- 狙い
- Awwwards Nominee(8/24)。UI そのものを世界の中に埋め込み(ボタンも重さを持つ物)、モバイルではデバイス傾きを入力にする日本発の遊具的ブランド体験。スケートは「街の障害物を読む」競技なので、障害物をナビにする翻案は原理と一致する
- 設計の勘所
- UI を世界内オブジェクト化する演出と、傾き=入力のモバイル差別化。共同プランナーの「都市の障害物そのものをナビにする」「4 種の運動語彙」を全面採用し、1 画面遊具から縦のストリート断面へ拡張(物理の本命は 1 スポットに絞るので auto-loop 規模で成立)
ビルダーに渡した指示文の全文を見る
上の提案をもとに AI が起こした詳細ブリーフです。これがそのままコードを書く AI への入力になりました。原文のまま載せています。
# GRIND DISTRICT 板場 / 街を降りながら、板を組む: 強化版ブリーフ v1
選択案 no.3(参考: TILToooTILT(tote) / 業種: スケートボードショップ・翻案)を impeccable の流儀で詳細化したもの。実装は portfolio-demos の規約(Astro + `site-content-<slug>.json` + `src/styles/<slug>.css` + `<slug>/en/index.astro`)を前提にする。想定 slug: `grind-district`。
- 日付: 2026-08-29 / 選択案 no.3 / モード: **Persuade**(EC の入口。Experience の機構を使うが、1 画面目で「何の店で・何ができて・どこを押すか」が分かることを優先する)
- 方向は選択案で**ピン留め済み**なので、new-work の方向ロール(concept-seed)は回さない。世界は下記の通り確定
- headless 実行のため確認質問は行わず、判断はすべてこのブリーフ内で確定した
**Design Read:** スケートボードショップの EC 入口を、棚でもカタログでもなく「街の縦断面(縁石 → レール → 階段 → 店)」として作る。商品は障害物に紐づけて置き、見出しとボタンは床に置かれた重さのある物として扱う。動くものは自前の 2D verlet 物理(canvas・依存追加なし)を **レールの 1 スポットに絞り**、残り 3 スポットは CSS だけで「跳ねる / 着地する / 失速する」を担う。参考サイト(Three.js + GSAP + Lenis の 3D 遊具)を 2D に縮約するのは、auto-loop 規模で完走させるための意図的な選択で、劣化版ではない。
**ダイヤル:** `DESIGN_VARIANCE: 8` / `MOTION_INTENSITY: 7` / `VISUAL_DENSITY: 5`
- VARIANCE 8: レイアウトは「棚」を捨てて断面図にする。ただし価格・サイズ・在庫・CTA の 4 点は各障害物の中で必ず同じ位置に出す(遊具でも EC としての読み順は守る)
- MOTION 7: 物理は 1 スポット、他は CSS。parallax は 0 箇所。ピン留めスクラブも 0 箇所(理由は 4.4)
- DENSITY 5: 障害物 1 つあたり商品 3〜4 点。カタログ的な網羅はしない(「その障害物に要る物」だけ)
---
## 参考サイトの一次確認(2026-08-29 取得)
生 HTML / CSS / JS を取得して確認した事実。ブリーフはこれに基づく。
| 観点 | TILToooTILT の実態 | この案で盗む / 盗まない |
|---|---|---|
| 主題 | `<title>` は「Everything Has Weight」。物体ごとに `mass: 3.2 kg / force: 31.4 N / density / drift / stability` のティッカー | **盗む(翻案)**。全商品に **質量(g)** を stencil 注記で持たせ、店で合計する(「完成: 3,010 g」)。force/density は捨てる |
| 物体一覧 | `data-section` が 20 種(`skateYellow` / `skateSilver` / `weigher`(秤)/ `boots*` / `head*` …)、重さ順のリスト `22000G … 500G` | **盗む(限定)**。「重さ順の一覧」を断面ナビの右端に縦 1 列で置く(4 スポットの位置表示を兼ねる) |
| 機構 | Three.js(WebGLRenderer 41 箇所)+ GSAP 3.15 + Lenis。カーソルとデバイス傾きで 3D 物体が転がる | **盗まない**。3D と依存ライブラリは足さない。2D verlet を自前で書き、本命はレール 1 スポット(4.4) |
| 傾き入力 | `DeviceOrientationEvent.requestPermission` を持つ(iOS の許可ダイアログ対応) | **盗む**。スマホでは「傾きを使う」ボタン(44px)を押した後だけ傾きが効く。押さなければドラッグ |
| 音 | `AudioContext` 7 箇所。入口で音あり / なしを選ばせる(`enter-shutter` / `enter-without`) | **盗む(形を変えて)**。入口の選択画面は作らず、ナビに音トグル(既定 OFF)を置く。音は合成(音源ファイル不要) |
| 書体 | システムサンス(`-apple-system … Arial`)+ 「Tiny5」(ピクセル)。書体で勝っていない | 盗まない。この案は書体が主役級(ultra-condensed + stencil + 可変幅数字) |
| 配色 | `#faf2e6`(生成り)地 × `#000` × `#ff0`(黄)が CSS に散在 | 黄の使い方だけ継承し、地は「路面の白線」に、黒は「アスファルトの帯」に置き換える。生成りは使わない |
| カーソル | `page-stalker`(追従カーソル)+ `page-drag`(ドラッグ促し) | ドラッグ促しだけ盗む(レールの端に 44px のハンドルを可視化)。追従カーソルは作らない |
---
## 1. ブランド軸
- **名前:** GRIND DISTRICT 板場(いたば)。欧文が主、和文「板場」は副(店名の読みと「板を扱う場所」の二重の意味)
- **タグライン:** 街を降りながら、板を組む。(英: Ride down the block. Build the board on the way.)
- **業種:** スケートボードショップ(ストリート用デッキ・トラック・ウィール・ベアリングの EC + 実店舗)。**架空**。価格・在庫・住所はすべて合成値で、成果物では `synthetic` として扱う
- **ペルソナ:** 16〜29 歳、街で滑る人。縁石とレールと階段で今日どこに行くかを決める。パーツの数字(幅 8.0 / 硬さ 99A / 径 54mm)は読めるが、「初心者向け」「おすすめ」という言葉には反応しない。スマホで店を見て、店に来て組む。副ペルソナは 30 代の出戻り(昔の板が捨てられず、規格が変わったことを知らない)
- **価格帯(合成):** デッキ ¥8,800〜¥14,300 / トラック ¥12,100(1 組)/ ウィール ¥5,500〜¥7,700(4 個)/ ベアリング ¥3,300〜¥9,900(8 個)/ コンプリート ¥26,400〜¥38,500。組み立て無料
- **ブランド人格(4 語):** 重い / 短い / 削れる / 実地
- **Why-This-Brand:** スケートは棚から板を選ぶ遊びではなく、街の障害物を読む遊びだ。縁石の高さで板の幅が決まり、レールの太さでトラックの幅が決まり、階段の段数でウィールの硬さが決まる。だから板場は、商品を棚に並べず、障害物の横に置く。客は街を降りながら、今日ぶつかる障害物に合う物を拾い、いちばん下の店で組む。板場という名前は「板を扱う場所」であると同時に、料理の板場のように「材料を切って組む現場」でもある。売っているのは板ではなく、街の読み方だ。
---
## 2. 差別化軸
### 同業の凡庸な見せ方(3 つ)
1. **ブランドロゴのグリッド + 「NEW ARRIVAL」の横流し。** 入荷順のカードが 4 列で並び、板は棚に刺さった状態の写真。何がどの用途かは商品名の英字を知っている人にしか分からない
2. **カルチャー写真の全画面 hero(夕方の逆光、宙にいる人)+ 「Skate or Die」型の英語スローガン。** 気分は伝わるが、店として何を売っていて次に何を押すかが hero に無い
3. **サイズガイドが別ページの表。** 8.0 と 8.25 の違いを「足のサイズ」の表で説明し、街のどこで滑るかという実際の判断軸を扱わない
### この案の踏み外し方
- **棚を捨てて断面図にする。** 1 本の縦スクロールが curb → rail → stair → shop の 4 スポットで構成され、商品は障害物の横に置く。「このレールにはこのトラック幅」「この階段にはこの硬さ」を配置そのもので言う
- **見出しとボタンを物にする。** 見出しは床に置かれた看板で、押せるものには重さがある(押すと 2px 沈み、離すと 1 回だけ弾む)。動く語彙は「擦れる / 跳ねる / 失速する / 着地する」の 4 つに固定し、各スポットに 1 つずつ割る(4.4)
- **1 スポットだけ本当に物理を書く。** レールでは verlet のデッキがレールの上を滑り、傾きとスクロール速度で動く。他の 3 スポットは CSS だけで 4 語彙を担い、物理の見せ場を薄めない
- **質量を全商品の共通仕様にする。** 参考サイトの「Everything Has Weight」を翻案し、DECK 1,180 g / TRUCKS 740 g のように stencil で書き、店で合計する。「軽い板」は宣伝文句でなく数字になる
- **配色は 3 値で、降りるほど黒が増える。** 直近 10 本の成果物が「地 1 色 + アクセント 1 色」に収束していた(2026-08-27 監査)ので、この案は白線 / アスファルト / 反射ベスト黄の 3 値を**面積の変化**で使う。CURB で黒の帯 12vh、RAIL で 40vh、STAIR で約 70vh、SHOP で全面黒 + 黄の床
- **コピーの型を変える。** 直近 10 本すべてが「X は、Y ではない。Z だ。」の否定→肯定構文だった。この案は**否定文で始めない**。動詞で終わる常体の短文だけで書く(3 章)
- **計器・帳票のメタファーを使わない。** 直近 7 本中 6 本が計器 / 帳票だった。この案の装置は「障害物」と「遊具」で、目盛り・ダイヤル・伝票・スタンプは 1 つも置かない
---
## 3. トーン&マナー
- **一人称:** 「板場は」を必要な時だけ。「私たち」「当店」「うち」は使わない
- **二人称:** 使わない。動詞の命令形と終止形で客に向く(「降りる」「拾う」「組む」)。「あなた」「君」「お客様」は禁止
- **敬体 / 常体:** 全面 **常体**。見出し・本文・ボタン・注記まで常体で通す。例外は特商法・プライバシー・店舗案内の法定情報だけ敬体(です・ます)
- **抽象度:** 見出しは動詞 1 語〜 1 文(「降りる」「幅が合わないと、擦れない。」)、本文は数字と場面(高さ 15cm の縁石、5 段の階段)。「カルチャー」「スタイル」「フィーリング」のような抽象名詞で段落を終えない
- **リズム:** 1 文 25 字以内を基本。読点は 1 文に 1 つまで。**「X は、Y ではない。Z だ。」の否定→肯定構文は使わない**(ページ内 0 回)。並列は「縁石で板。レールでトラック。階段でウィール。」のように名詞止めの 3 連で作る(hero 直下と shop の 2 箇所まで)
- **数字の書き方:** 半角。板の幅はインチ小数 1 桁(8.0 / 8.25)、ウィールは mm と硬さ(54mm 99A)、質量は g で 3 桁区切り(1,180 g、数字と単位の間に半角スペース)。価格は「¥8,800」(記号が前、税込表記は shop に 1 回)。範囲は「から」で書き、波ダッシュを使わない
- **避ける言葉:** 初心者歓迎 / おすすめ / 人気 / 豊富な品揃え / プロ御用達 / 本格 / こだわり / カルチャー / ライフスタイル / スタイリッシュ / 最高 / 最強 / Skate or Die / 「!」/ 波ダッシュ「〜」/ 全角ダッシュ(U+2014 / U+2013 はページ内ゼロ。区切りは「/」か読点)
- **英語版:** 直訳せず、動詞主導の同じ構造で書く。hero は "Ride down the block. Build the board on the way." スポット見出しの CURB / RAIL / STAIR / SHOP は日英共通(英語版では和文副題を英文に差し替える)
---
## 4. デザイン原則
### 4.1 配色方向: 路面の 3 値。降りるほど黒が増え、店で黄が最大になる
色は 3 値(白線 / アスファルト / 反射ベスト黄)+ 補助 4 色。グラデーション・ぼかし・グロー・透過ガラスは使わない。奥行きは「帯の重なり」と「硬い影(offset あり・blur 小)」で作る。
**面積の規則(この案の配色はここで決まる):**
| スポット | 黒の帯(アスファルト)の面積 | 黄の面 |
|---|---|---|
| HERO / CURB | ビューポート高の **12vh**(縁石の立面。最小 72px) | 無し(ナビのカート数バッジの 4px ストライプだけ) |
| RAIL | **40vh**(最小 320px。canvas の床) | 無し(ADD ボタン下端の 4px 反射ストライプだけ) |
| STAIR | 3 段 × **22vh** ≒ 66vh + 段間 8px(合計約 70vh) | 無し(同上) |
| SHOP | **100%**(セクション全面) | 幅 100% × 高さ **60vh 以上** の黄の床。ページで黄が面になるのはここだけ |
黄は SHOP に着くまで「面」にならない。それまでは反射ベストの反射テープのように、**4px の線**としてしか現れない(カート数バッジ・ADD ボタンの下端・断面ナビの現在位置)。この抑制があるから、SHOP の黄の床が「着いた」と読める。
- 文字色は白線地では `--asphalt`、黒の帯では `--line-white`。黄の面では必ず `--asphalt`(黄の上に白文字は禁止。1.1:1 で読めない)
- 写真に黄や青の色被りを乗せない。曇天の平らな光で撮ったニュートラルな路面と、白線地の上で撮った商品だけ
- ダークモードは作らない(`prefers-color-scheme` で変えない。配色の面積そのものが構造なので、反転すると意味が壊れる)
- `::selection` は黄地に黒文字。フォーカスリングは白線地で黒 3px、黒の帯と黄の面で黄 / 黒 3px(4.5)
### 4.2 タイポ体系: ultra-condensed の看板 + stencil の注記 + 幅が動く数字
- **欧文表示(看板):** Anybody(variable、`wdth` 50〜150 / `wght` 100〜900、Google Fonts で実在確認済み)。見出しは **`wdth 50` に固定**した ultra-condensed で、`wght 800`、uppercase。直近デモの carga が Archivo(wdth 62〜125)を使ったので Archivo は避ける。Anybody の wdth 50 は Archivo の 62 より明確に細長く、看板文字として別物になる
- **和文表示:** Dela Gothic One(400 のみ)。「板場」と各スポットの和文副題に使う。極太で、白線地の上に置くと看板の板そのものに見える
- **stencil 注記 / UI ラベル:** Big Shoulders Stencil(variable、`opsz` 10〜72 / `wght` 100〜900)。質量・仕様・ナビ項目・ボタン文字。`opsz 72`、`wght 700`、`letter-spacing 0.06em`、uppercase。**stencil は注記にだけ使い、見出しには使わない**(見出しの「削れ」は Anybody をマスクで欠けさせて作る。4.4)
- **本文:** BIZ UDPGothic(400 / 700。Google Fonts で実在確認済み)。公共標識向けの UD 書体で、路面標示の世界と噛み合う。既存デモで未使用
- **可変幅数字(この案の署名タイポ):** 仕様の数字(8.0 / 5.25 / 54mm / 99A / 1,180 g)は Anybody で `font-variation-settings: "wdth" var(--wdth), "wght" var(--wght)` を持つ。`--wdth` は**衝突の強さ**(平時 62、衝突の瞬間に最大 100、420ms で 62 に戻る)、`--wght` は**床の傾き**(平時 500、レール傾き ±12° で 900)。値は RAIL の物理が CSS 変数に書き込む。`font-variation-settings` はブラウザで transition 可能(数値リストとして補間される)
- **書体は 4 家族。** 役割が 4 つあるので 4 家族で、5 つ目は足さない。mono は使わない(stencil が「測った物」の役を担う)
- **級数(clamp):** 5 章の確定トークンに実値で書く。hero の看板は craft floor の「display max 6rem」を**意図的に超える**(11rem)。看板は本文ではなく床に置かれた物で、その大きさ自体が「重さ」を運ぶため。ただし 390px では 4.5rem まで縮み、2 行で収まることをチェックリストで縛る
- **和文の折返し:** `text-wrap: balance` + `word-break: auto-phrase`(非対応では `overflow-wrap: anywhere`)。見出しの読点で必ず改行する(`<br>` を JSON 側の `\n` で持ち、コンポーネントで `white-space: pre-line`)
- **eyebrow は 0。** 見出しの上に小さなラベルを置かない。stencil 注記は見出しの**下**か、商品の**横**に置く(注記は「物に貼ったラベル」であって「見出しの前置き」ではない)
### 4.3 グリッド / レイアウト原則: 断面図。障害物が全幅、商品は障害物に寄りかかる
- 12 カラム、`max-width: 1440px`、ガター `clamp(20px, 4vw, 72px)`。スポット間の余白は `160px`(モバイル `64px`)。基準単位 8px
- **4 スポットはそれぞれ別のレイアウト族**で、同じ族を 2 回使わない:
- CURB = 横一線の段差(黒の帯 12vh が画面下部に走り、デッキ 3 枚がその立面に**寄りかかる**。カラム 7〜12)
- RAIL = 全幅の canvas(56vh 以上)+ その下の黒の帯 40vh に商品を**横 1 列**(トラック 3 幅)
- STAIR = 3 段の帯が**右に 1 カラムずつずれて**下る階段。段ごとに商品 1 種(ウィール 2 硬さ / ベアリング 2 種)を**踏面に置く**
- SHOP = 全面黒の上に黄の床。床の上に「拾った物」が横一列に**止まっている**。合計質量と合計金額、CTA
- **障害物は全幅、商品は障害物の位置に従う。** 商品カードを均等グリッドに並べない。カードという枠も作らない(商品は「白線地に置かれた物 + 影 + 注記 + 価格 + ADD」で、囲み線・角丸・背景色の枠を持たない)
- **ナビ(64px):** 左にロゴ、中央に CURB / RAIL / STAIR / SHOP(各スポットへのアンカー)、右にカート数と音トグル。断面ナビ(右端の縦 1 列・現在地マーカー)は 1024px 以上だけ表示
- **モバイル(< 768px):** 障害物は全幅のまま。商品は障害物の下に **2 カラム**(390px で 1 列 167px)。RAIL の canvas は高さ 56vh を維持し、レールの傾きハンドルは左右端に 44px。ナビはロゴ + カート + 音トグルだけ、スポットのリンクはハンバーガーではなく**断面ナビを画面右端の 12px 幅の縦バー**として残す(タップで各スポットへ)
- **hero は左寄せ**(anti-center)。看板「GRIND DISTRICT」がカラム 1〜9、右にデッキの静止画(カラム 10〜12)
- **形状ロック:** 角丸 0(看板・帯・ボタン・写真)。例外は音トグルと数量ステッパーの「ウィール」だけ(真円)
### 4.4 モーション言語: 4 語彙、1 スポットの物理、CSS 3 スポット
**前提の整理(混同しない):**
- **ピン留めスクラブ:** 画面を固定し、スクロール量を「再生位置」として使う機構。この案では**使わない**(物理はスクロール「速度」を入力にするのであって、スクロール位置を再生位置にはしない)
- **parallax:** 要素を速度差でずらす装飾。この案では **0 箇所**(黒の帯が増えていくのはレイアウトの面積であって、ずれではない)
- 使うのは ①自前の verlet 物理(RAIL のみ)②CSS の scroll-driven animation(STAIR の着地と断面ナビの現在地。`@supports` で囲み静的フォールバック付き)③CSS transition(ボタンの跳ね、店の失速)の 3 種だけ
**運動語彙の割り当て(これ以外の動きは無い):**
| 語彙 | スポット | 何が動く | 機構 | 意味 | reduced-motion |
|---|---|---|---|---|---|
| **跳ねる** | CURB | ADD ボタン(全スポット共通の挙動だが、語彙の主役は CURB) | `:active` で `translateY(2px)` + 影 0 → 離すと `--ease-pop` 380ms で 1 回だけ弾んで戻る。デッキ 3 枚は hover で 1px 浮く(`translateY(-1px)`)だけ | フィードバック(押した事実に重さがある) | 沈む / 戻るは即時。弾みは無し |
| **擦れる** | RAIL(本命) | canvas のデッキがレールを滑り、見出し「RAIL」の下端が欠ける。仕様の数字の幅が衝突で広がる | 自前 2D verlet(下記)。擦った距離を `--grind`(0〜0.34em)に書き、見出しを `mask` で下から欠けさせる | 世界の物理そのもの。ここだけが「本物」 | 物理停止。デッキはレール中央に静止、`--grind: 0.18em` 固定、`--wdth: 62` 固定 |
| **着地する** | STAIR | 各段のウィール / ベアリングが段の踏面に降りて止まる | `@supports (animation-timeline: view())` で `animation-timeline: view(block)`、`animation-range: entry 0% entry 40%`。`translateY(-24px)` → `0`、影 `0 0 0` → `0 2px 0 var(--asphalt)`。keyframe を 0% / 70% / 100% に置き、70% までに距離の 92% を進めて減速感を出す(timeline は linear なので、イージングは keyframe 配分で作る) | スクロールの関係が意味を運ぶ(降りる = 段を 1 つ降りるたびに 1 つ着地する) | `animation: none`。最初から着地済み。非対応ブラウザも同じ静止状態 |
| **失速する** | SHOP | 拾った物が黄の床の上で減速して止まる。合計金額と合計質量の数字が「転がって止まる」 | セクションが `view()` で入場したとき 1 回だけ(`@supports` 内)、各商品を `translateX(48px)` → `0` に `--ease-stall` 900ms。数字は `--ease-stall` で 1 行分だけ縦に滑る(カウントアップはしない) | 到着。動きが止まることが「店に着いた」の合図 | 即時表示 |
**断面ナビの現在地:** `@supports (animation-timeline: scroll())` で `animation-timeline: scroll(root)` によりマーカーが縦に移動する(4 スポット位置を keyframe の 0 / 33 / 66 / 100% に対応)。非対応では IntersectionObserver で `aria-current` を切り替えるだけ(移動アニメ無し)。reduced-motion でも `aria-current` の切替は残す(状態表示は消さない)。
**RAIL の物理(自前 verlet。依存追加なし)— 実装の確定値:**
- canvas は RAIL セクション内、`100vw × max(56vh, 360px)`。`devicePixelRatio` は 2 で上限。描画は `getContext('2d')`
- **固定タイムステップ 1/120 s**、1 フレーム最大 4 サブステップ、余りは蓄積。rAF ループは **IntersectionObserver でセクションが可視のときだけ**回す(`document.hidden` でも停止)
- **物体:** デッキ = 4 粒子の矩形(デスクトップ 180×14px、モバイル 120×10px)+ 距離拘束 6 本(辺 4 + 対角 2)、拘束反復 6 回。接地点は 20% / 80% 位置の 2 点(トラックの位置)。質量は選択中のデッキの g を 1,000 で割った相対値(1,180 g → 1.18)。剛体を verlet で近似する最小構成で、回転は粒子の位置差から自然に出る
- **レール:** 静的な線分(長さ 60vw、太さ 4px、色 `--steel`)。角度 θ は ±12° に clamp。**ドラッグ**はレール両端の 44px ハンドル(pointer イベント、`touch-action: none` はハンドル上だけ)を上下に動かして θ を変える。**傾き**は `deviceorientation` の `gamma` を `θ = clamp(gamma × 0.4, -12, 12)`、ローパス 0.15。iOS では `DeviceOrientationEvent.requestPermission()` がユーザー操作内でしか呼べないので、「傾きを使う」ボタン(44px、canvas 左下)を押した後だけ有効化。HTTPS 必須(44dat.com / CloudFront ともに満たす)
- **床:** canvas 下端の静的水平線。黒の帯の上端と一致させる(床 = アスファルト)
- **重力:** `2.0 × canvasHeight / s²`(canvas の高さに比例させ、モバイルでも落下時間が同じになる)。**レール上の摩擦:** 接触中は速度を毎サブステップ 0.985 倍(擦れて減速)。**床の摩擦:** 0.92 倍(すぐ止まる = 失速)。**反発係数 0.18**(着地で 1 回だけ小さく跳ねて止まる。2 回目の跳ねは高さ 3% 未満なので視認されない)
- **スクロール速度入力:** `Δscroll / Δt`(px/s)を毎フレーム測り、レール接触中のデッキにレール方向の速度 `min(|v| × 0.35, 900) px/s` を加える(向きはスクロール方向)。|v| < 50 px/s が 300ms 続いたら入力ゼロ → 摩擦で失速 → レール端から落ちれば床へ着地。**位置ではなく速度**を使うので、ピン留めではない
- **擦った距離 → 見出しの欠け:** レール接触中の |Δx| を積算し、`--grind = min(0.34em, grindPx / 600 × 0.34em)` を見出し要素の style に書く。見出しは `mask: linear-gradient(#000 0 0) top / 100% calc(100% - var(--grind)) no-repeat` で下から欠ける。欠けは**戻さない**(リロードまで残る = 削れた履歴)。欠けの断面が「切り取り」に見えないよう、見出しの下に幅 2px・間隔 12px の stencil ブリッジ線(`repeating-linear-gradient`)を `--grind` の高さぶんだけ描く
- **火花:** 接触中 60px 進むごとに 6〜10 粒子(色 `--spark`、寿命 300ms、生存上限 60)。canvas 内だけ
- **衝突イベント:** レールへの接触開始(接触速度 > 200px/s)と床への着地で `impact(強さ)` を発火。強さ = `min(1, 速度 / 1200)`。受け手は ①仕様の数字の `--wdth = 62 + 38 × 強さ`(420ms で 62 へ)②音(下記)
- **音(既定 OFF、opt-in 必須):** ナビの音トグル ON のときだけ。Web Audio で**合成**する(音源ファイルは調達しない): 擦れ = ホワイトノイズをバンドパス 1.2〜2.4kHz、接触中ループ、ゲインは速度に比例(最大 0.25)。着地 = 180Hz サイン 30ms 減衰 + ノイズ 12ms。衝突と同じフレームで鳴らす(遅延 ±50ms 以内)
- **リセット:** デッキが床で 1.6 秒静止したら「RESET」ボタン(44px、canvas 右下)を表示。押すとレール中央へ戻す。セクションが再入場したときも戻す
- **reduced-motion:** ループを回さず、平らなレール中央のデッキを 1 フレームだけ描く。ドラッグ・傾き・スクロール入力を bind しない。`--grind: 0.18em`、`--wdth: 62` を固定値で書く。音トグルは非表示
- **JS 無効:** canvas を隠し、同じ構図のインライン SVG(平らなレール + デッキ)を表示。見出し「RAIL」は欠け無しで見える(content は既定で可視)
- **性能:** 4 粒子 + 火花 60 なので計算は無視できる。主コストは canvas の塗りだけ。`will-change` は付けない。60fps を切る要因があるとすれば DPR 3 の端末なので 2 で上限
**JS を足す理由(animate.md の要求):** 「傾きと速度を入力にして物が滑り、端で落ちる」は CSS の scroll-driven animation では表現できない(CSS は位置の関数であって、速度・傾き・接触の状態機械を持てない)。依存ライブラリ(matter.js / GSAP)を足さない理由は、必要な物体が 1 つ(4 粒子)で、剛体・関節・多体衝突が要らないため。自前 verlet は 150 行以内で書ける。
### 4.5 写真 / 動画の役割: 商品は「白線地に置いた物」、環境は「曇天の路面」。動画は無し
- **動画は使わない。** 動くものは物理と CSS で、動画があると本物の物理が偽物に見える
- **商品写真(8 点):** 白線地(`#F2F0EA` と同じシームレス地)の上に置き、真上または真横から、左上からの硬い光、右下へ落ちる影。小物・手・人物・ブランドロゴ無し。デッキ裏面のグラフィックは**反射ベスト黄 1 色 + 黒の stencil 文字**(架空ブランドのグラフィックとして作る)。各写真の `data-img-spec` を 6 章に書く
- **環境写真(3 点、各スポット 1):** 曇天の平らな光、人物・ロゴ・看板文字無し。縁石(正面やや上から、ワックスの跡)、ハンドレール(角パイプ、側面から、上面がグラインドで光る)、コンクリートの 5 段階段(正面から)。**写真は背景ではなく障害物の説明**なので、帯の中に小さく(幅 40% 以内)置き、全画面には敷かない
- 写真はすべて `fill-images.sh` のプレースホルダ(`data-img-spec`)として作り、後工程で差し替える。差し替え前でもレイアウトが崩れないよう、アスペクト比を固定(商品 1:1、環境 4:3)
---
## 5. 確定トークン
builder はこの値をそのまま貼る。決め直さない。
### 5.1 配色(16 進で統一)
```css
--line-white: #F2F0EA; /* 路面の白線。ページ地・商品写真の地・黒の帯の上の文字 / 黄の面の上の文字には使わない */
--asphalt: #17181A; /* アスファルト。黒の帯・本文・見出し・ボタン地・フォーカスリング(白線地) / 大面積は帯の規則(4.1)の面積だけ */
--asphalt-2: #2A2C2F; /* 帯の内側の二次面(SHOP の商品スロット・RAIL 帯の商品の下地)/ 文字色には使わない */
--vest: #F5E71E; /* 反射ベスト黄。SHOP の床・SHOP の CTA 地・4px 反射ストライプ・::selection / SHOP 以外で面にしない・文字色にしない */
--vest-deep: #C9BC00; /* 黄の :active(押下)と、黄の床の上のヘアライン / それ以外に使わない */
--steel: #B9BEC3; /* レールの線(canvas)と黒の帯の上のヘアライン / 白線地の上の文字にしない(1.6:1) */
--chip: #5F615D; /* 白線地の上の補足テキスト(注記・価格の税込表記)。#F2F0EA に対して 5.6:1 / 見出しに使わない */
--gravel: #C9C7BF; /* 白線地の上のヘアライン・影の縁 / 文字色にしない */
--white-72: rgb(242 240 234 / .72); /* 黒の帯の上の補足テキスト(9:1 以上)/ 白線地では使わない */
--spark: #FFB03B; /* 火花(canvas 内のみ)/ DOM では使わない */
```
コントラスト(実測値の目安): `--asphalt` on `--line-white` 15.9:1 / `--asphalt` on `--vest` 14:1 / `--line-white` on `--asphalt` 15.9:1 / `--chip` on `--line-white` 5.6:1 / `--white-72` on `--asphalt` 9.5:1 / `--steel` on `--asphalt` 9.7:1(注記のみ)。**黄の上に白、白線の上に steel は禁止。**
### 5.2 タイポ
読み込み(Google Fonts、全て 200 確認済み):
```
(参考URLは非公開)
```
```css
--font-display: 'Anybody', 'Arial Narrow', sans-serif; /* 欧文看板・可変幅数字 */
--font-display-ja: 'Dela Gothic One', 'BIZ UDPGothic', sans-serif; /* 和文看板・副題 */
--font-stencil: 'Big Shoulders Stencil', 'Anybody', sans-serif; /* 注記・UI ラベル・ボタン */
--font-body: 'BIZ UDPGothic', 'Hiragino Sans', sans-serif; /* 本文 */
/* 級数(6 段)*/
--t-sign: clamp(4.5rem, 14vw, 11rem); /* hero 看板 GRIND / DISTRICT。line-height .86、letter-spacing -.01em、wdth 50、wght 800 */
--t-spot: clamp(3rem, 9vw, 7rem); /* スポット見出し CURB / RAIL / STAIR / SHOP。line-height .9、wdth 50、wght 800 */
--t-h2: clamp(1.5rem, 3.4vw, 2.6rem); /* 和文見出し(Dela Gothic One)。line-height 1.25、letter-spacing .02em */
--t-num: clamp(2rem, 5vw, 4rem); /* 可変幅数字(仕様・価格)。line-height 1、tabular-nums、wdth var(--wdth)、wght var(--wght) */
--t-body: clamp(.9375rem, .9rem + .2vw, 1.0625rem); /* 本文。line-height 1.8、max-width 36em、letter-spacing 0 */
--t-label: clamp(.75rem, .7rem + .25vw, .875rem); /* stencil 注記・ボタン・ナビ。line-height 1.2、letter-spacing .06em、uppercase、opsz 72、wght 700 */
/* 可変軸の既定値(RAIL の物理が書き換える)*/
--wdth: 62; /* 62 → 衝突で最大 100 → 420ms で 62 */
--wght: 500; /* 500 → 傾き ±12° で 900 */
```
- 数字は `font-variant-numeric: tabular-nums lining-nums`。単位(mm / A / g / ¥)は数字の 0.5em、baseline 揃え
- 和文見出し: `text-wrap: balance; word-break: auto-phrase; overflow-wrap: anywhere; line-break: strict;` 読点改行は JSON の `\n` + `white-space: pre-line`
- 本文の和文は `font-feature-settings: "palt" 0`(UD 書体の等幅を活かす)。和文見出しだけ `"palt" 1`
- 看板の欧文は `text-transform: uppercase`。和文は変換しない
### 5.3 モーションの語彙(イージング 3 + linear)
```css
--ease-land: cubic-bezier(0.16, 1, 0.3, 1); /* 着地・確定・パネル到着。指数的減速 */
--ease-pop: cubic-bezier(0.34, 1.56, 0.64, 1); /* 跳ねる。1 回だけのオーバーシュート。ADD ボタンの離し・CURB のデッキ hover 復帰だけに使う */
--ease-stall: cubic-bezier(0.05, 0.7, 0.1, 1); /* 失速。速く出て長く止まる。SHOP の入場と数字の転がり */
/* 擦れる = イージング無し(linear)。物理の値を毎フレーム書くだけ */
--d-feedback: 120ms; /* 沈む・色が変わる */
--d-pop: 380ms; /* 弾んで戻る */
--d-land: 520ms; /* 着地・確定 */
--d-stall: 900ms; /* 失速 */
--d-wdth: 420ms; /* 数字の幅が戻る */
```
| 動き | イージング | 時間 |
|---|---|---|
| ボタン押下(沈む 2px、影 0) | `linear` | 120ms |
| ボタン離し(戻って 1 回弾む) | `--ease-pop` | 380ms |
| デッキ hover(1px 浮く / 戻る) | `--ease-land` / `--ease-pop` | 200ms / 380ms |
| STAIR の着地(scroll-driven、keyframe 配分で減速) | timeline は linear、keyframe 0 / 70 / 100% | スクロール依存 |
| SHOP の入場(48px 右から止まる) | `--ease-stall` | 900ms |
| SHOP の数字(1 行ぶん縦に滑る) | `--ease-stall` | 900ms |
| 数字の幅(wdth 100 → 62) | `--ease-land` | 420ms |
| 断面ナビのマーカー | scroll-driven linear | スクロール依存 |
| カート数バッジ(+1) | `--ease-pop` | 380ms |
### 5.4 余白・角丸・線
```css
/* 基準 8px。使う段は 8 つ */
--s-1: 4px; /* ヘアラインと文字の間、注記の行間調整 */
--s-2: 8px; /* 段と段の隙間(STAIR)、ボタン内の上下 */
--s-3: 16px; /* 注記と商品の間、見出しの下 */
--s-4: 24px; /* 商品同士(モバイル)、ボタンの左右 padding */
--s-5: 40px; /* 商品同士(デスクトップ)、帯の内側 padding(モバイル) */
--s-6: 64px; /* 見出しの上、帯の内側 padding(デスクトップ)、スポット間(モバイル) */
--s-7: 104px; /* hero の看板とデッキ静止画の間 */
--s-8: 160px; /* スポット間(デスクトップ) */
/* 角丸 */
--r-0: 0; /* 看板・帯・ボタン・写真・すべての面 */
--r-wheel: 999px; /* 音トグルと数量ステッパーの「ウィール」だけ */
/* 線 */
--hairline-light: 1px solid var(--gravel); /* 白線地の区切り */
--hairline-dark: 1px solid rgb(242 240 234 / .24); /* 黒の帯の区切り */
--rail-line: 4px solid var(--steel); /* レール(canvas 外の装飾では使わない) */
--curb-edge: 2px solid var(--asphalt); /* 縁石の上端 */
--stripe: 4px solid var(--vest); /* 反射ストライプ(SHOP 前の黄はこれだけ) */
/* 影(硬い影。offset あり、blur は小さく) */
--shadow-object: 0 2px 0 var(--asphalt); /* 着地した物 */
--shadow-lift: 0 3px 0 var(--asphalt), 0 6px 8px rgb(23 24 26 / .18); /* hover で 1px 浮いた物 */
/* ボタン */
--btn-h: 48px; --btn-px: 24px; /* 最小 44px を満たす */
/* フォーカス */
--focus-light: 3px solid var(--asphalt); /* outline-offset 3px */
--focus-dark: 3px solid var(--vest);
--focus-vest: 3px solid var(--asphalt);
```
- ブラウザ面もトークンで塗る: `::selection`(黄地・黒文字)/ `caret-color: var(--asphalt)` / スクロールバー(`scrollbar-color: var(--asphalt) var(--line-white)`、幅 `thin`)/ `text-underline-offset: .18em`、リンクの下線は `text-decoration-thickness: 2px`
---
## 6. ページ構成
セクション順 = 街を降りる順。全セクションが別のレイアウト族(4.3)。
### 0. ナビ(64px、床のレベル)
- 目的: 4 スポットのどこにいるかと、拾った物の数を常に見せる
- 要素: ロゴ(左)/ CURB・RAIL・STAIR・SHOP のアンカー(中央、`--font-stencil`)/ カート数バッジ(4px の黄ストライプ付き)/ 音トグル(真円 44px、既定 OFF、ラベル「SOUND OFF / ON」)/ 断面ナビ(右端の縦 1 列、1024px 以上。4 スポットの位置に stencil で質量の目安 `1,180 g / 740 g / 220 g / 3,010 g` を添える = 参考サイトの重さ順リストの翻案)
- モバイル: ロゴ + カート + 音トグル。断面ナビは右端 12px 幅の縦バーに縮む(タップで各スポット)
### 1. HERO / 街の入口
- 主張: 店を降りながら板を組む、と 1 行で分からせる
- 要素: 看板「GRIND / DISTRICT」(`--t-sign`、2 行、カラム 1〜9)/ 和文「板場」(`--font-display-ja`、看板の右下に重ねて配置)/ タグライン「街を降りながら、板を組む。」(`--t-h2`)/ 3 連の名詞止め「縁石で板。レールでトラック。階段でウィール。」(本文)/ 主 CTA「降りる」(ボタン、CURB へスクロール)/ 副 CTA「SHOP へ直行」(テキストリンク)/ デッキ側面の静止画(カラム 10〜12、`data-img-spec`)/ 画面下端に縁石の帯 12vh が始まる(hero と CURB は同じ帯で繋がる)
- ファーストビューで見えるもの: 店名・何の店か・何ができるか・次に押す物。看板は物なので入場アニメ無し(最初から置いてある)
### 2. CURB(縁石)— 跳ねる
- 主張: 板は最初の障害物で決まる
- 要素: スポット見出し「CURB」(帯の上端に乗る)/ 和文副題「縁石。高さ 15 cm。板の幅はここで決まる。」/ 縁石の環境写真(帯の中、幅 40%)/ デッキ 3 枚(7.75 / 8.0 / 8.25、立面に寄りかかる)。各デッキに: 名前 / 幅(可変幅数字)/ 質量 g(stencil)/ 価格 / ADD ボタン / 「どの縁石に」の 1 行(「低い縁石とマニュアル台」「なんでも」「高い縁石と広い着地」)
- ADD で跳ねる(4.4)。カート数が +1 で弾む
### 3. RAIL(レール)— 擦れる(本命)
- 主張: 幅が合わないと、擦れない
- 要素: canvas(56vh 以上。レール・デッキ・火花・ハンドル 2 つ・「傾きを使う」ボタン・RESET ボタン)/ スポット見出し「RAIL」(canvas の**後ろ**に置き、欠ける)/ 和文副題「レール。角パイプ 50 mm。トラックの幅はここで決まる。」/ 黒の帯 40vh にトラック 3 幅(5.0 / 5.25 / 5.5、各: 幅の可変幅数字 / 対応デッキ幅 / 質量 / 価格 / ADD)+ ワックス 1 点(「擦れを速くする」)/ 操作の説明は stencil 1 行「DRAG THE RAIL / TILT YOUR PHONE / SCROLL FAST」
- 音は音トグル ON のときだけ(4.4)
### 4. STAIR(階段)— 着地する
- 主張: 硬いほど速く、柔らかいほど静か
- 要素: 3 段の帯(右に 1 カラムずつずれる)/ スポット見出し「STAIR」/ 和文副題「階段。5 段。ウィールの硬さはここで決まる。」/ 段 1: ウィール 54mm 99A(「硬い。速い。段の音が大きい」)/ 段 2: ウィール 56mm 101A(「もっと硬い。雨の後は滑る」)/ 段 3: ベアリング 2 種(ABEC 相当の表記はせず「静か / 速い」の 2 語で)。各: 可変幅数字 / 質量 / 価格 / ADD / 階段の環境写真は段 1 の踏面に幅 40%
- 各段の商品が scroll-driven で着地(4.4)
### 5. SHOP(店)— 失速する
- 主張: 拾ったものを、ここで組む
- 要素: 全面黒 + 黄の床(60vh 以上)/ スポット見出し「SHOP」/ 和文副題「板場。拾ったものを、ここで組む。」/ 床の上に「拾った物」が横一列で止まっている(未選択のスロットは `--asphalt-2` の空の枠線無し面 + stencil で「DECK / TRUCKS / WHEELS / BEARINGS」)/ 合計質量(可変幅数字、例「3,010 g」)/ 合計金額(「¥33,000」税込表記 1 回)/ 主 CTA「組む」(黄地・黒文字、48px)/ 「組み立て無料。持ち込みの板も組む。」の 1 行 / 店舗情報(合成: 住所・営業時間・定休日・地図リンク)/ 3 連「拾う。組む。降りる。」
- 入場で失速(4.4)。以後この節では何も動かない
### 6. フッター(床の下)
- 主張: 法定情報と連絡先。装飾しない
- 要素: 会社名(合成)/ 特定商取引法に基づく表記 / プライバシーポリシー / SNS 2 つ(リンクは `#`)/ 「© GRIND DISTRICT 板場」/ デッキの静止画が右端で止まっている(hero と同じ画像、動かない)
### 画像の `data-img-spec`(12 点)
1. hero デッキ側面: 「スケートボードのコンプリート 1 台を真横から。白線色(#F2F0EA)のシームレス地、左上からの硬い光、右下に短い影。ロゴ・人物無し」
2. デッキ 7.75 裏面: 「デッキ裏面を真上から。反射ベスト黄(#F5E71E)1 色のグラフィックに黒の stencil 文字 GRIND。白線色の地」
3. デッキ 8.0 裏面: 同上、文字は DISTRICT
4. デッキ 8.25 裏面: 同上、文字は 板場
5. トラック 1 組: 「シルバーのスケートボードトラック 1 組を真上から。白線色の地、硬い光」
6. ワックス: 「四角い黒のスケートワックス 1 個。白線色の地」
7. ウィール 4 個(白): 「白いスケートウィール 4 個を真上から。白線色の地」
8. ウィール 4 個(黒): 同上、黒
9. ベアリング 8 個: 「スケートベアリング 8 個を 2 列に。箱無し。白線色の地」
10. 縁石: 「都市の歩道の縁石を正面やや上から。曇天の平らな光。コンクリートの粒とワックスの跡。人物・ロゴ・文字無し」
11. ハンドレール: 「公園の角パイプのハンドレールを側面から。上面がグラインドで光っている。曇天。人物無し」
12. 階段: 「コンクリートの 5 段の階段を正面から。曇天の平らな光。人物・文字無し」
(番号 12 まで。hero とフッターは同じ 1 を使う)
### ファイル計画(portfolio-demos 規約)
- `src/pages/grind-district/index.astro` / `src/pages/grind-district/en/index.astro`
- `src/layouts/GrindDistrictLayout.astro`(`DemoBanner` + skip link + fonts link + `<slot />`)
- `src/components/grind-district/{Nav,Hero,CurbSpot,RailSpot,StairSpot,ShopSpot,Footer,Scripts}.astro`(物理と入力は `Scripts.astro` の `<script>` 1 本。既存の `meikyo-ip/MeikyoScripts.astro` と同じ作法: `matchMedia('(prefers-reduced-motion: reduce)')` に動的追従、IO で可視時だけ rAF)
- `src/styles/grind-district.css`(`body.grind-district-page` スコープ。`@import "tailwindcss" source(none)` + 明示 `@source`。ビルダーが素の `@import` で書いても `npm run fix:tailwind` が直す)
- `site-content-grind-district.json` / `site-content-grind-district.en.json`(コピー・価格・質量・画像 spec を全部ここに)
- `panel/signature-grind-district.txt` に 1 行: `街の縦断面(障害物) | レール上の verlet デッキと削れる見出し | 動詞終止の常体・名詞止め 3 連(否定→肯定構文なし)`
---
## 7. コピー方針
### Hero コピーの草案
| 案 | 和文 | 英文 | 評価 |
|---|---|---|---|
| **A(採用)** | 街を降りながら、板を組む。 | Ride down the block. Build the board on the way. | 何をする店か(組む)と、どうやって(降りながら)が 1 文。動詞 2 つで終わる |
| B | 縁石で板。レールでトラック。階段でウィール。 | Curb for the deck. Rail for the trucks. Stairs for the wheels. | 構造そのもの。A の直下の 3 連として使う |
| C | 降りた先に、店がある。 | The shop is at the bottom. | 短いが「何の店か」が無い。副 CTA「SHOP へ直行」の補助文に回す |
| D | 重さを選ぶ。 | Pick your weight. | 質量の翻案が効くが、初見で意味が取れない。SHOP の合計質量の注記に使う |
**hero 全文(採用):**
> GRIND DISTRICT(看板)/ 板場(和文)
> 街を降りながら、板を組む。
> 縁石で板。レールでトラック。階段でウィール。障害物ごとに合う物を置いた。降りて、拾って、店で組む。
> [降りる] SHOP へ直行
### 各セクションの言葉のトーン
- **CURB:** 高さと幅の数字で語る。「縁石。高さ 15 cm。板の幅はここで決まる。」→ 各デッキに「どの縁石に」の 1 行(場面)
- **RAIL:** 操作を stencil で 3 語(DRAG THE RAIL / TILT YOUR PHONE / SCROLL FAST)。副題は「幅が合わないと、擦れない。」のように因果を 1 文で。「面白い」「遊べる」と自分で言わない
- **STAIR:** 対比で語る。「硬いほど速く、柔らかいほど静か。」段ごとに 1 行の性格(「段の音が大きい」「雨の後は滑る」)
- **SHOP:** 到着の言葉。「拾ったものを、ここで組む。」「組み立て無料。持ち込みの板も組む。」最後に 3 連「拾う。組む。降りる。」
- **ボタン:** 動詞 1 語(降りる / ADD / 組む / RESET)。「カートに入れる」「購入する」「詳細を見る」は使わない
- **注記(stencil):** 単位付きの数値だけ(`1,180 g` / `8.0` / `54 mm 99 A`)。形容詞を入れない
- **英語版:** 見出しの CURB / RAIL / STAIR / SHOP は共通。和文副題は "Curb. 15 cm high. The deck width is decided here." のように同じ構造で。stencil 注記は共通
---
## 8. クラフトの肝(ここで勝つ 5 点)
1. **押下の重さ(ホバー / 押下):** ADD ボタンは hover で何も起きず(浮かない)、押している間だけ 2px 沈んで影が消え、離すと `--ease-pop` 380ms で**1 回だけ**弾んで元の位置に戻る。2 回揺れたら失敗。デッキ写真は hover で 1px 浮き(`--shadow-lift`)、離れると `--ease-pop` で戻る。ボタンが「物」であることは、この 2px と 1 回の弾みでしか伝わらない
2. **止まることが到着(間):** SHOP では入場の 900ms で拾った物が右から滑り込んで失速し、その後は**何も動かない**。合計金額はカウントアップせず、1 行ぶん縦に滑って止まる(「増えていく」の誤読を避ける)。ページで最も静かな節が最も下にあることで「降りきった」が分かる
3. **削れて戻らない見出し(タイポ詳細):** RAIL の見出しはデッキが擦った距離だけ下端が欠け、最大 0.34em。欠けの断面には幅 2px・間隔 12px の stencil ブリッジ線を描いて「切り取り」ではなく「削れ」に見せる。**欠けはリロードまで戻らない。** 見出しが物であることは、傷が残ることで証明される
4. **黄が線から面になる(色のニュアンス):** SHOP に着くまで黄は 4px の反射ストライプ(カート数バッジ・ADD の下端・断面ナビの現在位置)としてしか現れず、SHOP で幅 100% × 60vh の床になる。黒の帯は 12vh → 40vh → 70vh → 100% と増える。配色を「面積の推移」で設計するので、どのスポットの切り抜きを見ても位置が分かる
5. **物理は 1 か所、他は借りない(モーション量):** verlet はレールだけ。CURB / STAIR / SHOP は CSS(transition / scroll-driven)で 4 語彙を担い、parallax・ピン留め・入場フェードは 0 箇所。canvas は可視時だけ回り、DPR 2 上限、火花 60 以下。「動くものが少ないのに動いている実感がある」のは、動く物が本物だから
---
## 9. ロゴ
- **何を象るか:** 街の断面(縁石 → レール → 階段と下っていく**段差の 1 本線**)と、デッキの側面(ノーズとテールが上がった **1 本の弧**)。この 2 本線の関係 — 段差の上にデッキが乗っている、または段差をデッキの弧がなぞっている — が「障害物を読む」というブランドの原理をそのまま図にする。幾何・線。面で塗らない
- **言葉の扱い:** 欧文「GRIND DISTRICT」が主(ultra-condensed の看板文字と同じ声)。和文「板場」は副で、stencil の判子のように小さく添える(店名の読みと「現場」の意味を持たせる)。略称「GD」は作らない(2 文字では障害物が読めない)。タグラインはロゴに含めない
- **ブランド側の意味づけ:** ロゴは看板であり、床に置ける物であること。背景に色面を持たず、白線地・黒の帯・黄の床のどこに置いても 1 色(黒または白線色)で成立すること
- **避けたい既視感:** 炎・髑髏・翼・十字・稲妻(Thrasher / Independent 系のアイコン)、円形のクレスト、赤い box logo、龍や漢字の刺青風、手描きグラフィティ、レトロな筆記体、ダイヤ形の道路標識。板の平面図(上から見たデッキの輪郭)も既視感が強いので使わない
- ※ シンボルの有無・線幅・字間・サイズ比などの「作り」は、この後の Step 1 で参考サイトの型紙(ref-structure.json の logo)を調べてから決める。ここでは決め打ちしない
---
## 10. 受け入れチェックリスト
すべて「見れば / 測れば分かる」形。builder は 1 項目ずつ実物照合して観測値付きの PASS / FAIL 表を PR に貼る。
1. **[390px]** hero の看板「GRIND」「DISTRICT」が各 1 行、合計 2 行に収まり 3 行目が出ない。横スクロールバーも出ない(`document.documentElement.scrollWidth === 390`)
2. **[390px]** RAIL の canvas は高さ 56vh 以上あり、レール両端のハンドル(44×44px 以上)がビューポート内で左右に分かれて見え、商品(トラック 3 幅)と重ならない
3. **[署名モーション]** RAIL でレールの端をドラッグして傾けると(スマホは「傾きを使う」を押して端末を傾けると)、デッキが低い側へ滑り、レールの端から落ちて床で止まる。床で 2 回以上跳ねない
4. **[署名タイポ・肝 3]** デッキがレールを擦っている間だけ見出し「RAIL」の下端が欠けていき、擦った距離 300px 以上で欠けが 0.17em 以上になる。擦るのをやめても欠けは戻らない
5. **[肝 5]** 1,500px/s 以上の速度でスクロールしている間はデッキがレールの上を滑走し、スクロールを止めてから 1.5 秒以内に失速して止まる(または端から落ちて着地する)
6. **[肝 1]** ADD ボタンは押している間 2px 下がって影が消え、離すと 400ms 以内に 1 回だけ元の位置を越えて戻る。2 回以上揺れない
7. 押せるもの(ADD・数量ステッパー・音トグル・「傾きを使う」・RESET・ナビのリンク・断面ナビの縦バー)はすべて最小 44×44px
8. 音は初期状態で鳴らず、音トグルを ON にした後だけ、デッキがレールに当たった瞬間と床に着地した瞬間に音が出る(`AudioContext` はトグル ON の操作内で生成される)
9. **[reduced-motion]** `prefers-reduced-motion: reduce` で canvas のデッキはレール中央に静止し、ドラッグ・傾き・スクロールのどれでも動かない。見出しの欠けは 0.18em 固定。断面ナビの `aria-current` だけは切り替わる
10. **[肝 4]** SHOP セクションの背景は全面 `#17181A` で、その中に幅 100% × 高さ 60vh 以上の `#F5E71E` の面がある。SHOP より上のセクションに `#F5E71E` の面(高さ 8px 以上の塗り)は存在しない
11. STAIR の 3 段それぞれで、段がビューポート下端から入るとウィール / ベアリングの写真が 24px 上から降りて踏面で止まる。`animation-timeline: view()` 非対応ブラウザでは最初から止まった位置にある
12. 仕様の数字(例: 5.25)はデッキの衝突の瞬間に幅が広がり(`font-variation-settings` の wdth 62 → 最大 100)、420ms 以内に 62 へ戻る。衝突が無いときは 62 のまま
未照合の項目は SKILL.md Step 5 の FAIL 条件。 制作記録
このデモは AI が設計・実装しました。使ったモデルと実際の制作記録をそのまま公開しています。
- 生成モデル
- fable(effort: ultracode)
- 実行環境
- Claude Code 2.1.251
- 制作時間
- 49分12秒
- 人による修正
- 0回(一発生成)
- やり取り
- 161 メッセージ
- 出力トークン
- 258,289
- 読み込みトークン
- 40,491,706
写真は生成 AI で作成した架空のイメージです。ブランド・実績・数値はすべて架空のもので、実在の企業とは関係ありません。
この業種・このテイストで、御社のサイトを制作します。
掲載デモと同じ品質のオリジナルサイトを、設計から公開まで一貫して承ります。「このデモの雰囲気で」の一言から始められます。