# DESIGN.md — 画廊の回遊 / gallery-kaiyu

> **使い方**: このファイルをプロジェクトに置き、AIに
> 「DESIGN.md に従って◯◯のサイトを作って」と指示してください。
> ライセンス: 商用利用可・改変可・クレジット不要（AIっぽくないデザイン見本帳 / サードパーティートラスト）

## 1. コンセプト

画廊の中を歩くように、横へ横へと進む体験。モノクロに統一した写真と明朝、
圧倒的な余白で、UIは展示室の壁に徹する。主役は常に作品（写真・図版）の連なりで、
サイトの構造は「順路」として設計する。縦スクロールは導入と実務情報だけに使い、
核となる展示は横スクロールのギャラリー動線に置く。

**キーワード**: 回遊 / モノクロ / 順路 / 図録 / 余白
**この見た目が向く場面**: ギャラリー・写真スタジオ・美術館・工芸作家のポートフォリオ・
建築設計事務所の作品集

## 2. タイポグラフィ

- 和文見出し: Zen Old Mincho / ウェイト 500〜600（大見出しは 500、節見出し・強調語は 600）
- 和文本文: Zen Old Mincho / ウェイト 400（このフォントに 300 は存在しないため、
  軽さは字間・行間・余白で作る。ウェイトを 300 相当に見せかけて別フォントを混ぜない）
- 欧文・数字: Cormorant Garamond（展覧会英題・作品の英題・年代・キャプション末尾の
  出典表記に使う。**必ずイタリックで、英題やキャプションの装飾として使う**。
  地の文の代替書体としては使わない。**Inter に置換しない**）
- 見出しスケール: h1（展覧会名・縦書き） clamp(38px, 6vw, 60px) / h2（節見出し）
  clamp(26px, 3.6vw, 34px) / h3（作品名） 19px / 本文 16px / キャプション 12.5〜13px
- 特記: 級数差だけでなく**字間と余白**で階層を作る。見出しは字間 0.3em 前後まで開く。
  英字ラベル（節番号・作品英題）は字間 0.16〜0.3em。空虚な機械翻訳のeyebrowにしない
  （§8参照）。**縦書き（`writing-mode: vertical-rl`）を展覧会名・章タイトルに使う。**
  一覧性が要る本文（作家紹介・利用案内・キャプション本文）は横書きのまま

## 3. カラー

**monochrome。彩度のある色を1色も足さない。**

| 役割 | 値 | 使用比率の目安 |
|---|---|---|
| 地（月白・ベース） | #f7f7f5 | 65% |
| 地（節替え） | #efeeea | — |
| 墨（見出し・強い要素） | #1f1e1c | 20% |
| 薄墨（本文弱・キャプション・英字ラベル） | #686765 | 10% |
| 罫線・境界 | #e3e2de | — |

- 配色ルール: 純黒 #000000・純白 #ffffff を使わない。彩度を持つ色（青・朱・金など）を
  一切追加しない。強調は「墨の濃さ」と「文字の大きさ・字間」でつける
- **薄墨 `#686765` は `#f7f7f5` 地で 5.3:1、`#efeeea` 地で 4.9:1 のコントラストがあり、
  13px 程度の小さなキャプション・ラベルでも AA (4.5:1) を満たす。** これより明るい
  灰色（例: `#8e8c87` 系、3:1前後）をキャプションや英字ラベルの既定色にしない
- 写真の上に文字を載せる場合は**不透明の帯**を敷く（§5・§9参照）。半透明の
  グラデーションスクリムやガラス風の`backdrop-filter`は使わない

## 4. レイアウト・余白

- コンテンツ最大幅: 1120px（本文カラムは 640px まで絞る）
- **レイアウトの核は横スクロール・ギャラリー（`scroll-snap-type: x mandatory`）。**
  1作品=1スナップ点。作品と作品の間は 88px 以上あける。縦スクロールは
  「入口（ヒーロー）」「出品作家」「アーカイブ」「利用案内」の4節だけに使う
