Back to index

Now Next Later

Three Column
Generates documents
Now Next Later

Seen as a design

Take it with you

Copy and paste, or save a file and hand it over. For a machine with no network, one “Everything” file is enough.

Everything

now-next-later-everything.md

Everything in this panel, including the contents behind each URL, in one Markdown file

Prompt

1.3 KB
Build an HTML document with "Now Next Later". This layout runs, so there is no composition to rebuild — what it needs is content.

## What this layout does
Now Next Later 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? — 出典・時点・母集団や仮定
- `items` — array (id, label, horizon, outcome, exitCriteria, owner) — 施策・時間帯・成果・移行条件・担当

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 now-next-later <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/now-next-later/source/template.tsx
- https://design-vault.pages.dev/designs/now-next-later/source/schema.ts
- https://design-vault.pages.dev/designs/now-next-later/source/sample-data.json
- https://design-vault.pages.dev/designs/now-next-later/sample.html

Files

Template, input schema, sample data and metadata. This document was generated from those four. The generated document

template.tsx

6.7 KB

/designs/now-next-later/source/template.tsx

Show contents
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 groups=[{id:"now",name:"NOW",note:"いま取り組む"},{id:"next",name:"NEXT",note:"次に検証する"},{id:"later",name:"LATER",note:"条件を待つ"}];
return <section className="asset asset-now-next-later"><style>{CSS}</style><header><p className="eyebrow">NOW NEXT LATER</p><h1>{d.title}</h1>{d.subtitle && <p className="subtitle">{d.subtitle}</p>}</header>
<div className="horizontal-list">{groups.map(g=><article key={g.id} className="board-column"><h2>{g.name}</h2><p className="small muted">{g.note}</p>{d.items.filter(r=>r.horizon===g.id).map(r=><div className="board-item" key={r.id}><h3>{r.label}</h3><p>{r.outcome}</p><p className="meta-line">完了・移行条件:{r.exitCriteria}</p><span className="pill">{r.owner}</span></div>)}</article>)}</div><Notes><p>時間帯は確定日程ではありません。条件が整った施策を次の時間帯へ移すための計画です。</p></Notes>
<footer>時間帯と完了条件を明示し、未確定の日付を作らない。</footer></section>;
}

schema.ts

772 B

/designs/now-next-later/source/schema.ts

Show contents
import { z } from "zod";
const text = z.string().trim().min(1).max(160);
const short = z.string().trim().min(1).max(48);
const value = z.number().finite();
const positive = value.positive();
const unique = (values: string[]) => new Set(values).size === values.length;

export const schema = z.object({
  title: text.describe("結論を伝える見出し"),
  subtitle: text.optional().describe("出典・時点・母集団や仮定"),
  items:z.array(z.object({id:short,label:short,horizon:z.enum(["now","next","later"]),outcome:text,exitCriteria:text,owner:short}).strict()).min(3).max(9).describe("施策・時間帯・成果・移行条件・担当"),
}).strict().refine(d=>unique(d.items.map(r=>r.id)),"施策IDは一意");
export type Props = z.infer<typeof schema>;

meta.yaml

1.2 KB

/designs/now-next-later/source/meta.yaml

Show contents
id: now-next-later
name:
  ja: Now・Next・Later計画
  en: Now Next Later
purpose:
  ja: 日付を確約できない施策を、着手順と移行条件で整理する。
  en: Now Next Later with explicit source values and reading conditions.
status: published
still: ./still.png
category: operations
catalogOrder: 520
jobs:
  - plan-sequence
useCases:
  - roadmap
layoutKinds:
  - 3-column
tags:
  - now-next-later
  - operations
  - offline
  - responsive
whenToUse:
  - ja: 日付を確約できない施策を、着手順と移行条件で整理する。
    en: Use to communicate now next later.
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:
  - timeline
  - kanban-wip
dataSchema:
  title: string — 結論を伝える見出し
  subtitle: string? — 出典・時点・母集団や仮定
  items: array (id, label, horizon, outcome, exitCriteria, owner) — 施策・時間帯・成果・移行条件・担当
sources: []

sample-data.json

1010 B

/designs/now-next-later/source/sample-data.json

Show contents
{
  "title": "まず受付改善を完了し、その結果で次段階を決める",
  "subtitle": "架空サンプル|レイアウトの使用例",
  "items": [
    {
      "id": "N1",
      "label": "入力補助",
      "horizon": "now",
      "outcome": "不備入力を減らす",
      "exitCriteria": "試行200件で評価",
      "owner": "業務チーム"
    },
    {
      "id": "N2",
      "label": "通知文面",
      "horizon": "now",
      "outcome": "問合せを減らす",
      "exitCriteria": "顧客確認を完了",
      "owner": "CXチーム"
    },
    {
      "id": "N3",
      "label": "照会統合",
      "horizon": "next",
      "outcome": "対応時間を短縮",
      "exitCriteria": "API疎通を確認",
      "owner": "基盤チーム"
    },
    {
      "id": "N4",
      "label": "承認自動化",
      "horizon": "later",
      "outcome": "審査待ちを減らす",
      "exitCriteria": "例外の分類が完了",
      "owner": "審査チーム"
    }
  ]
}