-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDesign Notes.html
More file actions
172 lines (164 loc) · 11.5 KB
/
Design Notes.html
File metadata and controls
172 lines (164 loc) · 11.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>VSA DT Fabrication — Design Notes</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter+Tight:wght@400;500;600&family=Fraunces:opsz,wght@9..144,500&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<link rel="stylesheet" href="lib/tokens.css"/>
<template id="__bundler_thumbnail">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400"><rect width="400" height="400" fill="#f0eee9"/><g stroke="#1a1a16" stroke-width="4" fill="none"><rect x="90" y="110" width="90" height="60"/><rect x="220" y="110" width="90" height="60"/><rect x="90" y="210" width="220" height="60"/><path d="M180 140 L220 140 M200 170 L200 210"/></g><text x="200" y="330" font-family="monospace" font-size="20" fill="#1a1a16" text-anchor="middle" letter-spacing="4">DESIGN NOTES</text></template>
<style>body{background:#f0eee9}</style>
</head>
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
<script type="text/babel" src="lib/design-canvas.jsx"></script>
<script type="text/babel">
const STATES = [
{ k: "submitted", l: "Submitted", c: "var(--s-submitted)", d: "In the review pile. Technician owns next action." },
{ k: "needs_fix", l: "Needs fix", c: "var(--s-needs-fix)", d: "Back with the student. Coaching moment." },
{ k: "approved", l: "Approved", c: "var(--s-approved)", d: "Cleared to cut/print. Awaiting machine slot." },
{ k: "in_queue", l: "In queue", c: "var(--s-in-queue)", d: "Scheduled. Position & ETA visible." },
{ k: "in_production", l: "In production", c: "var(--s-in-prod)", d: "Physically running on machine." },
{ k: "completed", l: "Completed", c: "var(--s-completed)", d: "On the finished-work shelf." },
{ k: "rejected", l: "Rejected", c: "var(--s-rejected)", d: "Terminal. With reason and appeal route." },
];
const IA = [
{ role: "Student", icon: "person", color: "oklch(72% 0.08 30)",
surfaces: ["Home / pipeline", "New submission", "My job: status", "My job: needs fix (coaching)", "Machine library", "Ask"] },
{ role: "Teacher", icon: "book", color: "oklch(72% 0.08 160)",
surfaces: ["Class roster", "Student detail", "Class-wide patterns", "Ask"] },
{ role: "Technician", icon: "wrench", color: "oklch(72% 0.08 240)",
surfaces: ["Triage queue (3-col)", "Job detail + pre-flight", "Machine status board", "Audit log"] },
{ role: "Admin", icon: "gear", color: "oklch(72% 0.08 100)",
surfaces: ["Year-group rules", "Users & roles", "Machine config", "System audit"] },
{ role: "Public demo", icon: "eye", color: "oklch(72% 0.08 60)",
surfaces: ["Judge landing", "Guided role tour", "Read-only walkthrough"] },
];
const AI_POINTS = [
{ stage: "Before submit", what: "Plain-language rule explainers next to fields", human: "— not AI —", risk: "Low — explanatory text only" },
{ stage: "Submission", what: "File pre-flight flags (vector/raster, size)", human: "Technician confirms in review", risk: "Medium — could mislead if wrong" },
{ stage: "Needs-fix", what: "Drafts student-friendly issue explanations", human: "Technician reviews before send", risk: "Medium — always human-approved" },
{ stage: "Ask sidekick", what: "Contextual Q&A about rules, files, feedback", human: "— not AI —", risk: "Low — cannot change state" },
{ stage: "Pattern nudges",what: "Surfaces repeat-failures as learning prompts", human: "Student/teacher dismissible", risk: "Low — framed as invitation, not judgement" },
{ stage: "DECISIONS", what: "Approve / reject / grade / schedule", human: "HUMAN ONLY — AI excluded", risk: "N/A — not used here", danger: true },
];
const App = () => (
<DesignCanvas>
{/* ───────── 1. THESIS ───────── */}
<DCSection title="01 · Design thesis" subtitle="One sentence for what this product is.">
<DCArtboard width={960} height={360}>
<div style={{ padding: 48, height: "100%", display: "flex", flexDirection: "column", justifyContent: "center", background: "var(--ink-0)" }}>
<div className="small-caps" style={{ marginBottom: 14 }}>Thesis</div>
<div style={{ fontSize: 34, fontFamily: "var(--font-serif)", lineHeight: 1.2, letterSpacing: -0.8, color: "var(--ink-900)", fontWeight: 500 }}>
A <u style={{ textDecorationColor: "var(--ai-ink)", textDecorationThickness: 3, textUnderlineOffset: 6 }}>GenAI-supported guidance and feedback environment</u><br/>
for design-to-fabrication learning.
</div>
<div style={{ marginTop: 20, fontSize: 15, color: "var(--ink-600)", lineHeight: 1.6, maxWidth: 720 }}>
The workshop used to be opaque: submit, wait, get rejected, not know why. This tool makes the
hidden knowledge of fabrication <em>visible, teachable, and paced</em>. AI helps translate
rules and feedback into language a Y6 can follow. Humans still own every decision.
</div>
</div>
</DCArtboard>
<DCPostIt top={40} left={-10} rotate={-4} width={190}>
Not an AI automation tool.<br/>Not a ticket queue.<br/>A <strong>learning environment</strong>.
</DCPostIt>
</DCSection>
{/* ───────── 2. IA MAP ───────── */}
<DCSection title="02 · Information architecture" subtitle="Surfaces by role. Shared primitives, divergent landings.">
<DCArtboard width={1040} height={520}>
<div style={{ padding: 32, height: "100%", background: "var(--ink-0)", display: "grid", gridTemplateColumns: `repeat(${IA.length}, 1fr)`, gap: 14 }}>
{IA.map(col => (
<div key={col.role}>
<div style={{ padding: "8px 10px", borderRadius: 6, background: col.color, color: "#fff", fontSize: 13, fontWeight: 600, marginBottom: 10 }}>
{col.role}
</div>
{col.surfaces.map(s => (
<div key={s} style={{
padding: "10px 12px", marginBottom: 6, background: "var(--ink-50)",
border: "1px solid var(--ink-150)", borderRadius: 5,
fontSize: 12.5, color: "var(--ink-800)",
}}>{s}</div>
))}
</div>
))}
</div>
</DCArtboard>
<DCPostIt top={80} right={-10} rotate={3} width={200}>
Shared under the hood: one job record, one state machine, one audit log. Different landings.
</DCPostIt>
</DCSection>
{/* ───────── 3. STATE MACHINE ───────── */}
<DCSection title="03 · Workflow state palette" subtitle="Same chroma/lightness, different hues. State is colour-coded everywhere.">
<DCArtboard width={1200} height={280}>
<div style={{ padding: 32, height: "100%", background: "var(--ink-0)", display: "grid", gridTemplateColumns: `repeat(${STATES.length}, 1fr)`, gap: 14 }}>
{STATES.map(s => (
<div key={s.k}>
<div style={{ height: 54, borderRadius: 6, background: s.c, marginBottom: 10 }} />
<div style={{ fontSize: 13, fontWeight: 600 }}>{s.l}</div>
<div style={{ fontSize: 11, color: "var(--ink-500)", fontFamily: "var(--font-mono)", marginBottom: 6 }}>{s.k}</div>
<div style={{ fontSize: 11.5, color: "var(--ink-600)", lineHeight: 1.4 }}>{s.d}</div>
</div>
))}
</div>
</DCArtboard>
</DCSection>
{/* ───────── 4. GENAI MAP ───────── */}
<DCSection title="04 · Where GenAI lives (and where it doesn't)" subtitle="Explicit safeguards. Everything labelled in UI with the violet AI tag.">
<DCArtboard width={1100} height={440}>
<div style={{ padding: 24, height: "100%", background: "var(--ink-0)" }}>
<div style={{ display: "grid", gridTemplateColumns: "140px 1fr 1fr 1fr", gap: 0, fontSize: 11, fontFamily: "var(--font-mono)", textTransform: "uppercase", letterSpacing: "0.06em", color: "var(--ink-500)", padding: "0 12px 10px", borderBottom: "1px solid var(--ink-200)" }}>
<div>Stage</div><div>What AI does</div><div>Human role</div><div>Risk posture</div>
</div>
{AI_POINTS.map(p => (
<div key={p.stage} style={{
display: "grid", gridTemplateColumns: "140px 1fr 1fr 1fr",
gap: 0, padding: "14px 12px",
borderBottom: "1px solid var(--ink-100)",
background: p.danger ? "var(--s-rejected-bg)" : "transparent",
}}>
<div style={{ fontSize: 13, fontWeight: 600, color: p.danger ? "var(--s-rejected)" : "var(--ink-900)" }}>{p.stage}</div>
<div style={{ fontSize: 12.5, color: "var(--ink-700)" }}>{p.what}</div>
<div style={{ fontSize: 12.5, color: "var(--ink-600)" }}>{p.human}</div>
<div style={{ fontSize: 12.5, color: p.danger ? "var(--s-rejected)" : "var(--ink-600)" }}>{p.risk}</div>
</div>
))}
</div>
</DCArtboard>
<DCPostIt top={20} left={-10} rotate={-3} width={180}>
Every AI string in the UI wears a violet tag. Students learn to spot the difference.
</DCPostIt>
</DCSection>
{/* ───────── 5. OPEN QUESTIONS ───────── */}
<DCSection title="05 · Open questions & trade-offs" subtitle="What I'd want answered before implementation.">
<DCArtboard width={920} height={320}>
<div style={{ padding: 32, height: "100%", background: "var(--ink-0)" }}>
{[
["Apps Script latency", "Write ops take 1–3s. Do we use optimistic UI everywhere, or gate behind a spinner? I'd lean optimistic with rollback."],
["AI moderation", "Student-typed questions go to Ask — do we filter for off-topic? Rate-limit? Log for teacher review?"],
["Judge demo data", "Seed a realistic class or let judges create their own fake submissions? The latter shows more but is more to build."],
["Machine telemetry", "Real 'in production' progress is aspirational without sensors. Fake it with time-since-started? Or omit until v2?"],
["Mobile scope", "Student submit on phone: full flow, or 'start on phone, finish on desktop'? Dimension screenshots are easier on phone."],
].map(([q, a], i) => (
<div key={i} style={{ marginBottom: 14, paddingBottom: 14, borderBottom: "1px dashed var(--ink-150)" }}>
<div style={{ fontSize: 13, fontWeight: 600, marginBottom: 3 }}>{q}</div>
<div style={{ fontSize: 12.5, color: "var(--ink-600)", lineHeight: 1.5 }}>{a}</div>
</div>
))}
</div>
</DCArtboard>
<DCPostIt top={-10} right={20} rotate={5} width={180}>
Reply with answers to any of these and I'll iterate.
</DCPostIt>
</DCSection>
</DesignCanvas>
);
ReactDOM.createRoot(document.getElementById("root")).render(<App/>);
</script>
</body>
</html>