- グリッドの性格: 縦スクロール部は中央寄せの1本道。横スクロール部は左右の
  余白（10vw程度）を大きく取り、最初と最後の作品も画面中央でスナップさせる
- セクション間余白: 上下 160〜170px 基準。**余白を埋めるための飾り線・ドット・
  アイコンを足さない**
- **ヒーローの構成（"展示室の入口"）**: 画面を左1/3・右2/3に分割し、右2/3に
  現在の企画展のメイン写真を裁ち落としで置く。左1/3には縦書きで
  「展覧会名（大）→ 英題イタリック（中）→ 会期（小）→ 回数ラベル（小）」を
  右から左へ並べる（`flex-direction: row-reverse` で縦書きの列を自然な順序にする）。
  **ボタンを置かない。** 誘導はスクロールという行為そのものに委ねる。
  下部に小さな一筆線のスクロールキュー（自作、装飾のみ）を置いてよい。
  「中央寄せ見出し＋サブコピー＋ボタン2つ」の定型を絶対に作らない

## 5. コンポーネントの質感

- ヘッダー・ナビゲーション: 初期は透明地・スクロールで地色に切り替わる
  （`backdrop-filter` は使わず不透明な `--color-bg` に切り替える）。ナビリンクは
  既定で薄墨、ホバーで墨色に変わり**字間が広がる**（下線は使わない。
  下線を使うテイストは別にあるため、ここでは字間の変化で差別化する）
- 角丸: 0px（すべて直角）/ 影: 使わない（box-shadow 禁止）/ 境界線: 1px solid
  `--color-line`
- ボタン: **原則使わない。** ヒーローに限らずサイト全体で主ボタン/副ボタンの
  対を作らない。誘導はテキストリンクとスクロールに委ねる
- 横スクロール・ギャラリーの1点（`.artwork`）:
  - 写真は**トリミングしない**（`object-fit: contain`）。額装のように、作品ごとの
    アスペクト比のまま高さをそろえて幅は可変にする（横長は横に大きく、縦長は
    幅が狭く並ぶ＝実際の展示壁の掛け方に近い）
  - 写真の下に**常時表示のキャプション**（figcaption）を置く。図録の様式で
    「作品番号 → 作品名（和文） → 英題（イタリック） → 作者・年代・技法・出典」の順
  - 写真にマウスオーバー（またはフォーカス）すると、写真下端に**不透明の墨帯**が
    せり上がり、英題だけが浮かぶ（§9コード例参照）。半透明のグラデーションで
    にじませない
  - 進行インジケータ（「01 / 06」）はギャラリー節の間だけ画面に固定表示する
- カード的要素: 「アイコン＋見出し＋説明」の角丸カードを**一切使わない**。
  出品作家・アーカイブの一覧は罫線区切りの横並びリスト（グリッド）で組む
- フォーム要素: 本テイストは問い合わせフォームを持たない
  （電話・メールのテキスト表記のみ）。フォームが必要な場合は下線1pxのみの
  枠なしinputとし、角丸は使わない
- 画像の扱い: 全写真に `grayscale(1) contrast(1.04)` を一律適用してトーンを統一する
  （§9）。角丸・影・枠線を使わない

## 6. モーション

