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 "Accessibility Audit Findings Register". This layout runs, so there is no composition to rebuild — what it needs is content. ## What this layout does Track reproducible accessibility barriers, evidence, owners, and verification status against success criteria. ## What you have to supply - Record the standard, reproducible finding, evidence, owner, due date, and status. ## The shape of the input - `title` — string — 監査結果の要点 - `subtitle` — string? — 対象リリース・監査日・範囲 - `product` — string — 対象プロダクト - `standard` — string — 適用規格・適合レベル - `findings` — array (3–12) — 指摘(各指摘に達成基準、重大度、課題、証跡1–3件、責任者、期限、状態) schema.ts holds the machine-checkable validation. Ask rather than guess when an input is missing. ## When not to use it - Use a customer journey map to organize research findings and user journeys. ## How to build it Put the input in a JSON file and run: ```bash node scripts/render.mjs accessibility-audit-register <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/accessibility-audit-register/source/template.tsx - https://design-vault.pages.dev/designs/accessibility-audit-register/source/schema.ts - https://design-vault.pages.dev/designs/accessibility-audit-register/source/sample-data.json - https://design-vault.pages.dev/designs/accessibility-audit-register/sample.html
Template, input schema, sample data and metadata. This document was generated from those four. The generated document
/designs/accessibility-audit-register/source/template.tsx
import type { Props } from "./schema";
const CSS = String.raw`
.asset-accessibility-audit-register{font-family:var(--font-sans);color:var(--color-primary);background:var(--color-surface);max-width:var(--container-slide);margin:auto;padding:3rem 2.5rem;line-height:1.55;font-size:var(--text-body-sm)}
.asset-accessibility-audit-register *{box-sizing:border-box}.asset-accessibility-audit-register header{margin-bottom:1.4rem}.asset-accessibility-audit-register .eyebrow{font-family:var(--font-mono);font-size:var(--text-label);color:var(--color-tertiary);margin:0 0 .6rem}.asset-accessibility-audit-register h1{font-size:var(--text-h1);line-height:1.25;max-width:28em;margin:0}.asset-accessibility-audit-register .subtitle{color:var(--color-secondary);margin:.65rem 0 0}.asset-accessibility-audit-register .summary{display:flex;gap:1.5rem;flex-wrap:wrap;padding:.75rem 0;border-block:1px solid var(--color-outline);margin-bottom:1rem}.asset-accessibility-audit-register .summary p{margin:0;color:var(--color-secondary);font-size:var(--text-label)}.asset-accessibility-audit-register .summary strong{font-family:var(--font-mono);font-size:var(--text-h3);color:var(--color-primary);margin-right:.3rem}.asset-accessibility-audit-register .findings{border-top:2px solid var(--color-primary)}.asset-accessibility-audit-register article{padding:.9rem 0;border-bottom:1px solid var(--color-outline)}.asset-accessibility-audit-register .finding-head{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap}.asset-accessibility-audit-register code{font-family:var(--font-mono);font-size:var(--text-label);overflow-wrap:anywhere}.asset-accessibility-audit-register .severity,.asset-accessibility-audit-register .status{font-size:var(--text-label);border:1px solid var(--color-outline);padding:.08rem .4rem}.asset-accessibility-audit-register .finding-head h2{font-size:var(--text-body-md);margin:0;flex:1}.asset-accessibility-audit-register .issue{margin:.45rem 0;color:var(--color-primary);overflow-wrap:anywhere}.asset-accessibility-audit-register .details{display:grid;grid-template-columns:1fr 1fr;gap:.65rem 1.5rem}.asset-accessibility-audit-register .label{display:block;font-size:var(--text-label);color:var(--color-secondary)}.asset-accessibility-audit-register ul{display:flex;gap:.4rem;flex-wrap:wrap;margin:.2rem 0 0;padding:0;list-style:none}.asset-accessibility-audit-register li{font-size:var(--text-label);background:var(--color-surface-subtle);padding:.12rem .4rem;overflow-wrap:anywhere}.asset-accessibility-audit-register .still-svg{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
@media(max-width:680px){.asset-accessibility-audit-register{padding:1.5rem 1rem}.asset-accessibility-audit-register h1{font-size:var(--text-h2)}.asset-accessibility-audit-register .details{grid-template-columns:minmax(0,1fr);gap:.5rem}.asset-accessibility-audit-register .summary{gap:.8rem}}
@media print{.asset-accessibility-audit-register{max-width:none;padding:1rem}.asset-accessibility-audit-register article{break-inside:avoid}}
`;
const severityLabel = { blocker: "遮断", high: "高", medium: "中", low: "低" };
const statusLabel = { open: "未着手", "in-progress": "対応中", verified: "再確認済み", accepted: "例外合意" };
const compact = (value: string, max: number) => [...value].length > max ? `${[...value].slice(0, max - 1).join("")}…` : value;
function Still({ data }: { data: Props }) {
return <svg className="still-svg" data-layout-still="true" width="1280" height="720" viewBox="0 0 1280 720" aria-hidden="true">
<rect width="1280" height="720" fill="var(--color-surface)" />
<text x="48" y="45" fontSize="14" fontFamily="sans-serif" fill="var(--color-secondary)">{data.product} · {data.standard}</text>
<text x="48" y="87" fontSize="27" fontWeight="700" fontFamily="sans-serif" fill="var(--color-on-surface)">{compact(data.title, 62)}</text>
<text x="48" y="123" fontSize="13" fontFamily="sans-serif" fill="var(--color-secondary)">重大度 · 達成基準 · 再現証跡 · 修正責任 · 再確認</text>
{data.findings.slice(0, 9).map((finding, index) => {
const y = 170 + index * 55;
return <g key={finding.id}>
<line x1="48" x2="1232" y1={y - 17} y2={y - 17} stroke="var(--color-outline)" />
<text x="52" y={y + 3} fontSize="11" fontFamily="sans-serif" fill="var(--color-tertiary)">{severityLabel[finding.severity]}</text>
<text x="105" y={y + 3} fontSize="12" fontWeight="700" fontFamily="monospace" fill="var(--color-on-surface)">{finding.id}</text>
<text x="220" y={y + 3} fontSize="12" fontFamily="sans-serif" fill="var(--color-on-surface)">{compact(finding.criteria, 27)}</text>
<text x="450" y={y + 3} fontSize="12" fontFamily="sans-serif" fill="var(--color-on-surface)">{compact(finding.issue, 61)}</text>
<text x="1090" y={y + 3} fontSize="11" fontFamily="sans-serif" fill="var(--color-secondary)">{compact(finding.status, 13)}</text>
</g>;
})}
<text x="48" y="704" fontSize="12" fontFamily="sans-serif" fill="var(--color-secondary)">{data.findings.length}指摘 · 証跡と再確認状態を保持</text>
</svg>;
}
export default function Template(data: Props) {
const counts = Object.fromEntries(Object.keys(severityLabel).map((key) => [key, data.findings.filter((finding) => finding.severity === key).length]));
return <section className="asset asset-accessibility-audit-register">
<style>{CSS}</style>
<header>
<p className="eyebrow">{data.product} · 適合性監査 · {data.standard}</p>
<h1>{data.title}</h1>
{data.subtitle && <p className="subtitle">{data.subtitle}</p>}
</header>
<div className="summary" aria-label="重大度別指摘件数">
<p><strong>{data.findings.length}</strong>指摘</p>
{Object.entries(severityLabel).map(([key, label]) => <p key={key}><strong>{counts[key]}</strong>{label}</p>)}
</div>
<div className="findings">
{data.findings.map((finding) => <article key={finding.id}>
<div className="finding-head"><code>{finding.id}</code><span className="severity">{severityLabel[finding.severity]}</span><h2>{finding.criteria}</h2><span className="status">{statusLabel[finding.status]}</span></div>
<p className="issue">{finding.issue}</p>
<div className="details">
<div><span className="label">再現・確認証跡</span><ul>{finding.evidence.map((item) => <li key={item}>{item}</li>)}</ul></div>
<div><span className="label">修正責任 / 期限</span><p>{finding.owner} · {finding.due}</p></div>
</div>
</article>)}
</div>
<Still data={data} />
</section>;
}
/designs/accessibility-audit-register/source/schema.ts
import { z } from "zod";
const text = z.string().trim().min(1).max(160);
const short = z.string().trim().min(1).max(48);
const findingSchema = z.object({
id: short.describe("指摘を追跡する一意な識別子"),
criteria: short.describe("WCAG達成基準または社内基準"),
severity: z.enum(["blocker", "high", "medium", "low"]).describe("利用者への影響度"),
issue: text.describe("確認された操作上の障壁"),
evidence: z.array(short).min(1).max(3).describe("再現手順・画面・支援技術などの証跡"),
owner: short.describe("修正責任者"),
due: short.describe("修正予定または再確認日"),
status: z.enum(["open", "in-progress", "verified", "accepted"]).describe("修正と再確認の状態"),
}).strict();
export const schema = z.object({
title: text.describe("監査結果の要点"),
subtitle: text.optional().describe("対象リリース・監査日・対象範囲"),
product: short.describe("対象プロダクトまたは画面群"),
standard: short.describe("適用する規格・適合レベル"),
findings: z.array(findingSchema).min(3).max(12).describe("再現可能なアクセシビリティ指摘"),
}).strict().superRefine((data, ctx) => {
const ids = data.findings.map(({ id }) => id);
if (new Set(ids).size !== ids.length) {
ctx.addIssue({ code: "custom", path: ["findings"], message: "指摘IDは一意にすること" });
}
});
export type Props = z.infer<typeof schema>;
/designs/accessibility-audit-register/source/meta.yaml
id: accessibility-audit-register
name:
ja: アクセシビリティ監査指摘台帳
en: Accessibility Audit Findings Register
purpose:
ja: 達成基準に紐づく操作障壁、再現証跡、修正責任、再確認状態を一行ずつ追跡する。
en: Track reproducible accessibility barriers, evidence, owners, and verification status against success criteria.
status: published
still: ./still.png
category: operations
catalogOrder: 830
jobs:
- prioritize-diagnose
- assign-governance
useCases:
- requirements
- status
layoutKinds:
- table
tags:
- accessibility
- wcag
- audit
- remediation
- responsive
whenToUse:
- ja: 実際に再現したアクセシビリティ障壁を、基準・証跡・修正責任・再確認まで一元管理するとき。
en: Use to manage reproducible accessibility barriers from criterion and evidence through remediation and verification.
avoidWhen:
- ja: 利用者調査の発見や旅程を整理する場合は、カスタマージャーニーマップを使う。
en: Use a customer journey map to organize research findings and user journeys.
requiredInputs:
- ja: 適用基準、再現可能な指摘、証跡、修正責任者、期限、状態を記録する。
en: Record the standard, reproducible finding, evidence, owner, due date, and status.
relatedLayouts:
- requirement-traceability-matrix
- change-impact-assessment
dataSchema:
title: string — 監査結果の要点
subtitle: string? — 対象リリース・監査日・範囲
product: string — 対象プロダクト
standard: string — 適用規格・適合レベル
findings: array (3–12) — 指摘(各指摘に達成基準、重大度、課題、証跡1–3件、責任者、期限、状態)
sources: []
/designs/accessibility-audit-register/source/sample-data.json
{
"title": "購入完了までキーボードのみで操作できない箇所を優先修正する",
"subtitle": "Webストア v3.8 · 2026-09-18監査 · 購入とアカウント設定",
"product": "Northstar Web Store",
"standard": "WCAG 2.2 AA",
"findings": [
{ "id": "A11Y-014", "criteria": "2.4.7 Focus Visible", "severity": "high", "issue": "配送方法の選択肢でフォーカスリングが見えず、現在位置を判別できない。", "evidence": ["Chrome 128 / Tab操作", "動画 audit-014.mp4"], "owner": "Checkout UI", "due": "2026-09-25", "status": "in-progress" },
{ "id": "A11Y-019", "criteria": "1.4.3 Contrast", "severity": "medium", "issue": "注文合計の補足ラベルが背景色に対して低コントラスト。", "evidence": ["計測値 3.1:1", "画面 order-review"], "owner": "Design System", "due": "2026-10-02", "status": "open" },
{ "id": "A11Y-023", "criteria": "4.1.2 Name Role Value", "severity": "high", "issue": "数量変更後もライブ通知がなく、スクリーンリーダーに更新が伝わらない。", "evidence": ["VoiceOver / Safari", "再現手順 steps-023.md"], "owner": "Cart Team", "due": "2026-09-29", "status": "open" }
]
}