# REI Cedar デザインシステム

## REI Cedar デザインシステムのインターフェースプレビュー

ネイティブの Cedar タイルを使って、配送または店舗受け取りを選択します。キーボード操作と選択不可のオプションにも対応します。

## REI Cedar デザインシステムのデザインリファレンス

@rei/cdr-tokens 14.0.1 の REI テーマから値を抽出し、ネイティブコンポーネントの動作を @rei/cedar 17.1.0 で確認しています。

### REI テーマのカラーの役割

| 名前 / ルール | 値 / 設定 | 用途 |
| --- | --- | --- |
| cdr-color-background-button-primary-rest | #1f513f | プライマリボタンの背景色。 |
| cdr-color-background-button-primary-hover | #c7dfd1 | プライマリのホバー時の塗り。 |
| cdr-color-background-primary | #ffffff | 標準のコンテンツ面。 |
| cdr-color-background-secondary | #F4F2ED | セカンダリーサーフェス。 |
| cdr-color-text-button-primary | #fafbf9 | プライマリボタンのラベル。 |
| cdr-color-text-primary | #4b4a48 | メインテキストの役割。 |
| cdr-color-text-secondary | #736e65 | 補助テキスト。 |
| cdr-color-text-error | #811823 | エラーメッセージのテキスト。 |
| cdr-color-border-primary | #d5cfc3 | プライマリ面の境界線。 |
| cdr-color-border-secondary | #958e83 | セカンダリの境界線の役割。 |
### ルートサイズ 10px での余白と角丸

| 名前 / ルール | 値 / 設定 | 用途 |
| --- | --- | --- |
| cdr-space-zero | 0 | Cedar のルートでは 1rem は 10px です。これらの値を 16px のルートにそのまま適用しないでください。 |
| cdr-space-sixteenth-x | 0.1rem | Cedar のルートでは 1rem は 10px です。これらの値を 16px のルートにそのまま適用しないでください。 |
| cdr-space-eighth-x | 0.2rem | Cedar のルートでは 1rem は 10px です。これらの値を 16px のルートにそのまま適用しないでください。 |
| cdr-space-three-sixteenth-x | 0.3rem | Cedar のルートでは 1rem は 10px です。これらの値を 16px のルートにそのまま適用しないでください。 |
| cdr-space-quarter-x | 0.4rem | Cedar のルートでは 1rem は 10px です。これらの値を 16px のルートにそのまま適用しないでください。 |
| cdr-space-three-eighth-x | 0.6rem | Cedar のルートでは 1rem は 10px です。これらの値を 16px のルートにそのまま適用しないでください。 |
| cdr-space-half-x | 0.8rem | Cedar のルートでは 1rem は 10px です。これらの値を 16px のルートにそのまま適用しないでください。 |
| cdr-space-three-quarter-x | 1.2rem | Cedar のルートでは 1rem は 10px です。これらの値を 16px のルートにそのまま適用しないでください。 |
| cdr-space-one-x | 1.6rem | Cedar のルートでは 1rem は 10px です。これらの値を 16px のルートにそのまま適用しないでください。 |
| cdr-space-one-and-a-half-x | 2.4rem | Cedar のルートでは 1rem は 10px です。これらの値を 16px のルートにそのまま適用しないでください。 |
| cdr-space-two-x | 3.2rem | Cedar のルートでは 1rem は 10px です。これらの値を 16px のルートにそのまま適用しないでください。 |
| cdr-space-three-x | 4.8rem | Cedar のルートでは 1rem は 10px です。これらの値を 16px のルートにそのまま適用しないでください。 |
| cdr-space-four-x | 6.4rem | Cedar のルートでは 1rem は 10px です。これらの値を 16px のルートにそのまま適用しないでください。 |
| cdr-radius-sharp | 0 | 固定されたトークンパッケージに基づく角の形状。 |
| cdr-radius-soft | 0.2rem | 固定されたトークンパッケージに基づく角の形状。 |
| cdr-radius-softer | 0.4rem | 固定されたトークンパッケージに基づく角の形状。 |
| cdr-radius-softest | 0.6rem | 固定されたトークンパッケージに基づく角の形状。 |
| cdr-radius-round | 999.9rem | 固定されたトークンパッケージに基づく角の形状。 |
### フルフィルメントタイル API