- 量: rich。ただし「動き＝リッチ」を安易な均一フェードで済ませない
- 使う動き:
  - ヒーロー写真・縦書きテキストは初回のみフェード＋わずかな上昇（1.1〜1.4秒）。
    **このトリガーは `window.addEventListener('load', …)` または単発の `setTimeout`
    のみで発火させ、`requestAnimationFrame` は使わない**（rAFは横スクロール・
    ギャラリーのキャプション視差専用ですらなく、本テイストのどの用途にも使わない。
    tools/slop-scan.py の「カウントアップ疑い」検知は rAF ＋ `.textContent`書き換え
    ＋ 数値操作 の組み合わせをまとめて拾うため、進行インジケータ「01 / 06」用の
    正当な `.textContent` 書き換えがある本テイストでは、無関係な箇所で rAF を
    使うだけでも誤検知の引き金になる）
  - 縦スクロールの各節は IntersectionObserver で登場。**見出しは長く遅く
    （1.1秒）、リード文はさらに遅れて（1s, delay 0.2s）、リスト項目は
    0.7〜0.8秒**というように**役割ごとに速さを変える**。全要素を同じ0.6秒で
    フェードさせない
  - 横スクロール・ギャラリーは `scroll-snap` で進む。作品のキャプションは、
    スクロール位置に応じてわずかに横方向へずれ、CSSの `transition` で
    追いつく（§9）。**`requestAnimationFrame` は本テイストのどの用途にも
    一切使わない**（連続ループはもちろん、ヒーロー初回フェードや進行
    インジケータ更新のような単発トリガーとしても使わない）。初期表示・
    遅延発火はすべて `setTimeout` / `load`イベント / `IntersectionObserver`
    の組み合わせだけで実装する（実装をシンプルに保ち、スクロールイベント
    ごとの位置計算とCSS遷移だけで「少し遅れてついてくる」感触を作る）
  - 作品へのホバー/フォーカスで英題が不透明の帯とともにせり上がる（0.5秒）
  - ヘッダーはスクロールで透明→不透明に切り替わる（0.4秒）
- 使わない動き: 自動カルーセル、数字のカウントアップ、マーキー、パララックスの
  背景ブロブ、バウンス、拡大縮小のズーム演出、0.6秒一律の均一フェード
- `prefers-reduced-motion: reduce` 時はすべての transition/animation を止め、
  要素は最終状態で即表示する。横スクロールの `scroll-snap` 自体は動きの演出では
  なく構造なので維持してよい

## 7. 写真・イラスト・図版

- 写真がサイトの主役（`ornament: photo-dominant`）。5〜6点、CC0 /
  パブリックドメインのみを使用し、被写体は「静物・建築・風景・古典写真」など
  単体で展示作品として成立するものに限る。**人物のクローズアップ・ポートレートは
  避ける**（肖像の配慮。遠景に小さく人影が写り込む程度は可）
- 全写真に同一のグレースケール・フィルタを適用し、トーンを統一する（§9）。
  撮影年代・原版の色味が違っても、フィルタを通すことで「1つの展示」として
  一貫させる
- 写真はトリミングしない（`object-fit: contain`）。角丸・影・枠線を使わない。
  Pinterest風のグリッドに敷き詰めない（§8参照）
- キャプションは図録の様式（作品名・英題・作者/出典・年代・技法）で統一し、
  SNS風の短い一言キャプションにしない

## 8. 禁止事項（must not）

- Inter / Roboto / Arial / Noto Sans / Helvetica を使わない（明朝＝Zen Old Mincho
  で組む。欧文は Cormorant Garamond のイタリックのみ）
- グラデーションを一切使わない（背景・文字・ボタンすべて）。box-shadow を使わない。
  border-radius は常に 0
- 純黒 #000000・純白 #ffffff を使わない。彩度のある色（青・朱・金・緑など）を
  1色も追加しない
- 中央寄せの定型ヒーロー（見出し＋サブコピー＋ボタン2つ）を作らない。
  ヒーローにボタンを置かない
- **「ギャラリー風＝グリッドに写真を敷き詰める」に逃げない。** Pinterest型の
  マソンリーグリッド・正方形サムネイルの均一グリッドを作らない。
  横スクロールの1本の順路（`scroll-snap-type: x`）以外のギャラリー表現を
  メイン展示に使わない
- 写真に角丸をつけない。影をつけない。半透明グラデーションのスクリムで
  文字を載せない（載せる場合は不透明の帯のみ、§5・§9）
