/design-system · editorial showcase

Design System

src/editorial/ の semantic token / primitive を type 層から読み直せる showcase。

すべての color / typography / spacing は editorial visual language の contract を通ってレンダリングされます。colors.md が正本、 このページは視覚的な検証用 mirror。

01 — Color

色 / Semantic tokens

bg.* / text.* / border.* と accent.* (surface / interactive / positive / negative / warning / category.*) の token を、それぞれの base / _dark 値を light / dark の canvas に並べます。ページ自体は prefers-color-scheme に従って切り替わります。

  • Canvasbg.canvasPage background
    #ffffff
    #0a0b0e
    #ffffff→ #0a0b0e
  • Surfacebg.surfaceCard surface (default)
    #f8fafc
    #111317
    #f8fafc→ #111317
  • Subtlebg.subtleTinted separator
    #f1f5f9
    #191b21
    #f1f5f9→ #191b21
  • Accent fillbg.accentPrimary CTA idle
    #0369a1
    #0369a1
    #0369a1→ #0369a1
  • Inversebg.inverseInverse panel (static pair)
    #0f172a
    #0f172a
    #0f172a→ #0f172a
  • Defaulttext.defaultBody text
    #0f172a
    #f8fafc
    #0f172a→ #f8fafc
  • Mutedtext.mutedSecondary text
    #475569
    #8b9099
    #475569→ #8b9099
  • Accent texttext.accentInline link
    #0369a1
    #0ea5e9
    #0369a1→ #0ea5e9
  • Inversetext.inverseText on accent fill
    #ffffff
    #ffffff
    #ffffff→ #ffffff
  • Subtleborder.subtleDefault divider
    #f1f5f9
    #191b21
    #f1f5f9→ #191b21
  • Strongborder.strongEmphasis divider
    #64748b
    #6f747d
    #64748b→ #6f747d
  • Focus ringborder.focusFocus outline
    #0284c7
    #7dd3fc
    #0284c7→ #7dd3fc
  • Surfaceaccent.surfaceTinted feature surface
    #f0f9ff
    #151b26
    #f0f9ff→ #151b26
  • Interactiveaccent.interactiveCTA hover / pressed
    #075985
    #075985
    #075985→ #075985
  • Positiveaccent.positiveOK / live status
    #047857
    #6ee7b7
    #047857→ #6ee7b7
  • Negativeaccent.negativeError / unreachable
    #be123c
    #fda4af
    #be123c→ #fda4af
  • Warningaccent.warningDegraded status
    #b45309
    #fcd34d
    #b45309→ #fcd34d
  • Designaccent.category.designContent category — design
    #be185d
    #f9a8d4
    #be185d→ #f9a8d4
  • Codeaccent.category.codeContent category — code
    #0e7490
    #67e8f9
    #0e7490→ #67e8f9
  • Writingaccent.category.writingContent category — writing
    #a16207
    #fde047
    #a16207→ #fde047
  • Toolaccent.category.toolContent category — tool
    #4338ca
    #a5b4fc
    #4338ca→ #a5b4fc
02 — Typography

組版 / Type scale

heading (Zen Kaku Gothic New) / body (Noto Sans JP) / mono (JetBrains Mono) を text.xs〜text.2xl の scale で並べます。

Heading — Zen Kaku Gothic New

Display tier — h1 / h2 / h3

text.xs
静かな編集 / Editorial design
text.sm
静かな編集 / Editorial design
text.md
静かな編集 / Editorial design
text.lg
静かな編集 / Editorial design
text.xl
静かな編集 / Editorial design
text.2xl
静かな編集 / Editorial design
Body — Noto Sans JP

Body / UI default

text.xs
本文 / Body — Noto Sans JP は platform Japanese の正本
text.sm
本文 / Body — Noto Sans JP は platform Japanese の正本
text.md
本文 / Body — Noto Sans JP は platform Japanese の正本
text.lg
本文 / Body — Noto Sans JP は platform Japanese の正本
text.xl
本文 / Body — Noto Sans JP は platform Japanese の正本
text.2xl
本文 / Body — Noto Sans JP は platform Japanese の正本
Mono — JetBrains Mono

Metadata / hex / ordinals

text.xs
mono / hex · 0x1A2B3C · 0.618
text.sm
mono / hex · 0x1A2B3C · 0.618
text.md
mono / hex · 0x1A2B3C · 0.618
text.lg
mono / hex · 0x1A2B3C · 0.618
text.xl
mono / hex · 0x1A2B3C · 0.618
text.2xl
mono / hex · 0x1A2B3C · 0.618
03 — Spacing