| 名前 / ルール | 値 / 設定 | 用途 |
| --- | --- | --- |
| checked | boolean | 選択された方法を反映します。 |
| disabled | boolean | 選択不可のオプションです。状態を変更できないようにします。 |
| role | radio \| checkbox | フルフィルメント方法を1つ選ぶ場合は radio を使用します。 |
| tabindex | 0 / -1 | タブストップ1つと矢印キーによる移動は、アプリケーション側で管理します。 |
| header slot | method label | 選択肢を示す、読み上げ可能な名前。 |
| body slot | supporting details | 配送予定または受け取り場所。 |
| footer slot | prominent detail | コストまたは提供状況。 |
| icon-right slot | selection indicator | サンプルでは、選択中の方法にチェックマークを追加しています。 |
| loading | boolean | ヘッダーと寸法を維持しながら、本文とフッターをマスクします。 |
## REI Cedar デザインシステム完全ガイド

実際のインターフェースで、このデザインシステムを選び、適用し、レビューするための実践ガイドです。

詳しいガイダンス、実装の出発点、ソースへのリンクをまとめています。

## REI Cedar デザインシステムの Vue ランタイムとスタイルの依存関係

### コンポーネントとトークンのバージョンを揃える

> 動作するサンプルでは、@rei/cedar 17.1.0 と @rei/cdr-tokens 14.0.1、Vue 3 を使用します。コンポーネントパッケージには、モジュール単位のエントリーポイントがあります。この例では、CdrButton と CdrFulfillmentTile、およびそれらが内部で使う面、レイアウト、テキストのコンポーネントに必要なCSSのみをインポートします。JavaScriptの動作だけではスタイル適用まで保証されないため、ソースにはすべてのインポートを記載しています。

### プロプライエタリフォントをサンプルに含めない

Cedar のインストールガイドでは、コンポーネントの使用と REI フォントの利用権が区別されています。このサンプルでは、cdr-fonts.css やフォントフェイスを含む統合スタイルシートをインポートしません。インターフェースのテキストにはシステムの sans-serif を、オリジナルのエディトリアル見出しには Georgia を使用します。これらの代替フォントはアプリケーション側の選択であり、REI のブランド書体ではありません。

## REI Cedar デザインシステムのトークン単位と界面表面の色

### Cedar のルートスケールを使用する

Cedar のトークンでは、16px の余白を 1.6rem と表します。ルートサイズを 10px とすることが前提です。ルートを 16px にすると、同じ値は 25.6px になります。独立したサンプルでは html を 62.5% に設定し、body のサイズを 1.6rem にしています。ルートサイズが異なるホスト製品では、既存サイトにグローバルリセットを貼り付けるのではなく、明確な連携境界を設ける必要があります。

### トークンをコンポーネントの役割に対応付ける

プライマリボタンには、通常時に深い緑の塗り、ホバー時に淡い緑の塗りを使用します。コンテンツ面と境界線には、温かみのあるニュートラルカラーを使います。表には、ドキュメントサイトのテーマではなく、REI テーマのセマンティック値を記載しています。図示したバッグにはオリジナルの装飾色を使っており、公式の Cedar トークンの出力値として示すものではありません。

## REI Cedar デザインシステムのフルフィルメントタイル構成

### タイルごとに変化する選択肢を1つ提示する

フルフィルメントタイルには、方法名、所要時間、コストまたは提供状況をまとめます。別の操作可能なリンクやボタンを含めないでください。サンプルでは、確認アクションを radio グループの外に配置し、選択不可の速達オプションには、常に読み取れる説明を添えています。header、body、footer のスロットによって、情報の階層が明確になります。

### 境界線以外でも選択状態を示す