- 自動で流れるカルーセル・マーキー・タイプライター演出・数字のカウントアップを
  使わない
- 「アイコン＋見出し＋説明」の角丸カードを使わない（出品作家・アーカイブは
  罫線区切りのリストで組む）
- 絵文字をアイコンとして使わない（装飾に線画が必要な場合は自作インラインSVGのみ。
  本テイストでは基本的にアイコンを使わず、文字と罫線と写真だけで構成する）
- 全要素を同じ0.6秒の均一フェードで登場させない（§6の速度差を守る）
- 人物のクローズアップ写真を展示作品として使わない
- **`requestAnimationFrame` を一切使わない。** 本テイストの初期表示・遅延発火に
  許可される手段は次の3つのみ（排他リスト。これ以外は使わない）：
  `window.addEventListener('load', …)` / 単発の `setTimeout` /
  `IntersectionObserver`。ヒーロー初回フェード・進行インジケータ更新・
  キャプション視差のいずれも、この3手段の組み合わせだけで実装する
  （§6・§9のコード例が唯一の正解実装。rAFを使った代替実装を作らない）

## 9. 実装ノート

```css
/* tokens.css — この変数セットをそのまま使うこと */
:root {
  --color-bg: #f7f7f5;
  --color-bg-alt: #efeeea;
  --color-ink: #1f1e1c;
  --color-text: #1f1e1c;
  --color-text-weak: #686765;  /* #f7f7f5地で5.3:1・#efeeea地で4.9:1。AA余裕あり */
  --color-line: #e3e2de;

  /* 変数には総称ファミリ(serif)を含めないこと。フォールバック連結が壊れる */
  --font-heading: "Zen Old Mincho";
  --font-body: "Zen Old Mincho";
  --font-latin: "Cormorant Garamond";

  --max-width: 1120px;
  --measure: 640px;
  --radius: 0;

  --photo-filter: grayscale(1) contrast(1.04); /* 全写真に一律適用するトーン統一フィルタ */
}
```

- フォント読み込み:
  `https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,300;0,400;0,500;1,400;1,500&family=Zen+Old+Mincho:wght@400;500;600;700&display=swap`
- 本文の font-family は `var(--font-latin), var(--font-body), serif` の順に指定する
  （英数字が自動で Cormorant になる）

**写真のトーン統一（全写真に必ず適用）:**
```css
.artwork-frame img, .hero-photo-wrap img {
  filter: var(--photo-filter);
  object-fit: contain;   /* トリミングしない。cover でクロップしない */
}
```

**横スクロール・ギャラリーの骨格（1作品=1スナップ点。マソンリーグリッドにしない）:**
```html
<div class="gallery-track" id="galleryTrack" role="list">
  <figure class="artwork" role="listitem">
    <div class="artwork-frame">
      <img src="..." alt="…具体的な被写体の説明…" loading="lazy">
      <div class="artwork-scrim" aria-hidden="true">
        <span class="artwork-scrim-title">English Title, Italic</span>
      </div>
    </div>
    <figcaption class="artwork-caption">
      <p class="ac-index">01</p>
      <h3 class="ac-title">作品名（和文）</h3>
      <p class="ac-en">English Title</p>
      <p class="ac-meta">作者 ／ 年代 ／ 技法・出典</p>
    </figcaption>
  </figure>
  <!-- ×5〜6 -->
</div>
```
```css
.gallery-track {
  display: flex;
  align-items: flex-end;
  gap: 88px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding: 24px 10vw 40px;
}
.artwork { flex: 0 0 auto; scroll-snap-align: center; display: flex; flex-direction: column; gap: 24px; }
.artwork-frame { position: relative; display: inline-flex; height: min(60vh, 560px); overflow: hidden; }
.artwork-frame img { height: 100%; width: auto; max-width: 74vw; }
```

