视觉画布设计
canvas-design
基于设计原则创作静态视觉作品,用于海报与品牌图形。
design-theme-guide【文档与办公】Design-token register: colour, typography, spacing and radius tokens with light and dark values, contrast ratio and WCAG level. Use for design system documentation.
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
What it is: the documented value set a business designs against - colour, type, space, radius, motion - with every colour pair contrast-tested and written down.
Works out the smallest useful theme for the business in front of it, then builds it only when asked. The default output is a short recommendation, not a token file. The token register - CSV, SQL DDL, JSON Schema, Notion mapping - is produced on request, from one field list so the four cannot drift apart.
Layer: Layer 2: Brand & Design. Fits: Starter stage. Table code: n/a.
The rule this table exists to enforce: a theme is a set of values, not a set of
screens. If a colour, size or spacing value is not a row in the register, it is not part of
the system, and anything using it is a one-off. Value alone is the single source; the
light and dark variants and the type metrics exist on the same row because they are the
same token, and a token split across rows drifts within a month.
tokens.jsonDo not use it for: designing the logo itself (that is logo-image-design), choosing a
typeface's licence (logo-image-design covers rights), or a specific component's behaviour.
Follow the shared execution contract. The module-specific rules below define only domain fields, decisions, calculations, and safety constraints.
Read the request and pick the intent before asking anything.
Ask only if this is the highest-value missing fact; otherwise proceed without an opener:
Q: What is the business called, and what does one line of it actually do?
Treat ambiguous replies as unanswered and ask which explicit option the user means. Record unknown values as Unknown; Unknown is not zero. A record must not be Done when a required check fails.
Skip anything the user already answered, in any earlier message. Ask the rest one at a time, and stop as soon as the remaining answers would not change the token set.
Never invent an answer. Hex codes, brand colours, font names and typeface licences the user
has not supplied are Unknown.
module: design-theme-guide
intent: null # set up | fix | review | report | import
scale: null # Starter | Growth | Scale, only if the answer changes it
areas:
"Identity": null
"Surface": null
"Type": null
"Access": null
"Governance": null
requested_outputs: [] # csv | sql | json | notion | xlsx - requested formats only
confirmed_facts: []
open_questions: []
Build an already requested artifact without asking again. For advice-only requests, give a short recommendation and offer the relevant artifact.
Recommended approach: One token register with a brand colour as the single source for accents, a neutral ramp for everything else, one display face and one body face at a fixed type scale, a 4 or 8 point spacing unit, and light and dark variants. Every colour pair that carries text gets a measured ratio and a WCAG level in the row itself, so the accessibility of the theme is auditable rather than remembered.
Why this one: A theme that exists as values is the only thing that makes the website, the deck, the letterhead and the social posts look like one business. Screens cannot do that, and a theme with no contrast measurement is a theme that fails the first time someone chooses a pastel.
Workflow: Seed colour chosen → Neutral ramp derived → Semantic colour roles assigned → Every text pair contrast-measured → Typeface pair set and type scale fixed → Spacing unit and radius set → Light and dark variants recorded → Register approved and versioned → Components built from tokens only
Once the user asks for it, derive the fields from the confirmed context and emit the requested artifacts. For machine-readable text, keep prose outside the data; for files, provide a usable link. Report material validation failures or limitations separately.
A selected Notion output is rendered by notion-manual-import, so route the
Notion step there. When the user selects Notion, hand that step to
@notion-manual-import: it holds the CSV, the property
mapping, the import steps and the verification checklist, and it renders the Field
Reference below instead of defining a table of its own. Do not restate the mapping
here and do not improvise the import steps. Manual CSV and mapping outputs need no
connection. For requested workspace changes, follow the shared contract: verify actual
tool access and the target before writing. A user saying "connected" is not tool evidence.
Never ask for a Notion password or token.
Token ID,Token Name,Token Group,Token Type,Value,Unit,Light Mode Value,Dark Mode Value,Contrast Ratio,Contrast Against,WCAG Level,Font Family,Font Size,Font Weight,Line Height,Letter Spacing,Usage Rule,Do Not Use For,Source Reference,Version,Status,Approved By,Last Reviewed,Notes
TOK-EXAMPLE-001,color.brand.primary,Brand,Color,#1F4FD8,hex,#1F4FD8,#8FB4FF,7.02,color.surface.page,AA,,,,,,Primary action and brand accent,Body text on white surface,WCAG 2.2 SC 1.4.3,1.0,Draft,Unknown,2026-09-27,Example row - replace every value before use.
-- Engine assumption: PostgreSQL. For another engine use `id BIGINT PRIMARY KEY`
-- or the engine's auto-increment equivalent and keep the rest portable.
CREATE TABLE design_token (
token_id BIGINT PRIMARY KEY,
token_name VARCHAR(255) NOT NULL,
token_group VARCHAR(100) NOT NULL,
token_type VARCHAR(100) NOT NULL,
value VARCHAR(255),
unit VARCHAR(50),
light_mode_value VARCHAR(255),
dark_mode_value VARCHAR(255),
contrast_ratio NUMERIC(5,2),
contrast_against VARCHAR(255),
wcag_level VARCHAR(50) NOT NULL,
font_family VARCHAR(255),
font_size VARCHAR(50),
font_weight VARCHAR(50),
line_height VARCHAR(50),
letter_spacing VARCHAR(50),
usage_rule TEXT,
do_not_use_for TEXT,
source_reference VARCHAR(255),
version VARCHAR(50) NOT NULL,
status VARCHAR(50) NOT NULL,
approved_by VARCHAR(255),
last_reviewed DATE,
notes TEXT,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
CONSTRAINT token_ratio_range CHECK (contrast_ratio IS NULL OR (contrast_ratio >= 1 AND contrast_ratio <= 21)),
CONSTRAINT token_wcag_level CHECK (wcag_level IN ('AA','AAA','Fail - do not ship','Not applicable'))
);
CREATE INDEX idx_design_token_status ON design_token (status);
CREATE INDEX idx_design_token_type ON design_token (token_type);
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Design Theme Guide",
"type": "object",
"additionalProperties": false,
"properties": {
"Token ID": { "type": "integer" },
"Token Name": { "type": "string" },
"Token Group": { "type": "string" },
"Token Type": { "type": "string" },
"Value": { "type": "string" },
"Unit": { "type": "string" },
"Light Mode Value": { "type": "string" },
"Dark Mode Value": { "type": "string" },
"Contrast Ratio": { "type": "number" },
"Contrast Against": { "type": "string" },
"WCAG Level": { "type": "string" },
"Font Family": { "type": "string" },
"Font Size": { "type": "string" },
"Font Weight": { "type": "string" },
"Line Height": { "type": "string" },
"Letter Spacing": { "type": "string" },
"Usage Rule": { "type": "string" },
"Do Not Use For": { "type": "string" },
"Source Reference": { "type": "string" },
"Version": { "type": "string" },
"Status": { "type": "string" },
"Approved By": { "type": "string" },
"Last Reviewed": { "type": "string", "format": "date" },
"Notes": { "type": "string" }
},
"required": [
"Token Name",
"Token Group",
"Token Type",
"WCAG Level",
"Version",
"Status"
]
}
| CSV column | Notion property | Set after import |
|---|---|---|
| Token ID | Text (preserve source ID) | Keep imported IDs as Text; optionally add a separate Unique ID property |
| Token Name | Text | Leave as Text. This is the join key - keep it identical everywhere |
| Token Group | Select (add options after import) | Convert to Select, add options: "Brand", "Semantic", "Neutral", "Typography", "Layout", "Component" |
| Token Type | Select (add options after import) | Convert to Select, add options: "Color", "Typography", "Spacing", "Radius", "Shadow", "Border", "Motion", "Breakpoint", "Z-Index" |
| Value | Text | Leave as Text. Hex, px, rem, ms, unitless - it goes in the next column too |
| Unit | Title | Use as the database title |
| Light Mode Value | Text | Leave as Text |
| Dark Mode Value | Text | Leave as Text |
| Contrast Ratio | Number | Convert to Number, 2 decimal places, no unit |
| Contrast Against | Text | Leave as Text. Name the token, not a colour name |
| WCAG Level | Select (add options after import) | Convert to Select, add options: "AA", "AAA", "Fail - do not ship", "Not applicable" |
| Font Family | Text | Leave as Text |
| Font Size | Text | Leave as Text. Keep the unit inside the value, e.g. "16px" |
| Font Weight | Text | Leave as Text. Name the weight, e.g. "Semibold" |
| Line Height | Text | Leave as Text. Unitless multiplier |
| Letter Spacing | Text | Leave as Text |
| Usage Rule | Text | Leave as Text. One sentence. When to use it |
| Do Not Use For | Text | Leave as Text. The misuse list is the most-read column on this table |
| Source Reference | Text | Leave as Text. Link the spec, the checker or the standard clause |
| Version | Text | Leave as Text |
| Status | Select (add options after import) | Convert to Select, add options: "Draft", "In review", "Approved", "Deprecated" |
| Approved By | Text | Leave as Text |
| Last Reviewed | Date | Convert to Date |
| Notes | Text | Leave as Text |
The rows above are documentation examples only. Emit empty templates unless the user explicitly requests examples. Anything measured gets a ratio; anything not
measured is Not applicable, never a guess.
| # | Field | Type | SQL | JSON Schema | Notion | CSV example |
|---|---|---|---|---|---|---|
| 1 | Token ID | id | BIGINT PRIMARY KEY | integer | Text or Notion auto-ID | (blank) |
| 2 | Token Name | text | VARCHAR(255) | string | Text | color.brand.primary |
| 3 | Token Group | select | VARCHAR(100) | string | Select | Brand |
| 4 | Token Type | select | VARCHAR(100) | string | Select | Color |
| 5 | Value | text | VARCHAR(255) | string | Text | #1F4FD8 |
| 6 | Unit | select | VARCHAR(50) | string | Text | hex |
| 7 | Light Mode Value | text | VARCHAR(255) | string | Text | #1F4FD8 |
| 8 | Dark Mode Value | text | VARCHAR(255) | string | Text | #8FB4FF |
| 9 | Contrast Ratio | number | NUMERIC(5,2) | number | Number | 7.02 |
| 10 | Contrast Against | text | VARCHAR(255) | string | Text | color.surface.page |
| 11 | WCAG Level | select | VARCHAR(50) | string | Select | AA |
| 12 | Font Family | text | VARCHAR(255) | string | Text | (blank) |
| 13 | Font Size | text | VARCHAR(50) | string | Text | (blank) |
| 14 | Font Weight | text | VARCHAR(50) | string | Text | (blank) |
| 15 | Line Height | text | VARCHAR(50) | string | Text | (blank) |
| 16 | Letter Spacing | text | VARCHAR(50) | string | Text | (blank) |
| 17 | Usage Rule | long_text | TEXT | string | Text | (blank) |
| 18 | Do Not Use For | long_text | TEXT | string | Text | (blank) |
| 19 | Source Reference | text | VARCHAR(255) | string | Text | (blank) |
| 20 | Version | text | VARCHAR(50) | string | Text | 1.0 |
| 21 | Status | select | VARCHAR(50) | string | Select | Draft |
| 22 | Approved By | text | VARCHAR(255) | string | Text | (blank) |
| 23 | Last Reviewed | date | DATE | string, format: date | Date | (blank) |
| 24 | Notes | long_text | TEXT | string | Text | (blank) |
Token Group
Brand | Semantic | Neutral | Typography | Layout | Component
Token Type
Color | Typography | Spacing | Radius | Shadow | Border | Motion | Breakpoint | Z-Index
Unit
hex | px | rem | em | ms | s | unitless | count
WCAG Level - the four legal values. Fail - do not ship exists so a failing pair is
recorded and visible, not quietly deleted.
AA | AAA | Fail - do not ship | Not applicable
Status
Draft | In review | Approved | Deprecated
None. This table is standalone. Where a colour is measured, Contrast Against names
another token in the same table by Token Name - that is a lookup on a text field, not
a database relation, and it resolves in SQL as a self-join:
SELECT a.token_name, a.value, b.value, a.contrast_ratio
FROM design_token a
JOIN design_token b ON a.contrast_against = b.token_name
WHERE a.token_type = 'Color' AND a.status = 'Approved';
Prompt
We picked a blue from a logo two years ago and nobody knows which one it is. It looks
fine on the laptop but the founder says people struggle on the website.
Context first - one question per message, nothing already answered:
Q: What is the business called, and what does one line of it actually do? A: Example Retail, home and kitchen goods in Example City.
Q: Is the blue fixed by anything - a shop sign, a customer, a printed material? A: It is on the shopfront and on the invoices.
Q: Any existing logo, documents or website colours to match? A: A logo from 2022, and a PDF price list.
Q: Website only, or print and social as well? A: All three.
Q: Who decides a colour change? A: The founder.
Recommended next step - offered, not built:
One token register with that blue as
color.brand.primary, a neutral ramp derived from it, a light and a dark variant, the type scale, a spacing unit, and a measured contrast ratio on every pair that carries text - the blue on white is the pair most likely to fail.Workflow: Seed colour confirmed from the sign → Neutral ramp derived → Semantic roles assigned → Every text pair contrast-measured → Type scale fixed → Spacing unit set → Register approved and versioned
Want the CSV, SQL DDL, JSON Schema and Notion mapping for this?
Source Reference.color.semantic.success is a role; a green
hex used in a footer is a one-off that will fight the next person.Do Not Use For filled in. It is the column that prevents the theme from drifting
back into randomness.relation for anything that points at another table, text only for free text.Unknown until
supplied or measured.Fail - do not ship. The failure is the finding.Status = Deprecated and a new row. Never edit an approved value in
place - bump the version.website-setup (if present) / business-website-setup - where these tokens get built.I want a design theme for my business - brand colours, a type scale, spacing and
light/dark variants, with contrast measured properly.
Ask me one short question at a time, and only about what I have not already told you.
Never invent a hex code, a font or a ratio. Then recommend the smallest token set that
fits, and wait for me to ask before you build it.
When I ask, output CSV, SQL DDL, JSON Schema and a Notion property mapping. Data only.