余白 / Whitespace scale

editorial の余白は ≈1.618x で段階を刻みます。 小 cluster (4/8) → cluster separator (24) → page-level beat (96/128)。

  • spacing.1 · 4pxdecoration on title, ordinal gap
  • spacing.2 · 8pxtight cluster, sibling gap
  • spacing.4 · 16pxcluster close, body block end
  • spacing.6 · 24pxcluster separator, column gap
  • spacing.10 · 40pxsection block end, list gap
  • spacing.16 · 64pxsection padding
  • spacing.24 · 96pxpage-level beat
  • spacing.32 · 128pxhero entry breath
04 — Surface

面 / Surface treatments

bg.canvas / bg.surface / accent.surface の三段を、既存 primitive で組み立てたカード・タイルで示します。

  • neutral.0Default

    Canvas

    Page background. Outlined so the card reads as a region without leaving the page surface.

    bg.canvas
  • neutral.50Default

    Surface

    Card / panel background. The default tier feature code falls back to when no specific surface is called for.

    bg.surface
  • brand.50Featured

    Accent surface

    Tinted feature surface — Hero / feature card background. Says 'this is the featured region' without competing with the primary CTA.

    accent.surface
05 — Interactive

状態 / Default · Hover · Focus · Pressed

primary / secondary / link / button の四系統で、 default / hover / pressed / focus の状態差を semantic token だけで読みます。

Primary CTA — anchor

<a> filled with bg.accent (idle) → accent.interactive (hover / pressed) → outline 2px border.focus (focus)

Secondary — anchor

<a> on bg.canvas, bordered with border.subtle, text.text.default → border.strong on hover

Secondary
Secondary
Primary CTA — button

<button type=button> same CTA contract as the anchor above, equivalent activation.

Inline link

<a> rendered as text.accent with underline-on-hover. No fill, no border — minimal chrome.

Reaction picker dialog — the shipped picker, mounted without the home consumer API key

06 — Status

識別子 / Status & category accents

positive / negative / warning の status badge、 と design / code / writing / tool の content category を left-border で識別。

Status

Three status accents — positive / negative / warning. Foreground contrast 4.5 : 1 以上 (WCAG AA) を `bg.canvas` の light / dark 両 appearance で満たします。

  • OK / live

    Live

    Running, healthy, available — green.

    accent.positive
  • Error / unreachable

    Error

    Service down, build failed — red.

    accent.negative
  • Degraded

    Degraded

    Partially healthy, needs attention — amber.

    accent.warning
Category

Content category の 4 色。 同程度の彩度 × 異なる hue (pink ≈ 330°, cyan ≈ 190°, yellow ≈ 50°, indigo ≈ 240°) で一目で区別できます。

  • Design

    accent.category.design

    Pink. Portfolio facet が design 起点の作品、 左border で識別。

  • Code

    accent.category.code

    Cyan. Portfolio facet が develop 起点の作品、 実装寄りの surface で識別。

  • Writing

    accent.category.writing

    Yellow-brown. Portfolio facet が other / 散文寄りの作品。

  • Tool

    accent.category.tool

    Indigo. Tool surface の category tag、 portfolio facet が video の作品。

07 — Image

画像 / CLS fixture

Issue #486 の計測面。実運用の PortfolioMediaFigure を固定データで描画し、width/height・loading=lazy・placeholder の枠予約を E2E で実測する(e2e/image-cls.spec.ts、証跡は docs/verification/perf/images-cls-fixture.webp)。

Issue #486 の計測対象。実運用の PortfolioMediaFigure を固定データで描画し、 下の 4 セルが「予約済みの枠」を保つかを E2E で実測する。

eager / 1600×900 / first viewportLCP 相当。寸法が予約されているので読み込み前後で枠の高さが変わらない。
CLS fixture — eager cover (1600×900)
placeholder / url: null配信 URL が無い時の枠。
lazy / 1280×720 / scrolled into viewCLS の被験体。スクロールで読み込みが起き、枠の高さが維持されること(= layout-shift 0)が実測される。
CLS fixture — lazy cover (1280×720)

sentinel — この行の y 座標が読み込み前後で動かないこと

unknown size / width: null寸法未計測の row。予約枠を作れないので distortion せずに unchecked へ退避する。
CLS fixture — unknown intrinsic size
08 — CJK line-break