**写真上に文字を載せる時は不透明の帯（半透明グラデーションのスクリムにしない）:**
```css
.artwork-scrim {
  position: absolute; left: 0; right: 0; bottom: 0;
  background: var(--color-ink);   /* 不透明。rgba()の半透明にしない */
  padding: 16px 20px;
  opacity: 0; transform: translateY(10px);
  transition: opacity 0.5s ease, transform 0.5s ease;
}
.artwork:hover .artwork-scrim, .artwork:focus-within .artwork-scrim {
  opacity: 1; transform: translateY(0);
}
.artwork-scrim-title { color: var(--color-bg); font-family: var(--font-latin), serif; font-style: italic; }
/* var(--color-bg) on var(--color-ink) 地 = 15.5:1。写真の上でも常に高コントラストを確保する */
```

**キャプションの視差（少し遅れてついてくる。連続rAFループではなくCSS transitionで実現）:**
```css
.artwork-caption { transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1); }
```
```js
// スクロールのたびに「作品中心 と 表示領域中心 の距離」からズレ量を算出し、
// transform を書き換えるだけ。あとはCSSのtransitionが遅れて追いつく動きを作る。
function updateCaptionDrift() {
  const trackRect = track.getBoundingClientRect();
  const centerX = trackRect.left + trackRect.width / 2;
  artworks.forEach((art, i) => {
    const r = art.getBoundingClientRect();
    const drift = Math.max(-18, Math.min(18, (centerX - (r.left + r.width / 2)) * 0.05));
    captions[i].style.transform = `translateX(${drift.toFixed(1)}px)`;
  });
}
track.addEventListener('scroll', updateCaptionDrift, { passive: true });
```

**ヒーロー初回フェードの起動（`setTimeout`のみ。rAFは使わない）:**
```js
// 唯一の正当な実装。requestAnimationFrame を含む他の起動方法（rAF単発呼び出し、
// rAFループでの監視、rAFによるクラス付与のタイミング調整など）は一切使わない。
window.addEventListener('load', function () {
  setTimeout(function () {
    heroTextInner.classList.add('is-visible');
    heroPhotoWrap.classList.add('is-visible');
  }, 60);
});
```
```css
.hero-text-inner, .hero-photo-wrap {
  opacity: 0; transform: translateY(16px);
  transition: opacity 1.3s ease, transform 1.3s ease;
}
.hero-text-inner.is-visible, .hero-photo-wrap.is-visible {
  opacity: 1; transform: translateY(0);
}
```

**縦書きヒーロー（右から左へ列が並ぶ自然な順序にする）:**
```css
.hero { display: flex; min-height: 100vh; }
.hero-text { width: 33.333%; border-right: 1px solid var(--color-line); }
.hero-text-inner { display: flex; flex-direction: row-reverse; align-items: flex-start; gap: 28px; }
.hero-kanji, .hero-en, .hero-dates, .hero-no { writing-mode: vertical-rl; text-orientation: mixed; }
.hero-photo-wrap { width: 66.666%; }
.hero-photo-wrap img { width: 100%; height: 100%; object-fit: cover; filter: var(--photo-filter); }
```

**節の登場（役割ごとに速さを変える。全要素同じ0.6秒にしない）:**
```css
.eyebrow { transition: opacity 0.8s ease, transform 0.8s ease; }
.section-head h2 { transition: opacity 1.1s ease 0.1s, transform 1.1s ease 0.1s; }
.section-lead { transition: opacity 1s ease 0.2s, transform 1s ease 0.2s; }
.archive-item, .artist-item { transition: opacity 0.7s ease, transform 0.7s ease; } /* リストは短め */
```

- モバイル（768px以下を目安）: ヒーローは縦積みに変える（写真を上、縦書きテキストを下）。
  横スクロール・ギャラリーはネイティブのタッチスワイプに任せ（`overflow-x: auto` の
  ままでよい）、進行インジケータ「01 / 06」を画面下中央に固定表示する
- `prefers-reduced-motion: reduce` では全 transition/animation を `none` にし、
  最終状態で表示する