選択中の方法には checked=true が設定され、icon-right スロットにチェックマークが表示されます。これにより、控えめな境界線の違いがわかりにくい場合でも、現在の選択肢を判別できます。選択可能な項目をクリックすると選択状態のみが更新され、選択内容の確定は別の確認ステップで行います。無効な方法によってモデルが更新されることはありません。

## REI Cedarデザインシステムのプロダクトコンテキストとレスポンシブレイアウト

### 商品を選択肢の隣に配置する

広い画面では、オリジナルのCSSデイパックのイラストと商品概要を、受け取り方法の選択肢の隣に配置します。商品は架空のもので、配送に関する表示はサンプルであることを明記しています。この構成では、REIの商品写真を流用したり、実在する在庫情報を装ったりせずに、Cedarの温かみのある背景レイヤーを表現しています。

### コントロールを縮小せずにレイアウトを組み替える

700px未満では、選択肢をコンパクトな商品概要の後に全幅で配置します。この700pxというしきい値はアプリケーションのレイアウト上の判断であり、Cedarのブレークポイントトークンではありません。タイル内のコンテンツは折り返し可能で、サンプル全体の高さは固定のビューポートではなくコンテンツに応じて変わります。商品イラストは装飾として扱います。

## REI Cedarデザインシステムの選択、キーボード操作、フィードバック

### アプリケーション側でラジオボタンの動作を実装する

タイルはラジオボタンのセマンティクスを提供しますが、グループラベル、選択値、フォーカスの管理はアプリケーション側で行います。選択可能な項目のうち、選択中の項目だけをTabキーの移動対象にします。矢印キーで選択可能な項目を順に移動し、HomeキーとEndキーで先頭または末尾の項目を選択します。利用できない速達配送はスキップされます。アクセシビリティ対応をTODOとして残さず、完全なソースに実装しています。

### 古い確認フィードバックを無効にする

選択内容を確認すると、注文が行われたかのように見せることなく、ローカルなステータスを表示します。選択中のタイルを変更すると、以前の結果はクリアされます。ステータス領域は方法の説明とは分けてあるため、ラジオボタンのアクセシブルネームを変えずに、支援技術からフィードバックを伝えられます。

## REI CedarデザインシステムのVue完全実装

### 同じ画面をネイティブに再現する

ViteのVueプロジェクトを作成して、バージョンを固定したパッケージをインストールし、以下の完全なmain.jsとcedar.cssの例を使用します。ルート要素の名前はrootのままにするか、Viteのテンプレートに合わせてマウント先のセレクターを変更してください。この例ではVueのレンダー関数を使用しているため、読者に明示されていないSFCの前処理はありません。

1. バージョンを固定したコンポーネントパッケージとトークンパッケージをインストールします。

2. main.jsからのCSSインポートをすべて残します。

3. アプリをroot要素にマウントします。

4. 矢印キーで受け取り方法を変更し、ローカルな結果を確認します。

### レイアウトを調べる前にスタイルを確認する

最初に確認するのは、タイルに背景レイヤー、境界線、パディングが適用され、ボタンがCedarのスタイルになっていることです。画面は動作するのに素のテキストのように見える場合は、コンポーネントのCSSとトークンのCSSがインポートされているか確認してください。間隔が大きすぎる場合は、ルートのfont-sizeを調べてください。それぞれ原因が異なるため、対処方法も異なります。

## REI CedarデザインシステムのAIエージェントへの引き継ぎと受け入れ基準

### 連携範囲を明確にする

バージョンを固定したCedarのコンポーネントとトークンパッケージを使用し、独自フォントを使わないVue 3の受け取り方法セレクターをAIエージェントに依頼します。タイルの状態とキーボード操作を正確に指定してください。実際の商品に適用する場合は、架空の所要時間をバックエンドとの契約に置き換え、注文操作を有効にする前に読み込みとエラーを処理してください。

### 動作とソースをあわせて確認する

ローカルでの検証では、矢印キーによる選択、視認できる選択状態、ローカルな確認表示、古い結果のクリア、狭い画面でのレイアウトを確認します。ダウンロードできるガイドには、プレビューと同じアプリケーションコードが含まれています。ネイティブランタイムで検証しても、サンプルの配送予定が実際の情報になるわけではなく、REIのブランドを再利用する許可が得られるわけでもありません。

