Seen as a design The generated document itself — its toggles and disclosures work here
Seen as a design The generated document itself — its toggles and disclosures work here
Copy and paste, or save a file and hand it over. For a machine with no network, one “Everything” file is enough.
Everything in this panel, including the contents behind each URL, in one Markdown file — Large, so it goes as a file (copy is for 32 KB and under)
Build an HTML document with "Business Model Canvas". This layout runs, so there is no composition to rebuild — what it needs is content. ## What this layout does Business Model Canvas with explicit source values and reading conditions. ## What you have to supply - Provide the source values, labels and decision conditions described by the schema. ## The shape of the input - `title` — string — 結論を伝える見出し - `subtitle` — string? — 出典・時点・母集団や仮定 - `partners` — array (0, 1, 2, 3, 4, 5, 6, 7, 8) — 主要パートナー - `activities` — array (0, 1, 2, 3) — 主要活動 - `resources` — array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) — 主要資源 - `valuePropositions` — array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) — 価値提案 - `relationships` — array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) — 顧客関係 - `channels` — array (0, 1, 2, 3) — 提供チャネル - `segments` — array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) — 顧客セグメント - `costs` — array (0, 1, 2, 3, 4, 5, 6) — 費用構造 - `revenues` — array (0, 1, 2, 3, 4) — 収益の流れ schema.ts holds the machine-checkable validation. Ask rather than guess when an input is missing. ## When not to use it - Do not compare values with incompatible units, populations, or assumptions. ## How to build it Put the input in a JSON file and run: ```bash node scripts/render.mjs business-model-canvas <input.json> --theme ink -o out.html ``` The output is one self-contained file and fetches nothing at render time. ## The source - https://design-vault.pages.dev/designs/business-model-canvas/source/template.tsx - https://design-vault.pages.dev/designs/business-model-canvas/source/schema.ts - https://design-vault.pages.dev/designs/business-model-canvas/source/sample-data.json - https://design-vault.pages.dev/designs/business-model-canvas/sample.html
Template, input schema, sample data and metadata. This document was generated from those four. The generated document
/designs/business-model-canvas/source/template.tsx
import type { ReactNode } from "react";
import type { Props } from "./schema";
function Notes({children}:{children:ReactNode}) { return <details><summary>データ・判断条件を確認</summary>{children}</details>; }
const CSS = String.raw`
.asset{font-family:var(--font-sans);color:var(--color-primary);background:var(--color-surface);max-width:var(--container-slide);margin:auto;padding:3rem 2rem;line-height:1.6;font-size:var(--text-body-sm)}
.asset *{box-sizing:border-box}.asset header{margin-bottom:2rem}.asset .eyebrow{font-family:var(--font-mono);font-size:var(--text-label);letter-spacing:.08em;color:var(--color-secondary);margin-bottom:.75rem}.asset h1{font-size:var(--text-h1);font-weight:700;line-height:1.35;letter-spacing:-.025em;max-width:32em}.asset h2{font-size:var(--text-h3);font-weight:600;margin-bottom:.75rem}.asset h3{font-size:var(--text-body-md);font-weight:600}.asset .subtitle,.asset .muted{color:var(--color-secondary)}.asset .subtitle{margin-top:.75rem}.asset .number{font-variant-numeric:tabular-nums;font-family:var(--font-mono)}.asset .hero-number{font-size:var(--text-display);line-height:1.2;font-weight:700;letter-spacing:-.04em}.asset .callout{border-left:.25rem solid var(--color-tertiary);padding:1rem 1.5rem;background:var(--color-surface-subtle);margin-bottom:1.5rem}.asset .grid2{display:grid;grid-template-columns:1fr 1fr;gap:1.5rem}.asset .grid3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1.5rem}.asset .panel{padding:1.5rem;background:var(--color-surface-subtle);border-radius:var(--radius-md);min-width:0}.asset .rule{border-top:1px solid var(--color-outline);padding-top:1rem;margin-top:1rem}.asset .pill{display:inline-block;padding:.25rem .75rem;border:1px solid var(--color-outline);border-radius:var(--radius-full);font-size:var(--text-label)}.asset .focus{background:var(--color-tertiary-container);color:var(--color-on-tertiary-container)}.asset .dark{background:var(--color-primary);color:var(--color-on-primary)}.asset .dark .muted{color:var(--color-on-primary-container)}.asset .row{display:grid;grid-template-columns:12rem minmax(0,1fr) 6rem;gap:1rem;align-items:center;padding:.75rem 0;border-bottom:1px solid var(--color-outline)}.asset .row>*{min-width:0}.asset .track{height:1rem;position:relative;background:var(--color-neutral);border-radius:var(--radius-sm)}.asset .bar{height:100%;background:var(--color-tertiary);border-radius:var(--radius-sm)}.asset .track.tall{height:2rem}.asset .flex{display:flex;gap:1rem;align-items:center;justify-content:space-between;flex-wrap:wrap}.asset .stack>*+*{margin-top:1rem}.asset ul{list-style:disc;padding-left:1.25rem}.asset li+li{margin-top:.5rem}.asset .plot{display:block;width:100%;height:auto;overflow:visible}.asset .plot text{font-family:var(--font-sans);font-size:14px;fill:var(--color-secondary)}.asset .plot .ink{fill:var(--color-primary)}.asset .plot .axis{stroke:var(--color-outline);stroke-width:1}.asset .plot .accent{stroke:var(--color-tertiary);fill:none;stroke-width:3}.asset .legend{display:flex;gap:1.5rem;flex-wrap:wrap;font-size:var(--text-label);margin-bottom:1rem}.asset .legend b{display:inline-block;width:.75rem;height:.75rem;margin-right:.5rem}.asset .ledger{border-collapse:collapse;width:100%;font-variant-numeric:tabular-nums}.asset .ledger caption{text-align:left;font-weight:600;margin:1rem 0}.asset .ledger th{font-weight:600;color:var(--color-secondary);text-align:left}.asset .ledger th,.asset .ledger td{padding:.75rem 1rem;border-bottom:1px solid var(--color-outline);vertical-align:top;overflow-wrap:anywhere}.asset .ledger th:first-child,.asset .ledger td:first-child{padding-left:0}.asset .ledger th:last-child,.asset .ledger td:last-child{padding-right:0}.asset .ledger tbody tr:hover{background:var(--color-surface-subtle)}.asset details{border-top:1px solid var(--color-outline);margin-top:1.5rem;padding-top:1rem}.asset summary{cursor:pointer;color:var(--color-secondary);padding:.5rem 0;min-height:2.75rem}.asset summary:focus-visible{outline:2px solid var(--color-tertiary);outline-offset:.25rem}.asset .small{font-size:var(--text-label)}.asset .mobile-only{display:none}.asset .horizontal-list{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1rem}.asset .board-column{border-top:.25rem solid var(--color-primary);padding-top:1rem;min-width:0}.asset .board-item{padding:1rem 0;border-bottom:1px solid var(--color-outline)}.asset .board-item p{margin-top:.5rem}.asset .statement{font-size:var(--text-h2);line-height:1.5;font-weight:600}.asset .meta-line{margin-top:.75rem;font-size:var(--text-label);color:var(--color-secondary)}.asset pre{white-space:pre-wrap;overflow-wrap:anywhere}.asset footer{margin-top:2rem;font-size:var(--text-label);color:var(--color-secondary)}
@media(max-width:640px){.asset{padding:1.5rem 1rem}.asset h1{font-size:var(--text-h2)}.asset header{margin-bottom:1.5rem}.asset .grid2,.asset .grid3,.asset .horizontal-list{grid-template-columns:1fr}.asset .row{grid-template-columns:minmax(0,1fr) 5rem;gap:.5rem}.asset .row>:first-child{grid-column:1/-1}.asset .desktop-only{display:none!important}.asset .mobile-only{display:block}.asset .panel{padding:1rem}.asset .ledger,.asset .ledger tbody,.asset .ledger tr,.asset .ledger td{display:block}.asset .ledger thead{display:none}.asset .ledger tr{padding:.75rem 0;border-bottom:1px solid var(--color-outline)}.asset .ledger td{display:grid;grid-template-columns:7rem minmax(0,1fr);gap:.75rem;border:0;padding:.25rem 0!important}.asset .ledger td:before{content:attr(data-label);color:var(--color-secondary);font-size:var(--text-label)}.asset .hero-number{font-size:var(--text-h1)}}
@media print{.asset{max-width:none;padding:1rem}.asset details>*{display:block}.asset summary{display:none}}
`;
export default function Template(d: Props) {
const blocks=[{name:"パートナー",items:d.partners},{name:"主要活動",items:d.activities},{name:"主要資源",items:d.resources},{name:"価値提案",items:d.valuePropositions},{name:"顧客関係",items:d.relationships},{name:"チャネル",items:d.channels},{name:"顧客",items:d.segments},{name:"費用構造",items:d.costs},{name:"収益",items:d.revenues}];
return <section className="asset asset-business-model-canvas"><style>{CSS}</style><header><p className="eyebrow">BUSINESS MODEL CANVAS</p><h1>{d.title}</h1>{d.subtitle && <p className="subtitle">{d.subtitle}</p>}</header>
<div className="grid3">{blocks.map((b,i)=><article className={i===3?"panel focus":"panel"} key={b.name}><h2>{b.name}</h2><ul>{b.items.map((s,j)=><li key={j}>{s}</li>)}</ul></article>)}</div><Notes><p>9要素を独立の箇条書きとして埋めるだけでなく、価値提案を支える活動・資源・収益の整合を検証します。</p></Notes>
<footer>各区画は事業仮説。採算の成立は別途、数量と費用で検証する。</footer></section>;
}
/designs/business-model-canvas/source/schema.ts
import { z } from "zod";
const text = z.string().trim().min(1).max(160);
const value = z.number().finite();
const positive = value.positive();
export const schema = z.object({
title: text.describe("結論を伝える見出し"),
subtitle: text.optional().describe("出典・時点・母集団や仮定"),
partners:z.array(text).min(1).max(3).describe("主要パートナー"),activities:z.array(text).min(1).max(3).describe("主要活動"),resources:z.array(text).min(1).max(3).describe("主要資源"),valuePropositions:z.array(text).min(1).max(3).describe("価値提案"),relationships:z.array(text).min(1).max(3).describe("顧客関係"),channels:z.array(text).min(1).max(3).describe("提供チャネル"),segments:z.array(text).min(1).max(3).describe("顧客セグメント"),costs:z.array(text).min(1).max(3).describe("費用構造"),revenues:z.array(text).min(1).max(3).describe("収益の流れ"),
}).strict();
export type Props = z.infer<typeof schema>;
/designs/business-model-canvas/source/meta.yaml
id: business-model-canvas
name:
ja: 事業モデルの9要素
en: Business Model Canvas
purpose:
ja: 顧客・価値・提供体制・収益と費用を9区画に整理し、仮説を共有する。
en: Business Model Canvas with explicit source values and reading conditions.
status: published
still: ./still.png
category: decision
catalogOrder: 510
jobs:
- explain-structure
useCases:
- summary
layoutKinds:
- grid
tags:
- business-model-canvas
- decision
- offline
- responsive
whenToUse:
- ja: 顧客・価値・提供体制・収益と費用を9区画に整理し、仮説を共有する。
en: Use to communicate business model canvas.
avoidWhen:
- ja: 同じ条件・単位で比較できないデータには使わない
en: Do not compare values with incompatible units, populations, or assumptions.
requiredInputs:
- ja: 各区画は事業仮説。採算の成立は別途、数量と費用で検証する。
en: Provide the source values, labels and decision conditions described by the schema.
relatedLayouts:
- swot-evidence
- assumption-evidence
dataSchema:
title: string — 結論を伝える見出し
subtitle: string? — 出典・時点・母集団や仮定
partners: array (0, 1, 2, 3, 4, 5, 6, 7, 8) — 主要パートナー
activities: array (0, 1, 2, 3) — 主要活動
resources: array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) — 主要資源
valuePropositions: array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) — 価値提案
relationships: array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) — 顧客関係
channels: array (0, 1, 2, 3) — 提供チャネル
segments: array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) — 顧客セグメント
costs: array (0, 1, 2, 3, 4, 5, 6) — 費用構造
revenues: array (0, 1, 2, 3, 4) — 収益の流れ
sources: []
/designs/business-model-canvas/source/sample-data.json
{
"title": "導入支援付きの業務SaaSを9要素で検討する",
"subtitle": "架空サンプル|レイアウトの使用例",
"partners": [
"地域の導入支援会社"
],
"activities": [
"設定支援",
"運用改善"
],
"resources": [
"標準業務テンプレート"
],
"valuePropositions": [
"小規模組織でも短期間で導入",
"導入後の運用まで伴走"
],
"relationships": [
"担当者による定例支援"
],
"channels": [
"直接販売",
"紹介パートナー"
],
"segments": [
"専任IT担当が少ない中小企業"
],
"costs": [
"開発・基盤運用",
"導入支援人員"
],
"revenues": [
"月額利用料",
"初期設定支援料"
]
}