禁則処理 / Line breaking

ja / zh-Hans / zh-Hant / ko の見出しと本文を 3 段階の opt-in(出荷状態 → lang のみ → lang + CJK タイポグラフィ)で並べます。表示用の検証文言であり、公開コピーの推敲ではありません。幅を狭くして禁則と折り返しの実挙動を確認してください。

mode: default

① Default — 出荷状態(locale 未 opt-in)

`lang` もロケール固有宣言も無い出荷状態です。`src/styles.css` の body ルール(word-break: normal → auto-phrase / text-wrap: pretty)だけが効きます。

日本語

句読点と約物の禁則処理(表示サンプル)

日本語の段落は、句読点(、。「」)・約物(ー・…)が行頭や行末から離れるよう禁則処理されます。折り返し位置と word-break の指定が重なると、狭い画面では分断が悪化することがあります。この段落は表示の検証専用で、文面の推敲は含みません。件数 1,024 件、割合 99.9%、否定表現「〜しない」は原文のまま保持しています。

简体中文

标点符号与避头尾规则(显示样本)

中文段落会按照避头尾规则处理标点(例如「,」「。」「、」),避免它们出现在行首。折行位置与 word-break 的设置叠加时,窄屏上仍可能出现不自然的中断。本段仅用于显示验证,不包含文案润色;数量 1,024 条、比例 99.9%、否定表述「不」均保持原文。

繁體中文

標點符號與避頭尾規則(顯示樣本)

中文段落會按照避頭尾規則處理標點(例如「,」「。」「、」),避免它們出現在行首。折行位置與 word-break 的設定疊加時,窄螢幕上仍可能出現不自然的中斷。本段僅用於顯示驗證,不包含文案潤飾;數量 1,024 筆、比例 99.9%、否定表述「不」均保持原文。

한국어

문장 부호와 줄바꿈 규칙 (표시 샘플)

한국어 단락은 띄어쓰기 단위로 줄이 바뀌므로, 문장 부호가 줄머리에 남지 않는지 확인합니다. 줄바꿈 위치와 word-break 설정이 겹치면 좁은 화면에서 어색하게 끊길 수 있습니다. 이 문단은 표시 검증 전용이며 교정하지 않았습니다. 수량 1,024건, 비율 99.9%, 부정 표현 「아니다」는 원문 그대로 유지합니다.

mode: locale

② LocaleOptIn — `lang` のみ

`lang` だけを付けています。宣言は 1 つも増やさずに UA の行分割規則とフォントフォールバックだけを切り替えられるので、必要な地域でだけ opt-in できます。

日本語

句読点と約物の禁則処理(表示サンプル)

日本語の段落は、句読点(、。「」)・約物(ー・…)が行頭や行末から離れるよう禁則処理されます。折り返し位置と word-break の指定が重なると、狭い画面では分断が悪化することがあります。この段落は表示の検証専用で、文面の推敲は含みません。件数 1,024 件、割合 99.9%、否定表現「〜しない」は原文のまま保持しています。

简体中文

标点符号与避头尾规则(显示样本)

中文段落会按照避头尾规则处理标点(例如「,」「。」「、」),避免它们出现在行首。折行位置与 word-break 的设置叠加时,窄屏上仍可能出现不自然的中断。本段仅用于显示验证,不包含文案润色;数量 1,024 条、比例 99.9%、否定表述「不」均保持原文。

繁體中文

標點符號與避頭尾規則(顯示樣本)

中文段落會按照避頭尾規則處理標點(例如「,」「。」「、」),避免它們出現在行首。折行位置與 word-break 的設定疊加時,窄螢幕上仍可能出現不自然的中斷。本段僅用於顯示驗證,不包含文案潤飾;數量 1,024 筆、比例 99.9%、否定表述「不」均保持原文。

한국어

문장 부호와 줄바꿈 규칙 (표시 샘플)

한국어 단락은 띄어쓰기 단위로 줄이 바뀌므로, 문장 부호가 줄머리에 남지 않는지 확인합니다. 줄바꿈 위치와 word-break 설정이 겹치면 좁은 화면에서 어색하게 끊길 수 있습니다. 이 문단은 표시 검증 전용이며 교정하지 않았습니다. 수량 1,024건, 비율 99.9%, 부정 표현 「아니다」는 원문 그대로 유지합니다.

mode: locale-typography

③ LocaleOptInWithCjkTypography — `lang` + CJK タイポグラフィ(未採用)