- 利用できない方法は選択できません。

- 選択を変更すると、以前の確認結果はクリアされます。

- フォントファイルやサービス呼び出しは不要です。

## REI Cedarデザインシステムのコンポーネント例

### main.js — Vueの受け取り方法セレクター完全版

ネイティブコンポーネント、ローカル状態、ロービングラジオフォーカス、必要なスタイルのインポートをすべて含みます。

```
import { createApp, h, ref } from "vue";
import CdrButton from "@rei/cedar/CdrButton";
import CdrFulfillmentTile from "@rei/cedar/CdrFulfillmentTile";
import "@rei/cedar/dist/cdr-reset.css";
import "@rei/cedar/dist/style/cdr-button.css";
import "@rei/cedar/dist/style/cdr-fulfillment-title.css";
import "@rei/cedar/dist/style/cdr-surface-selection.css";
import "@rei/cedar/dist/style/cdr-layout.css";

import "@rei/cdr-tokens/css";
import "@rei/cedar/dist/style/cdr-surface.css";
import "@rei/cedar/dist/style/cdr-body.css";
import "@rei/cedar/dist/style/cdr-subheading-sans.css";
import "./cedar.css";
const choices = [
  {
    id: "ship",
    label: "Ship to home",
    detail: "Sample delivery: 3–5 days",
    price: "No delivery charge",
    available: true,
  },
  {
    id: "pickup",
    label: "Pick up nearby",
    detail: "Sample location: North Trail",
    price: "Ready tomorrow",
    available: true,
  },
  {
    id: "express",
    label: "Express delivery",
    detail: "Unavailable for this sample item",
    price: "Choose another method",
    available: false,
  },
];
createApp({
  setup() {
    const selected = ref("ship"),
      result = ref("");
    function choose(id) {
      selected.value = id;
      result.value = "";
    }
    function keyboard(e, id) {
      if (
        [
          "ArrowRight",
          "ArrowDown",
          "ArrowLeft",
          "ArrowUp",
          "Home",
          "End",
        ].includes(e.key)
      ) {
        e.preventDefault();
        const ids = choices.filter((x) => x.available).map((x) => x.id);
        let next =
          e.key === "Home"
            ? ids[0]
            : e.key === "End"
              ? ids.at(-1)
              : ids[
                  (ids.indexOf(id) +
                    (e.key === "ArrowRight" || e.key === "ArrowDown"
                      ? 1
                      : ids.length - 1)) %
                    ids.length
                ];
        choose(next);
        document.getElementById("choice-" + next).focus();
      }
    }
    return () =>
      h("main", [
        h("header", [
          h("p", { class: "eyebrow" }, "OUTDOOR GEAR / ORIGINAL SPECIMEN"),
          h("h1", "Ready for the next trail"),
          h("p", "Choose a fulfillment method for this fictional daypack."),
        ]),
        h("div", { class: "composition" }, [
          h("section", { class: "product", "aria-label": "Sample product" }, [
            h("div", { class: "art", "aria-hidden": "true" }, [
              h("div", { class: "pack" }, [h("i"), h("span"), h("b")]),
            ]),
            h("div", [
              h("h2", "Ridge daypack · 24 L"),
              h("p", "A lightweight everyday pack for short outings."),
              h(
                "p",
                { class: "note" },
                "Illustrated sample product · no inventory or purchase connection",
              ),
            ]),
          ]),
          h("section", { class: "options" }, [
            h(
              "h2",
              { id: "fulfillment-label" },
              "How would you like to receive it?",
            ),
            h(
              "div",
              {
                class: "tiles",
                role: "radiogroup",
                "aria-labelledby": "fulfillment-label",
              },
              choices.map((c) =>
                h(
                  CdrFulfillmentTile,
                  {
                    id: "choice-" + c.id,
                    role: "radio",
                    tabindex: c.available && selected.value === c.id ? 0 : -1,
                    checked: selected.value === c.id,
                    disabled: !c.available,
                    "aria-label": c.label,
                    onClick: () => c.available && choose(c.id),
                    onKeydown: (e) => keyboard(e, c.id),
                  },
                  {
                    header: () => c.label,
                    "icon-right": () =>
                      selected.value === c.id
                        ? h(
                            "span",
                            {
                              "aria-hidden": "true",
                              style: "font-size:2rem;color:#1f513f",
                            },
                            "✓",
                          )
                        : null,
                    body: () => c.detail,
                    footer: () => c.price,
                  },
                ),
              ),
            ),
            h("div", { class: "review" }, [
              h(
                CdrButton,
                {
                  onClick: () => {
                    result.value = `Local selection: ${choices.find((c) => c.id === selected.value).label}. No order has been placed.`;
                  },
                },
                () => "Review selection",
              ),
              h("p", { role: "status", class: "result" }, result.value),
            ]),
          ]),
        ]),
        h(
          "footer",
          "Native Cedar 17.1.0 fulfillment tiles and button. Original composition with system-font fallback; no REI proprietary fonts or photography.",
        ),
      ]);
  },
}).mount("#root");
```

