create-issflow 1.10.1 → 1.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +37 -12
- package/package.json +1 -1
- package/template/.issflow/README.md +4 -1
- package/template/.issflow/agents/planner.md +6 -1
- package/template/.issflow/agents/synthesizer.md +6 -4
- package/template/.issflow/commands/change-request.md +10 -2
- package/template/.issflow/commands/design.md +35 -20
- package/template/.issflow/commands/feature.md +6 -1
- package/template/.issflow/commands/overview.md +46 -7
- package/template/.issflow/commands/phase.md +50 -13
- package/template/.issflow/commands/propose.md +25 -7
- package/template/.issflow/commands/quick.md +2 -0
- package/template/.issflow/flow-config.json +11 -4
- package/template/.issflow/hooks/session-start.js +64 -128
- package/template/.issflow/istartsoft-flow/METHODOLOGY.md +57 -17
- package/template/.issflow/models/MODEL-MATRIX.md +33 -0
- package/template/.issflow/routing/model-router.js +66 -0
- package/template/.issflow/routing/policy.json +69 -0
- package/template/.issflow/scripts/entry-notice.js +20 -0
- package/template/.issflow/scripts/token-lint.js +58 -0
- package/template/.issflow/skills/ui-ux-pro-max/SKILL.md +7 -2
- package/template/.issflow/skills/ux-design/SKILL.md +3 -0
- package/template/.issflow/templates/ARCHITECTURE-template.md +7 -3
- package/template/.issflow/templates/PLAN-SCOPED.md +12 -0
- package/template/.issflow/templates/UX-PACK-template.md +19 -8
- package/template/.issflow/templates/design/DIRECTION.md +22 -0
- package/template/.issflow/templates/design/inventory.md +18 -0
- package/template/.issflow/templates/design/picker.html +165 -0
- package/template/.issflow/templates/design/platforms/line-oa.md +16 -0
- package/template/.issflow/templates/design/platforms/mobile-app.md +10 -0
- package/template/.issflow/templates/design/platforms/pwa.md +11 -0
- package/template/.issflow/templates/design/platforms/web-responsive.md +9 -0
- package/template/.issflow/templates/design/screens/SCREEN.md +19 -0
- package/template/.issflow/templates/design/tokens.css +47 -0
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
> Revision: 1
|
|
4
4
|
> Status: PENDING
|
|
5
|
+
> Size: S | M | L
|
|
6
|
+
> Lane: Fast | Standard | Heavy
|
|
7
|
+
> Platform: web | pwa | line | mobile | n/a
|
|
5
8
|
|
|
6
9
|
## Goal
|
|
7
10
|
Describe the desired outcome.
|
|
@@ -20,6 +23,12 @@ List the paths that the owner will approve in the approval record.
|
|
|
20
23
|
|
|
21
24
|
## Acceptance criteria
|
|
22
25
|
- [ ] Observable behavior with test evidence.
|
|
26
|
+
- [ ] (UI) Primary user can complete the task without guessing — task check
|
|
27
|
+
|
|
28
|
+
## Delivery (ETA)
|
|
29
|
+
- agent_eta:
|
|
30
|
+
- waiting_on: none | owner | client | vendor | other
|
|
31
|
+
- waiting_since:
|
|
23
32
|
|
|
24
33
|
## Tests
|
|
25
34
|
- Unit:
|
|
@@ -34,3 +43,6 @@ List the paths that the owner will approve in the approval record.
|
|
|
34
43
|
Do not change source until the owner approves this exact plan revision.
|
|
35
44
|
The approval record must bind the ID, revision, and Git blob hash.
|
|
36
45
|
Merge and deployment require separate authorization.
|
|
46
|
+
|
|
47
|
+
Plan-Ready required before approve (testable AC · no TBD on auth/money/PII ·
|
|
48
|
+
direction locked if UI · size+lane set).
|
|
@@ -5,7 +5,18 @@
|
|
|
5
5
|
|
|
6
6
|
## Purpose
|
|
7
7
|
Hi-fi-enough UI direction for build: screens, flows, and frame the implementer
|
|
8
|
-
must stay inside. Wireframe baseline first; visual direction
|
|
8
|
+
must stay inside. Wireframe baseline first; visual direction from locked picker.
|
|
9
|
+
|
|
10
|
+
## Design scale
|
|
11
|
+
Spike | Bounded | Architectural:
|
|
12
|
+
|
|
13
|
+
## Surfaces
|
|
14
|
+
- web-responsive (default) · pwa · line-oa · mobile-app:
|
|
15
|
+
|
|
16
|
+
## Direction lock
|
|
17
|
+
- `docs/design/DIRECTION.md` id:
|
|
18
|
+
- Tokens: `docs/design/tokens.css`
|
|
19
|
+
- Inventory: `docs/design/inventory.md`
|
|
9
20
|
|
|
10
21
|
## Users & jobs
|
|
11
22
|
-
|
|
@@ -15,19 +26,19 @@ must stay inside. Wireframe baseline first; visual direction confirmed here.
|
|
|
15
26
|
2.
|
|
16
27
|
|
|
17
28
|
## Screen inventory
|
|
18
|
-
| Screen | Job | Priority |
|
|
19
|
-
|
|
20
|
-
| | | |
|
|
29
|
+
| Id | Screen | Job | Priority | Empty/Loading/Error |
|
|
30
|
+
|----|--------|-----|----------|---------------------|
|
|
31
|
+
| S-01 | | | | |
|
|
21
32
|
|
|
22
33
|
## Frame & tokens
|
|
23
|
-
- Wireframe baseline:
|
|
24
|
-
- Brand / tokens: (
|
|
25
|
-
-
|
|
26
|
-
- Breakpoints: XS · SM · MD · LG · XL
|
|
34
|
+
- Wireframe baseline: `.issflow/skills/ux-design/references/wireframe-template.md`
|
|
35
|
+
- Brand / tokens: locked file above (do not re-roll catalogue)
|
|
36
|
+
- Breakpoints: XS · SM · MD · LG · XL — declare <SM and ≥MD behavior per primary screen
|
|
27
37
|
|
|
28
38
|
## States & a11y notes
|
|
29
39
|
- Empty / loading / error covered for each primary view
|
|
30
40
|
- WCAG 2.1 AA targets
|
|
41
|
+
- No emoji as UI icons
|
|
31
42
|
|
|
32
43
|
## Out of scope (design)
|
|
33
44
|
-
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Design direction — <project>
|
|
2
|
+
|
|
3
|
+
> Status: PENDING | locked <id> <YYYY-MM-DD>
|
|
4
|
+
|
|
5
|
+
## Chosen direction
|
|
6
|
+
- Id: (A|B|C or catalogue slug)
|
|
7
|
+
- Name:
|
|
8
|
+
- Mood / one-liner:
|
|
9
|
+
- Surfaces: web-responsive (default) · …
|
|
10
|
+
|
|
11
|
+
## Tokens source
|
|
12
|
+
- `docs/design/tokens.css`
|
|
13
|
+
|
|
14
|
+
## Primary user tasks
|
|
15
|
+
1.
|
|
16
|
+
2.
|
|
17
|
+
|
|
18
|
+
## Anti-patterns (do not ship)
|
|
19
|
+
-
|
|
20
|
+
|
|
21
|
+
## Notes
|
|
22
|
+
-
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Component inventory — <project>
|
|
2
|
+
|
|
3
|
+
> Only listed components may be used in UI. New need → add here first (STOP if inventing mid-page).
|
|
4
|
+
|
|
5
|
+
| Component | Variants | States required |
|
|
6
|
+
|-----------|----------|-----------------|
|
|
7
|
+
| Button | primary, ghost | default hover focus disabled loading |
|
|
8
|
+
| Text field | default | default focus error disabled |
|
|
9
|
+
| Nav (top) | desktop, collapsed | default |
|
|
10
|
+
| Card | default | default |
|
|
11
|
+
| Empty state | — | empty + CTA |
|
|
12
|
+
| Alert | info, danger, success | default |
|
|
13
|
+
|
|
14
|
+
## Icon set
|
|
15
|
+
- One SVG set, `currentColor`. No emoji as UI icons.
|
|
16
|
+
|
|
17
|
+
## Notes
|
|
18
|
+
-
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<title>Design direction picker — {{PROJECT}}</title>
|
|
7
|
+
<style>
|
|
8
|
+
/* Fixed chrome — agents only replace CSS variables + text slots below. */
|
|
9
|
+
:root {
|
|
10
|
+
--bg: {{P1_BG}};
|
|
11
|
+
--surface: {{P1_SURFACE}};
|
|
12
|
+
--text: {{P1_TEXT}};
|
|
13
|
+
--muted: {{P1_MUTED}};
|
|
14
|
+
--accent: {{P1_ACCENT}};
|
|
15
|
+
--border: {{P1_BORDER}};
|
|
16
|
+
--radius: {{P1_RADIUS}};
|
|
17
|
+
--font: {{P1_FONT}};
|
|
18
|
+
--bg2: {{P2_BG}};
|
|
19
|
+
--surface2: {{P2_SURFACE}};
|
|
20
|
+
--text2: {{P2_TEXT}};
|
|
21
|
+
--muted2: {{P2_MUTED}};
|
|
22
|
+
--accent2: {{P2_ACCENT}};
|
|
23
|
+
--border2: {{P2_BORDER}};
|
|
24
|
+
--radius2: {{P2_RADIUS}};
|
|
25
|
+
--font2: {{P2_FONT}};
|
|
26
|
+
--bg3: {{P3_BG}};
|
|
27
|
+
--surface3: {{P3_SURFACE}};
|
|
28
|
+
--text3: {{P3_TEXT}};
|
|
29
|
+
--muted3: {{P3_MUTED}};
|
|
30
|
+
--accent3: {{P3_ACCENT}};
|
|
31
|
+
--border3: {{P3_BORDER}};
|
|
32
|
+
--radius3: {{P3_RADIUS}};
|
|
33
|
+
--font3: {{P3_FONT}};
|
|
34
|
+
}
|
|
35
|
+
* { box-sizing: border-box; }
|
|
36
|
+
body { margin: 0; font-family: system-ui, sans-serif; background: #f3f1ec; color: #1c1917; }
|
|
37
|
+
header { padding: 28px 24px 8px; max-width: 1100px; margin: 0 auto; }
|
|
38
|
+
header h1 { margin: 0 0 8px; font-size: 1.6rem; }
|
|
39
|
+
header p { margin: 0; color: #57534e; max-width: 52ch; }
|
|
40
|
+
.grid { display: grid; gap: 18px; padding: 20px 24px 40px; max-width: 1100px; margin: 0 auto;
|
|
41
|
+
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
|
|
42
|
+
.card { border: 1px solid #d6d3d1; border-radius: 12px; overflow: hidden; background: #fff;
|
|
43
|
+
box-shadow: 0 8px 24px rgba(28,25,23,.06); }
|
|
44
|
+
.card h2 { margin: 0; padding: 14px 16px 6px; font-size: 1.05rem; }
|
|
45
|
+
.meta { padding: 0 16px 12px; font-size: .85rem; color: #78716c; }
|
|
46
|
+
.swatches { display: flex; gap: 6px; padding: 0 16px 12px; }
|
|
47
|
+
.swatches i { width: 28px; height: 28px; border-radius: 999px; border: 1px solid rgba(0,0,0,.12); display: block; }
|
|
48
|
+
.preview { margin: 0 16px 16px; border: 1px solid var(--c-border); border-radius: 10px; overflow: hidden;
|
|
49
|
+
background: var(--c-bg); color: var(--c-text); font-family: var(--c-font); }
|
|
50
|
+
.preview.wide { --c-bg: var(--bg); --c-surface: var(--surface); --c-text: var(--text); --c-muted: var(--muted);
|
|
51
|
+
--c-accent: var(--accent); --c-border: var(--border); --c-radius: var(--radius); --c-font: var(--font); }
|
|
52
|
+
.d2 .preview.wide { --c-bg: var(--bg2); --c-surface: var(--surface2); --c-text: var(--text2); --c-muted: var(--muted2);
|
|
53
|
+
--c-accent: var(--accent2); --c-border: var(--border2); --c-radius: var(--radius2); --c-font: var(--font2); }
|
|
54
|
+
.d3 .preview.wide { --c-bg: var(--bg3); --c-surface: var(--surface3); --c-text: var(--text3); --c-muted: var(--muted3);
|
|
55
|
+
--c-accent: var(--accent3); --c-border: var(--border3); --c-radius: var(--radius3); --c-font: var(--font3); }
|
|
56
|
+
.top { display: flex; gap: 12px; align-items: center; padding: 10px 12px; background: var(--c-surface);
|
|
57
|
+
border-bottom: 1px solid var(--c-border); font-size: .8rem; font-weight: 700; }
|
|
58
|
+
.top .brand { color: var(--c-accent); }
|
|
59
|
+
.top .spacer { flex: 1; }
|
|
60
|
+
.body { padding: 14px 12px; background: var(--c-bg); }
|
|
61
|
+
.body h3 { margin: 0 0 6px; font-size: .95rem; }
|
|
62
|
+
.body p { margin: 0 0 12px; font-size: .8rem; color: var(--c-muted); }
|
|
63
|
+
.row { display: flex; gap: 8px; flex-wrap: wrap; }
|
|
64
|
+
.btn { border: 0; border-radius: var(--c-radius); padding: 8px 12px; font: inherit; font-size: .8rem; font-weight: 700; cursor: default; }
|
|
65
|
+
.btn.primary { background: var(--c-accent); color: #fff; }
|
|
66
|
+
.btn.ghost { background: transparent; color: var(--c-text); border: 1px solid var(--c-border); }
|
|
67
|
+
.field { flex: 1; min-width: 120px; border: 1px solid var(--c-border); border-radius: var(--c-radius);
|
|
68
|
+
padding: 8px 10px; background: var(--c-surface); color: var(--c-muted); font-size: .8rem; }
|
|
69
|
+
.narrow-wrap { padding: 0 16px 16px; }
|
|
70
|
+
.narrow { width: 160px; margin: 0 auto; border: 1px solid var(--c-border); border-radius: 18px; overflow: hidden;
|
|
71
|
+
background: var(--c-bg); color: var(--c-text); font-family: var(--c-font); transform: scale(1); }
|
|
72
|
+
.narrow .top { font-size: .7rem; padding: 8px; }
|
|
73
|
+
.narrow .body { padding: 10px 8px; }
|
|
74
|
+
.narrow .btn, .narrow .field { font-size: .7rem; padding: 6px 8px; }
|
|
75
|
+
.anti { padding: 0 16px 16px; font-size: .8rem; color: #9a3412; }
|
|
76
|
+
.pick { display: block; margin: 0 16px 16px; text-align: center; padding: 10px; border-radius: 8px;
|
|
77
|
+
background: #1c1917; color: #fff; font-weight: 700; font-size: .85rem; text-decoration: none; }
|
|
78
|
+
footer { max-width: 1100px; margin: 0 auto; padding: 0 24px 40px; color: #78716c; font-size: .85rem; }
|
|
79
|
+
</style>
|
|
80
|
+
</head>
|
|
81
|
+
<body>
|
|
82
|
+
<header>
|
|
83
|
+
<h1>{{PROJECT}} — pick a visual direction</h1>
|
|
84
|
+
<p>Open this file in a browser. Choose A, B, or C. Then lock tokens into <code>docs/design/DIRECTION.md</code> + <code>docs/design/tokens.css</code>. Do not re-roll styles after lock.</p>
|
|
85
|
+
</header>
|
|
86
|
+
<div class="grid">
|
|
87
|
+
<article class="card d1">
|
|
88
|
+
<h2>A · {{P1_NAME}}</h2>
|
|
89
|
+
<div class="meta">{{P1_BLURB}}</div>
|
|
90
|
+
<div class="swatches">
|
|
91
|
+
<i style="background:{{P1_BG}}"></i>
|
|
92
|
+
<i style="background:{{P1_SURFACE}}"></i>
|
|
93
|
+
<i style="background:{{P1_ACCENT}}"></i>
|
|
94
|
+
<i style="background:{{P1_TEXT}}"></i>
|
|
95
|
+
</div>
|
|
96
|
+
<div class="preview wide">
|
|
97
|
+
<div class="top"><span class="brand">Brand</span><span>Home</span><span>Work</span><span class="spacer"></span><span>Account</span></div>
|
|
98
|
+
<div class="body">
|
|
99
|
+
<h3>Primary task</h3>
|
|
100
|
+
<p>Short supporting line for this direction.</p>
|
|
101
|
+
<div class="row"><span class="field">Email</span><button class="btn primary" type="button">Continue</button><button class="btn ghost" type="button">Cancel</button></div>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
<div class="narrow-wrap"><div class="narrow">
|
|
105
|
+
<div class="top"><span class="brand">Brand</span><span class="spacer"></span>☰</div>
|
|
106
|
+
<div class="body"><h3>Mobile</h3><p>Single column</p><button class="btn primary" type="button">Continue</button></div>
|
|
107
|
+
</div></div>
|
|
108
|
+
<div class="anti">Avoid: {{P1_ANTI}}</div>
|
|
109
|
+
<a class="pick" href="#lock-a">Lock direction A</a>
|
|
110
|
+
</article>
|
|
111
|
+
<article class="card d2">
|
|
112
|
+
<h2>B · {{P2_NAME}}</h2>
|
|
113
|
+
<div class="meta">{{P2_BLURB}}</div>
|
|
114
|
+
<div class="swatches">
|
|
115
|
+
<i style="background:{{P2_BG}}"></i>
|
|
116
|
+
<i style="background:{{P2_SURFACE}}"></i>
|
|
117
|
+
<i style="background:{{P2_ACCENT}}"></i>
|
|
118
|
+
<i style="background:{{P2_TEXT}}"></i>
|
|
119
|
+
</div>
|
|
120
|
+
<div class="preview wide">
|
|
121
|
+
<div class="top"><span class="brand">Brand</span><span>Home</span><span>Work</span><span class="spacer"></span><span>Account</span></div>
|
|
122
|
+
<div class="body">
|
|
123
|
+
<h3>Primary task</h3>
|
|
124
|
+
<p>Short supporting line for this direction.</p>
|
|
125
|
+
<div class="row"><span class="field">Email</span><button class="btn primary" type="button">Continue</button><button class="btn ghost" type="button">Cancel</button></div>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
<div class="narrow-wrap"><div class="narrow">
|
|
129
|
+
<div class="top"><span class="brand">Brand</span><span class="spacer"></span>☰</div>
|
|
130
|
+
<div class="body"><h3>Mobile</h3><p>Single column</p><button class="btn primary" type="button">Continue</button></div>
|
|
131
|
+
</div></div>
|
|
132
|
+
<div class="anti">Avoid: {{P2_ANTI}}</div>
|
|
133
|
+
<a class="pick" href="#lock-b">Lock direction B</a>
|
|
134
|
+
</article>
|
|
135
|
+
<article class="card d3">
|
|
136
|
+
<h2>C · {{P3_NAME}}</h2>
|
|
137
|
+
<div class="meta">{{P3_BLURB}}</div>
|
|
138
|
+
<div class="swatches">
|
|
139
|
+
<i style="background:{{P3_BG}}"></i>
|
|
140
|
+
<i style="background:{{P3_SURFACE}}"></i>
|
|
141
|
+
<i style="background:{{P3_ACCENT}}"></i>
|
|
142
|
+
<i style="background:{{P3_TEXT}}"></i>
|
|
143
|
+
</div>
|
|
144
|
+
<div class="preview wide">
|
|
145
|
+
<div class="top"><span class="brand">Brand</span><span>Home</span><span>Work</span><span class="spacer"></span><span>Account</span></div>
|
|
146
|
+
<div class="body">
|
|
147
|
+
<h3>Primary task</h3>
|
|
148
|
+
<p>Short supporting line for this direction.</p>
|
|
149
|
+
<div class="row"><span class="field">Email</span><button class="btn primary" type="button">Continue</button><button class="btn ghost" type="button">Cancel</button></div>
|
|
150
|
+
</div>
|
|
151
|
+
</div>
|
|
152
|
+
<div class="narrow-wrap"><div class="narrow">
|
|
153
|
+
<div class="top"><span class="brand">Brand</span><span class="spacer"></span>☰</div>
|
|
154
|
+
<div class="body"><h3>Mobile</h3><p>Single column</p><button class="btn primary" type="button">Continue</button></div>
|
|
155
|
+
</div></div>
|
|
156
|
+
<div class="anti">Avoid: {{P3_ANTI}}</div>
|
|
157
|
+
<a class="pick" href="#lock-c">Lock direction C</a>
|
|
158
|
+
</article>
|
|
159
|
+
</div>
|
|
160
|
+
<footer>
|
|
161
|
+
Fallback presets (no Python): A Calm SaaS · B Bold Commerce · C Trust Fintech.
|
|
162
|
+
After lock, set STATE <code>design-direction: locked <id> <date></code>.
|
|
163
|
+
</footer>
|
|
164
|
+
</body>
|
|
165
|
+
</html>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Platform pack — LINE OA
|
|
2
|
+
|
|
3
|
+
## Not web CSS
|
|
4
|
+
Design in Messaging API terms. Prototype Flex in Flex Message Simulator; verify on device.
|
|
5
|
+
|
|
6
|
+
## Inventory
|
|
7
|
+
| Piece | Notes |
|
|
8
|
+
|-------|-------|
|
|
9
|
+
| Rich menu | Image + tap bounds map |
|
|
10
|
+
| Message types | text / flex / imagemap / … |
|
|
11
|
+
| Flex bubbles | header/hero/body/footer; wrap long text |
|
|
12
|
+
| LIFF | for forms needing web UI |
|
|
13
|
+
| Reply vs push | quota / UX expectations |
|
|
14
|
+
|
|
15
|
+
## Auth
|
|
16
|
+
LINE userId linking to app user — record in ARCHITECTURE auth section.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Platform pack — mobile app
|
|
2
|
+
|
|
3
|
+
## Conventions
|
|
4
|
+
- Platform nav (tabs / stack) — do not paste web top-bar blindly
|
|
5
|
+
- Touch targets ≥ 44×44
|
|
6
|
+
- System type / spacing where OS expects it
|
|
7
|
+
- Safe areas / notches
|
|
8
|
+
|
|
9
|
+
## Screens
|
|
10
|
+
List screen IDs + primary gestures (tap / swipe / long-press) per flow.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Platform pack — PWA
|
|
2
|
+
|
|
3
|
+
## Beyond web-responsive
|
|
4
|
+
- Install / add-to-home-screen affordance
|
|
5
|
+
- Offline shell + update UX
|
|
6
|
+
- Safe-area insets
|
|
7
|
+
- Manifest icons + theme-color
|
|
8
|
+
- Service worker update prompt (no silent break)
|
|
9
|
+
|
|
10
|
+
## Out of scope unless listed
|
|
11
|
+
-
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Platform pack — web-responsive
|
|
2
|
+
|
|
3
|
+
## Constraints
|
|
4
|
+
- Mobile-first; breakpoints XS <640 · SM 640 · MD 768 · LG 1024 · XL 1280
|
|
5
|
+
- Tokens only from `docs/design/tokens.css`
|
|
6
|
+
- Wireframe baseline regions required
|
|
7
|
+
|
|
8
|
+
## Must show per primary screen
|
|
9
|
+
Route · primary CTA · empty · loading · error · <SM stack · ≥MD layout
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Screen: S-XX — <name>
|
|
2
|
+
|
|
3
|
+
- Id: S-XX
|
|
4
|
+
- Route: /
|
|
5
|
+
- Surface: web-responsive
|
|
6
|
+
- Primary job:
|
|
7
|
+
- Primary CTA:
|
|
8
|
+
- Breakpoints: <SM single column · ≥MD as wireframe
|
|
9
|
+
- Empty:
|
|
10
|
+
- Loading:
|
|
11
|
+
- Error:
|
|
12
|
+
|
|
13
|
+
## Regions (map to wireframe baseline)
|
|
14
|
+
- Top bar:
|
|
15
|
+
- Main:
|
|
16
|
+
- Footer / status:
|
|
17
|
+
|
|
18
|
+
## Tokens
|
|
19
|
+
- Uses `docs/design/tokens.css` only
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/* Semantic tokens — only file allowed to hold raw color/size literals for UI.
|
|
2
|
+
Components must use these variables. Generated/locked from Direction Picker. */
|
|
3
|
+
:root {
|
|
4
|
+
--color-bg: #f7f5f0;
|
|
5
|
+
--color-surface: #ffffff;
|
|
6
|
+
--color-text: #1c1917;
|
|
7
|
+
--color-text-muted: #78716c;
|
|
8
|
+
--color-border: #d6d3d1;
|
|
9
|
+
--color-accent: #0f766e;
|
|
10
|
+
--color-accent-contrast: #ffffff;
|
|
11
|
+
--color-danger: #b91c1c;
|
|
12
|
+
--color-success: #15803d;
|
|
13
|
+
--color-warning: #a16207;
|
|
14
|
+
|
|
15
|
+
--space-1: 4px;
|
|
16
|
+
--space-2: 8px;
|
|
17
|
+
--space-3: 12px;
|
|
18
|
+
--space-4: 16px;
|
|
19
|
+
--space-5: 24px;
|
|
20
|
+
--space-6: 32px;
|
|
21
|
+
--space-7: 48px;
|
|
22
|
+
|
|
23
|
+
--radius-sm: 4px;
|
|
24
|
+
--radius-md: 8px;
|
|
25
|
+
--radius-lg: 12px;
|
|
26
|
+
|
|
27
|
+
--font-sans: "Source Sans 3", "Noto Sans Thai", ui-sans-serif, system-ui, sans-serif;
|
|
28
|
+
--font-display: "Fraunces", "Noto Serif Thai", ui-serif, Georgia, serif;
|
|
29
|
+
--text-xs: 0.75rem;
|
|
30
|
+
--text-sm: 0.875rem;
|
|
31
|
+
--text-md: 1rem;
|
|
32
|
+
--text-lg: 1.125rem;
|
|
33
|
+
--text-xl: 1.5rem;
|
|
34
|
+
--text-2xl: 2rem;
|
|
35
|
+
--leading-body: 1.5;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/* Optional dark pair — fill when direction includes dark mode */
|
|
39
|
+
[data-theme="dark"] {
|
|
40
|
+
--color-bg: #0c0a09;
|
|
41
|
+
--color-surface: #1c1917;
|
|
42
|
+
--color-text: #fafaf9;
|
|
43
|
+
--color-text-muted: #a8a29e;
|
|
44
|
+
--color-border: #44403c;
|
|
45
|
+
--color-accent: #2dd4bf;
|
|
46
|
+
--color-accent-contrast: #042f2e;
|
|
47
|
+
}
|