`line-break: strict` と `text-spacing-trim: trim-start` を足した比較用。①②との差分を見るための候補であり、製品側ではまだ採用していません(全局 opt-in はこの Issue の受け入れ条件に反します)。

日本語

句読点と約物の禁則処理(表示サンプル)

日本語の段落は、句読点(、。「」)・約物(ー・…)が行頭や行末から離れるよう禁則処理されます。折り返し位置と word-break の指定が重なると、狭い画面では分断が悪化することがあります。この段落は表示の検証専用で、文面の推敲は含みません。件数 1,024 件、割合 99.9%、否定表現「〜しない」は原文のまま保持しています。

简体中文

标点符号与避头尾规则(显示样本)

中文段落会按照避头尾规则处理标点(例如「,」「。」「、」),避免它们出现在行首。折行位置与 word-break 的设置叠加时,窄屏上仍可能出现不自然的中断。本段仅用于显示验证,不包含文案润色;数量 1,024 条、比例 99.9%、否定表述「不」均保持原文。

繁體中文

標點符號與避頭尾規則(顯示樣本)

中文段落會按照避頭尾規則處理標點(例如「,」「。」「、」),避免它們出現在行首。折行位置與 word-break 的設定疊加時,窄螢幕上仍可能出現不自然的中斷。本段僅用於顯示驗證,不包含文案潤飾;數量 1,024 筆、比例 99.9%、否定表述「不」均保持原文。

한국어

문장 부호와 줄바꿈 규칙 (표시 샘플)

한국어 단락은 띄어쓰기 단위로 줄이 바뀌므로, 문장 부호가 줄머리에 남지 않는지 확인합니다. 줄바꿈 위치와 word-break 설정이 겹치면 좁은 화면에서 어색하게 끊길 수 있습니다. 이 문단은 표시 검증 전용이며 교정하지 않았습니다. 수량 1,024건, 비율 99.9%, 부정 표현 「아니다」는 원문 그대로 유지합니다.

09 — table & code

表とコードブロックの読みやすさ

Issue #407 の fixture です。caption と scope 付きヘッダーセルで表構造を伝え、横スクロールはコンポーネント内部に閉じ込め、スクロール領域はキーボードから到達できます。正常 / 空 / 失敗 / 縮小表示の 4 状態をそのまま再現します。

Normal / 01-normal

WCAG 2.2 success criteria — normal state
Success criterionLevelWhat the component provides
1.4.10 ReflowAAThe scroll box is the widest element; the document stays viewport-wide.
1.3.1 Info and RelationshipsAA caption plus scope on the column and row headers of every table.
2.1.1 KeyboardAEach scroll box is focusable, so arrow keys move it.
2.4.6 Headings and LabelsAAThe caption and the code label name their own regions.

Four criteria rows, one row header column, four columns.

Sample markup — normal state

const table = <DataTable
	caption="WCAG 2.2 success criteria"
	columns={columns}
	rows={rows}          // four criteria, one row header column
/>;                    // scroll lives inside the component

Empty / 02-empty

WCAG 2.2 success criteria — empty state
Success criterionLevelWhat the component provides
No rows to show yet.

No rows: the header row and the caption stay, so the structure is still announced.

Sample markup — empty state

const table = <DataTable
	caption="WCAG 2.2 success criteria"
	columns={columns}
	rows={rows}          // four criteria, one row header column
/>;                    // scroll lives inside the component

Failure / 03-failure

WCAG 2.2 success criteria — failure state
Success criterionLevelWhat the component provides
This data could not be loaded.

The read failed: one full-width message row replaces the data rows.

Sample markup — failure state

const table = <DataTable
	caption="WCAG 2.2 success criteria"
	columns={columns}
	rows={rows}          // four criteria, one row header column
/>;                    // scroll lives inside the component

Compact / 04-compact

WCAG 2.2 success criteria — compact state
Success criterionLevelWhat the component provides
1.4.10 ReflowAAThe scroll box is the widest element; the document stays viewport-wide.
1.3.1 Info and RelationshipsAA caption plus scope on the column and row headers of every table.
2.1.1 KeyboardAEach scroll box is focusable, so arrow keys move it.
2.4.6 Headings and LabelsAAThe caption and the code label name their own regions.

Same data at the reduced density used at narrow widths.

Sample markup — compact state

const table = <DataTable
	caption="WCAG 2.2 success criteria"
	columns={columns}
	rows={rows}          // four criteria, one row header column
/>;                    // scroll lives inside the component