コードリファレンス

- index.htmlで<div id="root"></div>を使用します。

### cedar.css — オリジナルの商品レイアウト

レスポンシブレイアウト、CSSイラスト、明示的なフォントフォールバック。

```
html {
  font-size: 62.5%;
}
body {
  margin: 0;
  color: #2e2e2b;
  background: #fafbf9;
  font:
    1.6rem/1.5 system-ui,
    sans-serif;
}
* {
  box-sizing: border-box;
}
main {
  padding: 3.2rem;
}
header {
  border-bottom: 1px solid #dcd6cb;
  margin-bottom: 3.2rem;
  padding-bottom: 2.4rem;
}
h1 {
  font:
    700 3.6rem/1.1 Georgia,
    serif;
  margin: 1.2rem 0;
}
h2 {
  font:
    700 2.2rem/1.25 system-ui,
    sans-serif;
  margin: 0 0 1.6rem;
}
p {
  margin: 0.8rem 0;
}
.eyebrow,
footer,
.note {
  font-size: 1.4rem;
  color: #4b4a48;
}
.composition {
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: 4.8rem;
}
.product {
  display: grid;
  gap: 2.4rem;
  align-content: start;
}
.art {
  height: 25rem;
  background: #edeae3;
  border-radius: 0.4rem;
  display: grid;
  place-items: center;
}
.pack {
  position: relative;
  width: 12rem;
  height: 17rem;
  border-radius: 4rem 4rem 2rem 2rem;
  background: #48633c;
  border: 0.6rem solid #34492c;
  box-shadow: 2rem 1rem 0 -1.2rem #b3ad9f;
}
.pack i {
  position: absolute;
  top: -2.2rem;
  left: 3.2rem;
  width: 4.4rem;
  height: 2.4rem;
  border: 0.7rem solid #34492c;
  border-bottom: 0;
  border-radius: 1.4rem 1.4rem 0 0;
}
.pack span {
  position: absolute;
  left: 1.2rem;
  right: 1.2rem;
  bottom: 1.2rem;
  height: 7rem;
  border-radius: 1rem;
  background: #607b52;
  border-top: 0.5rem solid #34492c;
}
.pack b {
  position: absolute;
  left: 4.4rem;
  top: 4rem;
  width: 2rem;
  height: 2rem;
  background: #edeae3;
  border-radius: 50%;
}
.tiles {
  display: grid;
  gap: 1.6rem;
}
.tiles > * {
  font-family: system-ui, sans-serif !important;
}
.review {
  margin-top: 2.4rem;
}
.result {
  color: #355e28;
  font-size: 1.4rem;
  margin-top: 1.6rem;
}
footer {
  margin-top: 3.2rem;
  padding-top: 1.6rem;
  border-top: 1px solid #dcd6cb;
}
:focus-visible {
  outline: 3px solid #406eb5;
  outline-offset: 3px;
}
@media (max-width: 700px) {
  main {
    padding: 2rem;
  }
  .composition {
    grid-template-columns: 1fr;
    gap: 3.2rem;
  }
  .product {
    grid-template-columns: 12rem 1fr;
    gap: 1.6rem;
  }
  .art {
    height: 17rem;
  }
  .pack {
    transform: scale(0.7);
  }
  h1 {
    font-size: 2.8rem;
  }
  .product h2 {
    font-size: 1.8rem;
  }
}
```

コードリファレンス

- REI独自のフォントファイルはインポートしていません。

## REI CedarデザインシステムのAIエージェント設定

### 実装の出発点

プレビューでは、これらのネイティブモジュールをローカルにバンドルしています。フォントにはシステムフォントのフォールバックを使用します。

```
npm create vite@latest cedar-study -- --template vue
cd cedar-study
npm install
npm install @rei/cedar@17.1.0 @rei/cdr-tokens@14.0.1
# Replace src/main.js and add src/cedar.css with the complete examples.
# Change the index.html mount element to id="root".
npm run dev
```

### あなたのプロジェクト向けプロンプト

```
この完全なソースを使用して、Cedar 17.1.0とtokens 14.0.1によるVue 3の受け取り方法セレクターを構築します。10pxのルートスケールを分離し、必要なコンポーネントとトークンのCSSをインポートし、独自フォントを使わず、ロービングラジオフォーカスと無効な選択肢を維持してください。実際の在庫連携の仕様が提供されるまでは、架空の在庫状況を使用してください。
```

## REI Cedarデザインシステムの情報源と対象範囲

OpenDesignに関するREI Cedarガイド。サンプルではCedar 17.1.0とtokens 14.0.1を使用します。商品、イラスト、店舗、配送に関する情報は架空のものです。REI独自のフォントや写真は含まれていません。

- Cedarのインストール Vueのセットアップ、CSS連携、フォントの使用範囲。

- 受け取り方法タイル スロット、状態、アプリケーション側のアクセシビリティ対応の役割。

- トークンリファレンス Webトークンの役割と値。

- Cedarのソース コンポーネントのソースとパッケージのリリース情報。

## REI Cedarデザインシステムの関連リソース

### Sainsbury's デザインシステム

Sainsbury’sの公開デザインガイドラインを、注文枠選択の一連の操作に適用します。実際の配色とサイズの参照、アクセシブルなラジオボタンの選択肢、更新されるサマリー、ページ内で完結する操作の適切なフィードバックを紹介します。

### Salesforce Lightning

詳細なレコードを扱うための Lightning ブループリントガイドです。実際の余白、タイポグラフィ、セマンティックカラー、編集可能なケースワークスペース、フィールド検証、ローカルの変更を反映するアクティビティ履歴を紹介します。

### Samsung One UI

ダーク表示と明示的なリセット時の復旧を備えた、オリジナルの読書設定プレビューを通じて、One UIの閲覧・操作の構成、24dpのマージン指針、テキストを200%に拡大する要件を確認できます。


- [実装リファレンス](https://cedar.rei.com/components/fulfillment-tile)
- [ソース](https://cedar.rei.com/tokens/web)
- [ソース](https://cedar.rei.com/components/fulfillment-tile)
- [コードリファレンス](https://cedar.rei.com/components/fulfillment-tile)
- [コードリファレンス](https://cedar.rei.com/tools-resources/installing-cedar)
- [Cedarのインストール Vueのセットアップ、CSS連携、フォントの使用範囲。](https://cedar.rei.com/tools-resources/installing-cedar)
- [受け取り方法タイル スロット、状態、アプリケーション側のアクセシビリティ対応の役割。](https://cedar.rei.com/components/fulfillment-tile)
- [トークンリファレンス Webトークンの役割と値。](https://cedar.rei.com/tokens/web)
- [Cedarのソース コンポーネントのソースとパッケージのリリース情報。](https://github.com/rei/rei-cedar)
