canvas-design-mcp 0.9.0
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/CLAUDE.md +200 -0
- package/DESIGN.md +288 -0
- package/PROFESSOR-INSTRUCTIONS.txt +131 -0
- package/README.md +250 -0
- package/dist/canvas-api.d.ts +24 -0
- package/dist/canvas-api.d.ts.map +1 -0
- package/dist/canvas-api.js +146 -0
- package/dist/canvas-api.js.map +1 -0
- package/dist/config.d.ts +5 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +22 -0
- package/dist/config.js.map +1 -0
- package/dist/design-engine.d.ts +5 -0
- package/dist/design-engine.d.ts.map +1 -0
- package/dist/design-engine.js +23 -0
- package/dist/design-engine.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +567 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/accessibility.d.ts +7 -0
- package/dist/tools/accessibility.d.ts.map +1 -0
- package/dist/tools/accessibility.js +149 -0
- package/dist/tools/accessibility.js.map +1 -0
- package/dist/tools/contrast.d.ts +2 -0
- package/dist/tools/contrast.d.ts.map +1 -0
- package/dist/tools/contrast.js +7 -0
- package/dist/tools/contrast.js.map +1 -0
- package/dist/tools/critique.d.ts +23 -0
- package/dist/tools/critique.d.ts.map +1 -0
- package/dist/tools/critique.js +194 -0
- package/dist/tools/critique.js.map +1 -0
- package/dist/tools/generate.d.ts +18 -0
- package/dist/tools/generate.d.ts.map +1 -0
- package/dist/tools/generate.js +101 -0
- package/dist/tools/generate.js.map +1 -0
- package/dist/tools/gotchas.d.ts +7 -0
- package/dist/tools/gotchas.d.ts.map +1 -0
- package/dist/tools/gotchas.js +61 -0
- package/dist/tools/gotchas.js.map +1 -0
- package/dist/tools/ingest.d.ts +44 -0
- package/dist/tools/ingest.d.ts.map +1 -0
- package/dist/tools/ingest.js +211 -0
- package/dist/tools/ingest.js.map +1 -0
- package/dist/tools/list-courses.d.ts +16 -0
- package/dist/tools/list-courses.d.ts.map +1 -0
- package/dist/tools/list-courses.js +79 -0
- package/dist/tools/list-courses.js.map +1 -0
- package/dist/tools/page-io.d.ts +19 -0
- package/dist/tools/page-io.d.ts.map +1 -0
- package/dist/tools/page-io.js +77 -0
- package/dist/tools/page-io.js.map +1 -0
- package/dist/tools/panopto.d.ts +36 -0
- package/dist/tools/panopto.d.ts.map +1 -0
- package/dist/tools/panopto.js +188 -0
- package/dist/tools/panopto.js.map +1 -0
- package/dist/tools/personas.d.ts +21 -0
- package/dist/tools/personas.d.ts.map +1 -0
- package/dist/tools/personas.js +464 -0
- package/dist/tools/personas.js.map +1 -0
- package/dist/tools/philosophy.d.ts +21 -0
- package/dist/tools/philosophy.d.ts.map +1 -0
- package/dist/tools/philosophy.js +137 -0
- package/dist/tools/philosophy.js.map +1 -0
- package/dist/tools/publish.d.ts +31 -0
- package/dist/tools/publish.d.ts.map +1 -0
- package/dist/tools/publish.js +198 -0
- package/dist/tools/publish.js.map +1 -0
- package/dist/tools/redesign.d.ts +18 -0
- package/dist/tools/redesign.d.ts.map +1 -0
- package/dist/tools/redesign.js +68 -0
- package/dist/tools/redesign.js.map +1 -0
- package/dist/tools/update-kb.d.ts +10 -0
- package/dist/tools/update-kb.d.ts.map +1 -0
- package/dist/tools/update-kb.js +93 -0
- package/dist/tools/update-kb.js.map +1 -0
- package/dist/tools/validate.d.ts +10 -0
- package/dist/tools/validate.d.ts.map +1 -0
- package/dist/tools/validate.js +76 -0
- package/dist/tools/validate.js.map +1 -0
- package/dist/types.d.ts +65 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/wizard.d.ts +3 -0
- package/dist/wizard.d.ts.map +1 -0
- package/dist/wizard.js +229 -0
- package/dist/wizard.js.map +1 -0
- package/docs/canvas-design-kb/00-meta/Changelog.md +42 -0
- package/docs/canvas-design-kb/00-meta/Contributing.md +58 -0
- package/docs/canvas-design-kb/00-meta/KB-Overview.md +51 -0
- package/docs/canvas-design-kb/01-canvas-rce/CSS-Inline-Strategy.md +166 -0
- package/docs/canvas-design-kb/01-canvas-rce/Canvas-Built-In-CSS-Classes.md +243 -0
- package/docs/canvas-design-kb/01-canvas-rce/Canvas-Page-Types.md +59 -0
- package/docs/canvas-design-kb/01-canvas-rce/HTML-Allowlist.md +204 -0
- package/docs/canvas-design-kb/01-canvas-rce/RCE-Limitations-and-Workarounds.md +151 -0
- package/docs/canvas-design-kb/01-canvas-rce/RCE-Overview.md +92 -0
- package/docs/canvas-design-kb/02-design-md/DESIGN-MD-Canvas-Template.md +323 -0
- package/docs/canvas-design-kb/02-design-md/DESIGN-MD-File-Structure.md +245 -0
- package/docs/canvas-design-kb/02-design-md/DESIGN-MD-Overview.md +120 -0
- package/docs/canvas-design-kb/02-design-md/DESIGN-MD-Toolchain.md +234 -0
- package/docs/canvas-design-kb/03-design-systems/Color-and-Typography.md +146 -0
- package/docs/canvas-design-kb/03-design-systems/Component-Library.md +299 -0
- package/docs/canvas-design-kb/03-design-systems/Design-System-Principles.md +99 -0
- package/docs/canvas-design-kb/04-tools/Canvas-Theme-Editor.md +40 -0
- package/docs/canvas-design-kb/04-tools/Other-Canvas-Design-Tools.md +47 -0
- package/docs/canvas-design-kb/05-patterns/Course-Home-Page.md +224 -0
- package/docs/canvas-design-kb/06-accessibility/Accessibility-Overview.md +128 -0
- package/docs/canvas-design-kb/07-resources/Inspiration-and-Showcases.md +121 -0
- package/docs/canvas-design-kb/07-resources/Official-Canvas-Links.md +54 -0
- package/docs/canvas-design-kb/README.md +58 -0
- package/docs/feature-roadmap.md +123 -0
- package/docs/installation.md +340 -0
- package/package.json +45 -0
- package/scripts/deploy-public.ps1 +68 -0
- package/src/kb/design-principles.md +45 -0
- package/src/templates/ignite-assignment-page.html +203 -0
- package/src/templates/two-column-dashboard.html +33 -0
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/dist/wizard.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wizard.d.ts","sourceRoot":"","sources":["../src/wizard.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAqCpD,wBAAsB,SAAS,IAAI,OAAO,CAAC,iBAAiB,CAAC,CA6N5D"}
|
package/dist/wizard.js
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { confirm, input, password } from '@inquirer/prompts';
|
|
2
|
+
import Color from 'color';
|
|
3
|
+
import { saveConfig } from './config.js';
|
|
4
|
+
import { wcagContrastRatio } from './tools/contrast.js';
|
|
5
|
+
import { getPhilosophyKb, savePhilosophyKb, updatePhilosophyKb, PHILOSOPHY_TEMPLATE, } from './tools/philosophy.js';
|
|
6
|
+
function deriveColors(primary, secondary) {
|
|
7
|
+
const c = Color(primary);
|
|
8
|
+
return {
|
|
9
|
+
primary,
|
|
10
|
+
primaryDark: c.darken(0.25).hex(),
|
|
11
|
+
primaryLight: c.lightness(93).hex(),
|
|
12
|
+
secondary,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function printMcpConfig() {
|
|
16
|
+
const config = {
|
|
17
|
+
mcpServers: {
|
|
18
|
+
'canvas-design': {
|
|
19
|
+
command: 'npx',
|
|
20
|
+
args: ['canvas-design-mcp'],
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
console.log('\n┌─────────────────────────────────────────────────────────┐');
|
|
25
|
+
console.log('│ Add this to your Claude Code MCP settings: │');
|
|
26
|
+
console.log('└─────────────────────────────────────────────────────────┘\n');
|
|
27
|
+
console.log(JSON.stringify(config, null, 2));
|
|
28
|
+
console.log('\nRestart Claude Code (or your MCP host) to activate.\n');
|
|
29
|
+
console.log('Works in: Claude Code · VS Code · ChatGPT Codex · any MCP host\n');
|
|
30
|
+
}
|
|
31
|
+
export async function runWizard() {
|
|
32
|
+
console.log('\n╔═══════════════════════════════════════════════════════════╗');
|
|
33
|
+
console.log('║ Canvas Design Studio — First Run Setup ║');
|
|
34
|
+
console.log('╚═══════════════════════════════════════════════════════════╝\n');
|
|
35
|
+
console.log('This wizard saves your institution config once.');
|
|
36
|
+
console.log('All fields except Canvas URL and API token can be changed later.\n');
|
|
37
|
+
const institution = await input({
|
|
38
|
+
message: 'Institution name:',
|
|
39
|
+
default: 'Boise State University',
|
|
40
|
+
});
|
|
41
|
+
let primaryHex;
|
|
42
|
+
while (true) {
|
|
43
|
+
primaryHex = await input({
|
|
44
|
+
message: 'Primary brand color (#hex):',
|
|
45
|
+
default: '#0033A0',
|
|
46
|
+
validate: (v) => /^#[0-9A-Fa-f]{6}$/.test(v) || 'Enter a valid hex color (e.g. #0033A0)',
|
|
47
|
+
});
|
|
48
|
+
const primaryRatio = wcagContrastRatio(primaryHex, '#ffffff');
|
|
49
|
+
if (primaryRatio >= 4.5) {
|
|
50
|
+
console.log(` Contrast on white: ${primaryRatio.toFixed(2)}:1 — passes WCAG AA`);
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
console.log(` Contrast on white: ${primaryRatio.toFixed(2)}:1 — ${primaryRatio >= 3.0 ? 'marginal' : 'fails'} for body text (AA requires 4.5:1)`);
|
|
54
|
+
console.log(' White text on this color may not be readable at small sizes. Consider darkening slightly.');
|
|
55
|
+
const go = await confirm({ message: 'Proceed with this color?', default: true });
|
|
56
|
+
if (go)
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
let secondaryHex;
|
|
60
|
+
while (true) {
|
|
61
|
+
secondaryHex = await input({
|
|
62
|
+
message: 'Secondary / accent color (#hex):',
|
|
63
|
+
default: '#D64309',
|
|
64
|
+
validate: (v) => /^#[0-9A-Fa-f]{6}$/.test(v) || 'Enter a valid hex color (e.g. #D64309)',
|
|
65
|
+
});
|
|
66
|
+
const secondaryRatio = wcagContrastRatio(secondaryHex, '#ffffff');
|
|
67
|
+
if (secondaryRatio >= 4.5) {
|
|
68
|
+
console.log(` Contrast on white: ${secondaryRatio.toFixed(2)}:1 — passes WCAG AA`);
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
console.log(` Contrast on white: ${secondaryRatio.toFixed(2)}:1 — ${secondaryRatio >= 3.0 ? 'marginal' : 'fails'} for body text (AA requires 4.5:1)`);
|
|
72
|
+
console.log(' White text on this color may not be readable at small sizes. Consider darkening slightly.');
|
|
73
|
+
const go = await confirm({ message: 'Proceed with this color?', default: true });
|
|
74
|
+
if (go)
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
const canvasUrl = await input({
|
|
78
|
+
message: 'Canvas base URL:',
|
|
79
|
+
default: 'https://boisestate.instructure.com',
|
|
80
|
+
validate: (v) => v.startsWith('https://') || 'URL must start with https://',
|
|
81
|
+
});
|
|
82
|
+
const apiToken = await password({
|
|
83
|
+
message: 'Canvas API token (optional — leave blank to generate HTML and paste it manually):',
|
|
84
|
+
mask: '*',
|
|
85
|
+
validate: (v) => !v || v.length > 10 || 'Token looks too short — leave blank or paste the full token from Canvas Account Settings > Approved Integrations',
|
|
86
|
+
});
|
|
87
|
+
const professorEmail = await input({
|
|
88
|
+
message: 'Professor email for FERPA scan allowlist (optional):',
|
|
89
|
+
default: '',
|
|
90
|
+
});
|
|
91
|
+
const favoriteCoursesRaw = await input({
|
|
92
|
+
message: 'Favorite Canvas course IDs, comma-separated (optional):',
|
|
93
|
+
default: '',
|
|
94
|
+
validate: (v) => {
|
|
95
|
+
if (!v.trim())
|
|
96
|
+
return true;
|
|
97
|
+
return v.split(',').every(id => /^\d+$/.test(id.trim())) || 'Use only numeric Canvas course IDs separated by commas.';
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
const favoriteCourses = favoriteCoursesRaw
|
|
101
|
+
.split(',')
|
|
102
|
+
.map(id => id.trim())
|
|
103
|
+
.filter(Boolean)
|
|
104
|
+
.map(Number);
|
|
105
|
+
const colors = deriveColors(primaryHex, secondaryHex);
|
|
106
|
+
const config = {
|
|
107
|
+
institution,
|
|
108
|
+
colors,
|
|
109
|
+
canvasUrl,
|
|
110
|
+
apiToken: apiToken || '',
|
|
111
|
+
professorEmail: professorEmail.trim() || undefined,
|
|
112
|
+
favoriteCourses: favoriteCourses.length > 0 ? favoriteCourses : undefined,
|
|
113
|
+
kbTipShown: false,
|
|
114
|
+
};
|
|
115
|
+
saveConfig(config);
|
|
116
|
+
// Optional Panopto section — always skippable
|
|
117
|
+
const panoptoDomain = await input({
|
|
118
|
+
message: 'Panopto domain (e.g. bsu.hosted.panopto.com, or leave blank to skip):',
|
|
119
|
+
default: '',
|
|
120
|
+
});
|
|
121
|
+
if (panoptoDomain.trim()) {
|
|
122
|
+
const whitelistAnswer = await input({
|
|
123
|
+
message: 'Is Panopto whitelisted for iframes in Canvas? (yes / no / unsure):',
|
|
124
|
+
default: 'unsure',
|
|
125
|
+
validate: (v) => ['yes', 'no', 'unsure'].includes(v.toLowerCase()) || 'Enter yes, no, or unsure',
|
|
126
|
+
});
|
|
127
|
+
const iframeWhitelisted = whitelistAnswer.toLowerCase() === 'yes' ? true :
|
|
128
|
+
whitelistAnswer.toLowerCase() === 'no' ? false :
|
|
129
|
+
null;
|
|
130
|
+
const panoptoClientId = await input({
|
|
131
|
+
message: 'Panopto API client ID (leave blank to skip — enables video search and caption download):',
|
|
132
|
+
default: '',
|
|
133
|
+
});
|
|
134
|
+
let panoptoClientSecret = '';
|
|
135
|
+
if (panoptoClientId.trim()) {
|
|
136
|
+
panoptoClientSecret = await password({
|
|
137
|
+
message: 'Panopto API client secret:',
|
|
138
|
+
mask: '*',
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
config.panopto = {
|
|
142
|
+
domain: panoptoDomain.trim().replace(/^https?:\/\//i, ''),
|
|
143
|
+
iframeWhitelisted,
|
|
144
|
+
...(panoptoClientId.trim() ? { clientId: panoptoClientId.trim(), clientSecret: panoptoClientSecret } : {}),
|
|
145
|
+
};
|
|
146
|
+
saveConfig(config);
|
|
147
|
+
console.log(`✓ Panopto domain: ${panoptoDomain.trim()}`);
|
|
148
|
+
console.log(` iFrame whitelisted: ${iframeWhitelisted === null ? 'unsure' : String(iframeWhitelisted)}`);
|
|
149
|
+
if (panoptoClientId.trim())
|
|
150
|
+
console.log('✓ Panopto API credentials saved');
|
|
151
|
+
}
|
|
152
|
+
// Philosophy KB phase — runs after Panopto, before final summary
|
|
153
|
+
const kbResult = getPhilosophyKb();
|
|
154
|
+
if (!kbResult.exists) {
|
|
155
|
+
const buildKb = await confirm({
|
|
156
|
+
message: 'Would you like to build your teaching philosophy KB now?\nClaude uses it to tailor every Canvas page to your style.\n(You can skip and build it in Claude later.)',
|
|
157
|
+
default: true,
|
|
158
|
+
});
|
|
159
|
+
if (buildKb) {
|
|
160
|
+
console.log('\nBuilding your teaching philosophy KB...\n');
|
|
161
|
+
const philosophyQuestions = [
|
|
162
|
+
"What's one thing you always tell students about this subject that you wish they'd really internalize?",
|
|
163
|
+
"What does a student who truly gets it do differently from one who just completes the work?",
|
|
164
|
+
"What's the biggest mistake students make on your assignments?",
|
|
165
|
+
"What separates an A from a B in concrete terms?",
|
|
166
|
+
"Are there teaching frameworks you consciously draw from? (Bloom's, UDL, constructivism, andragogy, etc.)",
|
|
167
|
+
"Any quotes or sayings you use regularly in class?",
|
|
168
|
+
];
|
|
169
|
+
const answers = [];
|
|
170
|
+
for (const q of philosophyQuestions) {
|
|
171
|
+
const answer = await input({ message: q });
|
|
172
|
+
if (answer.trim())
|
|
173
|
+
answers.push(answer.trim());
|
|
174
|
+
}
|
|
175
|
+
const coreContent = answers.map(a => `- ${a}`).join('\n');
|
|
176
|
+
const kbContent = PHILOSOPHY_TEMPLATE.replace('## Core Teaching Philosophy\n', `## Core Teaching Philosophy\n\n${coreContent}\n`);
|
|
177
|
+
savePhilosophyKb(kbContent);
|
|
178
|
+
console.log('✓ Teaching philosophy KB saved');
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
savePhilosophyKb(PHILOSOPHY_TEMPLATE);
|
|
182
|
+
console.log('✓ Philosophy KB template saved — build it in Claude anytime');
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
const updateKb = await confirm({
|
|
187
|
+
message: 'You already have a philosophy KB. Would you like to review or update it?',
|
|
188
|
+
default: false,
|
|
189
|
+
});
|
|
190
|
+
if (updateKb) {
|
|
191
|
+
console.log('\nYour current philosophy KB:\n');
|
|
192
|
+
console.log(kbResult.content);
|
|
193
|
+
console.log('');
|
|
194
|
+
const addCourse = await confirm({
|
|
195
|
+
message: 'Would you like to add course-specific focus for a course?',
|
|
196
|
+
default: false,
|
|
197
|
+
});
|
|
198
|
+
if (addCourse) {
|
|
199
|
+
const courseKey = await input({
|
|
200
|
+
message: 'Course key (e.g. "ITM 370 — AI Augmented Projects"):',
|
|
201
|
+
validate: (v) => v.trim().length > 0 || 'Course key is required',
|
|
202
|
+
});
|
|
203
|
+
const courseNote = await input({
|
|
204
|
+
message: `What should Claude know specifically about ${courseKey.trim()}?`,
|
|
205
|
+
});
|
|
206
|
+
if (courseNote.trim()) {
|
|
207
|
+
updatePhilosophyKb({ entry: courseNote.trim(), section: 'course', courseKey: courseKey.trim() });
|
|
208
|
+
console.log(`✓ Course-specific focus added for ${courseKey.trim()}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
console.log('\n✓ Config saved to ~/.canvas-design-mcp/institution.json');
|
|
214
|
+
console.log(`✓ Primary: ${colors.primary} → dark: ${colors.primaryDark} light: ${colors.primaryLight}`);
|
|
215
|
+
console.log(`✓ Secondary: ${colors.secondary}`);
|
|
216
|
+
if (!apiToken.trim()) {
|
|
217
|
+
console.log(' Canvas API token skipped. You can still generate HTML and paste it into Canvas manually.');
|
|
218
|
+
}
|
|
219
|
+
if (professorEmail.trim()) {
|
|
220
|
+
console.log(`✓ FERPA scan allowlist email: ${professorEmail.trim()}`);
|
|
221
|
+
}
|
|
222
|
+
if (favoriteCourses.length > 0) {
|
|
223
|
+
console.log(`✓ Favorite Canvas courses: ${favoriteCourses.join(', ')}`);
|
|
224
|
+
}
|
|
225
|
+
console.log('✓ Canvas Design Studio is ready\n');
|
|
226
|
+
printMcpConfig();
|
|
227
|
+
return config;
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=wizard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wizard.js","sourceRoot":"","sources":["../src/wizard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Parent: [Canvas Design Knowledge Base](../README.md) | [KB Overview](KB-Overview.md)
|
|
4
|
+
|
|
5
|
+
## 2026-05-10 - Public Documentation Cleanup
|
|
6
|
+
|
|
7
|
+
- Removed production guidance for the third-party Canvas design add-on and deleted those 04-tools pages.
|
|
8
|
+
- Kept third-party showcase references only where they are framed as external inspiration in [Inspiration and Showcases](../07-resources/Inspiration-and-Showcases.md).
|
|
9
|
+
- Converted the KB map and major reference pages away from Obsidian-style links.
|
|
10
|
+
- Reworked public resources so Canvas Design Studio is positioned as a standalone Canvas-safe HTML generator, not an integration with a commercial Canvas add-on.
|
|
11
|
+
|
|
12
|
+
## 2026-04-28 - Resource Evaluation Pass
|
|
13
|
+
|
|
14
|
+
New files:
|
|
15
|
+
|
|
16
|
+
- [Canvas Built-In CSS Classes](../01-canvas-rce/Canvas-Built-In-CSS-Classes.md) - Canvas utility classes such as `border`, `content-box`, `grid-row`, `col-*`, and `ic-Table`.
|
|
17
|
+
- [Other Canvas Design Tools](../04-tools/Other-Canvas-Design-Tools.md) - external Canvas design references, including Loree, HowToCanvas, Fleximode, JHU, Canvas Commons, and Canvas source links.
|
|
18
|
+
- [Inspiration and Showcases](../07-resources/Inspiration-and-Showcases.md) - real Canvas examples and design lessons.
|
|
19
|
+
|
|
20
|
+
Updated files:
|
|
21
|
+
|
|
22
|
+
- [HTML Allowlist](../01-canvas-rce/HTML-Allowlist.md) - added built-in CSS class notes.
|
|
23
|
+
- [RCE Limitations and Workarounds](../01-canvas-rce/RCE-Limitations-and-Workarounds.md) - grid gap workaround references built-in classes.
|
|
24
|
+
- [Official Canvas Links](../07-resources/Official-Canvas-Links.md) - consolidated production-facing Canvas and utility links.
|
|
25
|
+
- [README](../README.md) - updated KB map and quick reference table.
|
|
26
|
+
|
|
27
|
+
## 2026-04-28 - Initial Build
|
|
28
|
+
|
|
29
|
+
- Created the first knowledge base structure.
|
|
30
|
+
- Populated the core Canvas RCE, design-system, pattern, accessibility, and resource files.
|
|
31
|
+
|
|
32
|
+
## Template for Future Entries
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
## YYYY-MM-DD - Brief description
|
|
36
|
+
|
|
37
|
+
- What changed and why
|
|
38
|
+
- Source/reference if applicable
|
|
39
|
+
- Files affected: path/to/file.md
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
[KB Overview](KB-Overview.md) | [Contributing](Contributing.md)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Contributing to This KB
|
|
2
|
+
|
|
3
|
+
> **Parent:** [README](../README.md) | **Related:** [KB Overview](./KB-Overview.md), [Changelog](./Changelog.md)
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## How to Add Notes
|
|
8
|
+
|
|
9
|
+
### Adding a New Pattern
|
|
10
|
+
|
|
11
|
+
1. Create a new file in `05-patterns/` named descriptively: `Assignment-Page.md`, `Reading-Page.md`, etc.
|
|
12
|
+
2. Include the standard front matter: `> **Parent:** [README](../README.md) | **Related:** ...`
|
|
13
|
+
3. Add the anatomy, full HTML template, and customization checklist
|
|
14
|
+
4. Link from [README](../README.md) in the appropriate section
|
|
15
|
+
5. Add to [Changelog](./Changelog.md)
|
|
16
|
+
|
|
17
|
+
### Adding a New Component to the Library
|
|
18
|
+
|
|
19
|
+
1. Open [Component Library](../03-design-systems/Component-Library.md)
|
|
20
|
+
2. Add a numbered section with the component name
|
|
21
|
+
3. Include the ready-to-paste HTML
|
|
22
|
+
4. Add a note about any Canvas-specific gotchas
|
|
23
|
+
5. Update [Changelog](./Changelog.md)
|
|
24
|
+
|
|
25
|
+
### Updating an Existing Note
|
|
26
|
+
|
|
27
|
+
When Canvas changes behavior or a tool releases a new version:
|
|
28
|
+
1. Update the relevant file(s)
|
|
29
|
+
2. Add a dated entry to [Changelog](./Changelog.md)
|
|
30
|
+
3. If a link has changed, update the URL and note the change
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Formatting Conventions
|
|
35
|
+
|
|
36
|
+
- **Parent link** at top of every file
|
|
37
|
+
- **Related** links to closely connected files
|
|
38
|
+
- **Source** links to external authoritative references
|
|
39
|
+
- **⚠️** for warnings or "use with caution" notes
|
|
40
|
+
- **✅/❌** for allowed/not-allowed comparisons
|
|
41
|
+
- HTML code blocks use triple backticks with `html` language tag
|
|
42
|
+
- Inline code uses single backticks for HTML tags and CSS properties
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## What to Check Before Publishing a Pattern
|
|
47
|
+
|
|
48
|
+
- [ ] All HTML tested in Canvas RCE (paste into HTML view, save, verify nothing stripped)
|
|
49
|
+
- [ ] Checked in student view
|
|
50
|
+
- [ ] Tested on mobile (or Canvas mobile app)
|
|
51
|
+
- [ ] Color contrast checked against WCAG AA
|
|
52
|
+
- [ ] Heading hierarchy correct (H2 → H3 → H4)
|
|
53
|
+
- [ ] All images have `alt` attributes
|
|
54
|
+
- [ ] Links have descriptive text
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
*[KB Overview](./KB-Overview.md) | [Changelog](./Changelog.md)*
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# KB Overview
|
|
2
|
+
|
|
3
|
+
Parent: [Canvas Design Knowledge Base](../README.md)
|
|
4
|
+
|
|
5
|
+
This knowledge base is structured around three concerns:
|
|
6
|
+
|
|
7
|
+
1. Canvas constraints: what HTML and CSS survive inside the Canvas Rich Content Editor.
|
|
8
|
+
2. Design systems: how to define a consistent visual language for a course.
|
|
9
|
+
3. Patterns and examples: reusable Canvas-safe components plus real course examples for inspiration.
|
|
10
|
+
|
|
11
|
+
## Folder Structure
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
canvas-design-kb/
|
|
15
|
+
|-- README.md # Top-level map
|
|
16
|
+
|-- 00-meta/ # KB management
|
|
17
|
+
|-- 01-canvas-rce/ # How Canvas handles HTML/CSS
|
|
18
|
+
|-- 02-design-md/ # DESIGN.md specification notes
|
|
19
|
+
|-- 03-design-systems/ # Design system principles and components
|
|
20
|
+
|-- 04-tools/ # Canvas admin/tooling context
|
|
21
|
+
|-- 05-patterns/ # Page and component templates
|
|
22
|
+
|-- 06-accessibility/ # WCAG and inclusive design
|
|
23
|
+
`-- 07-resources/ # External links and references
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Update Cadence
|
|
27
|
+
|
|
28
|
+
| Area | When to review |
|
|
29
|
+
|---|---|
|
|
30
|
+
| HTML allowlist | When Canvas releases a major update |
|
|
31
|
+
| DESIGN.md spec | Monthly while the spec is evolving |
|
|
32
|
+
| Patterns and templates | Whenever a reusable page pattern is added |
|
|
33
|
+
| Accessibility | When WCAG or institutional guidance changes |
|
|
34
|
+
| External links | Before each public release |
|
|
35
|
+
|
|
36
|
+
## How to Use in Canvas Design Studio
|
|
37
|
+
|
|
38
|
+
1. Use [DESIGN.md Canvas Template](../02-design-md/DESIGN-MD-Canvas-Template.md) as the course design contract.
|
|
39
|
+
2. Treat [HTML Allowlist](../01-canvas-rce/HTML-Allowlist.md) and [CSS Inline Strategy](../01-canvas-rce/CSS-Inline-Strategy.md) as hard constraints.
|
|
40
|
+
3. Pull reusable snippets from [Component Library](../03-design-systems/Component-Library.md).
|
|
41
|
+
4. Use [Course Home Page](../05-patterns/Course-Home-Page.md) as the first page-level pattern.
|
|
42
|
+
5. Validate final HTML with [Accessibility Overview](../06-accessibility/Accessibility-Overview.md) and the `validate_canvas_html` MCP tool.
|
|
43
|
+
|
|
44
|
+
## Key Decisions
|
|
45
|
+
|
|
46
|
+
- Canvas strips `<style>` tags from content, so generated page CSS must be inline.
|
|
47
|
+
- Canvas reserves `<h1>` for the page title, so generated content starts at `<h2>`.
|
|
48
|
+
- The beginner workflow remains first-class: generate Canvas-safe HTML, then paste it manually into Canvas.
|
|
49
|
+
- Optional Canvas API publishing is a convenience, not a requirement.
|
|
50
|
+
|
|
51
|
+
See also: [Changelog](Changelog.md), [Contributing](Contributing.md)
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# CSS Inline Strategy for Canvas
|
|
2
|
+
|
|
3
|
+
> **Parent:** [README](../README.md) | **Related:** [HTML Allowlist](./HTML-Allowlist.md), [RCE Overview](./RCE-Overview.md)
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## The Core Constraint
|
|
8
|
+
|
|
9
|
+
Canvas strips `<style>` blocks from the RCE on save. **Every CSS declaration must live in a `style=""` attribute on the element it affects.**
|
|
10
|
+
|
|
11
|
+
This is non-negotiable at the page level unless your institution has a Canvas admin who can inject global CSS via the Theme Editor (see [Canvas Theme Editor](../04-tools/Canvas-Theme-Editor.md)).
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Writing Inline Styles That Survive
|
|
16
|
+
|
|
17
|
+
### ✅ Reliable Patterns
|
|
18
|
+
|
|
19
|
+
```html
|
|
20
|
+
<!-- Basic block with border and padding -->
|
|
21
|
+
<div style="border: 2px solid #0F6E56; padding: 16px; margin-bottom: 16px;">
|
|
22
|
+
Content here
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<!-- Colored background callout -->
|
|
26
|
+
<div style="background: #e1f5ee; border-left: 4px solid #0F6E56; padding: 14px 18px;">
|
|
27
|
+
<strong>Tip:</strong> Important note here.
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<!-- Two-column flex layout -->
|
|
31
|
+
<div style="display: flex; margin-bottom: 20px;">
|
|
32
|
+
<div style="flex: 1; padding: 12px; border: 1px solid #ddd;">Left column</div>
|
|
33
|
+
<div style="flex: 1; padding: 12px; border: 1px solid #ddd; margin-left: 12px;">Right column</div>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<!-- Card with border-radius -->
|
|
37
|
+
<div style="border: 1px solid #e0e0d8; border-radius: 10px; padding: 18px; margin-bottom: 16px;">
|
|
38
|
+
Card content
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<!-- Styled button link -->
|
|
42
|
+
<a href="#" style="display: inline-block; background: #0F6E56; color: #ffffff; padding: 10px 20px; border-radius: 6px; text-decoration: none; font-weight: bold;">
|
|
43
|
+
Button Label
|
|
44
|
+
</a>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### ❌ Things That Will Be Stripped
|
|
48
|
+
|
|
49
|
+
```html
|
|
50
|
+
<!-- STRIPPED: <style> block -->
|
|
51
|
+
<style>
|
|
52
|
+
.my-card { border-radius: 8px; }
|
|
53
|
+
</style>
|
|
54
|
+
|
|
55
|
+
<!-- STRIPPED: box-shadow -->
|
|
56
|
+
<div style="box-shadow: 0 2px 8px rgba(0,0,0,0.15);">
|
|
57
|
+
|
|
58
|
+
<!-- STRIPPED: transform -->
|
|
59
|
+
<div style="transform: rotate(3deg);">
|
|
60
|
+
|
|
61
|
+
<!-- STRIPPED: transition -->
|
|
62
|
+
<div style="transition: all 0.3s ease;">
|
|
63
|
+
|
|
64
|
+
<!-- STRIPPED: gap (use margin instead) -->
|
|
65
|
+
<div style="display: flex; gap: 16px;">
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Color Strategy
|
|
71
|
+
|
|
72
|
+
Since `opacity` is stripped, use **RGBA colors** for semi-transparent effects:
|
|
73
|
+
|
|
74
|
+
```html
|
|
75
|
+
<!-- Semi-transparent background -->
|
|
76
|
+
<div style="background: rgba(15, 110, 86, 0.1); padding: 16px;">
|
|
77
|
+
|
|
78
|
+
<!-- Border with transparency -->
|
|
79
|
+
<div style="border: 1px solid rgba(0,0,0,0.15); padding: 16px;">
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Flex Layout Without `gap`
|
|
85
|
+
|
|
86
|
+
Since `gap` isn't reliable, use negative margins on the parent + margins on children:
|
|
87
|
+
|
|
88
|
+
```html
|
|
89
|
+
<!-- Flex grid with spacing -->
|
|
90
|
+
<div style="display: flex; flex-wrap: wrap; margin-right: -12px;">
|
|
91
|
+
<div style="flex: 1; min-width: 200px; margin-right: 12px; margin-bottom: 12px; border: 1px solid #ddd; padding: 16px; border-radius: 8px;">
|
|
92
|
+
Item 1
|
|
93
|
+
</div>
|
|
94
|
+
<div style="flex: 1; min-width: 200px; margin-right: 12px; margin-bottom: 12px; border: 1px solid #ddd; padding: 16px; border-radius: 8px;">
|
|
95
|
+
Item 2
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Using CSS Inliner Tools
|
|
103
|
+
|
|
104
|
+
For complex layouts built externally (e.g., in a local HTML file with a `<style>` block), use an **inliner tool** to convert all CSS to inline styles before pasting into Canvas:
|
|
105
|
+
|
|
106
|
+
| Tool | URL | Notes |
|
|
107
|
+
|---|---|---|
|
|
108
|
+
| Juice (CLI) | https://github.com/Automattic/juice | Best for automation |
|
|
109
|
+
| CSS Inliner (web) | https://htmlemail.io/inline/ | Good for one-off use |
|
|
110
|
+
| Premailer | https://premailer.dialect.ca/ | Email-focused but works |
|
|
111
|
+
|
|
112
|
+
**Workflow:**
|
|
113
|
+
1. Write HTML with a `<style>` block (readable, maintainable)
|
|
114
|
+
2. Run through inliner
|
|
115
|
+
3. Paste resulting inline-only HTML into Canvas RCE HTML view
|
|
116
|
+
4. Save and verify
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Account-Level CSS (Admin Only)
|
|
121
|
+
|
|
122
|
+
If you have Canvas admin access, you can inject global CSS via:
|
|
123
|
+
|
|
124
|
+
**Admin → Account → Themes → Upload JS/CSS**
|
|
125
|
+
|
|
126
|
+
This allows `<style>` classes to work across all courses in the account. Useful for institution-wide design systems.
|
|
127
|
+
|
|
128
|
+
See [Canvas Theme Editor](../04-tools/Canvas-Theme-Editor.md) for details.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Property Reference Cheat Sheet
|
|
133
|
+
|
|
134
|
+
| CSS Property | Canvas Allowed? | Notes |
|
|
135
|
+
|---|---|---|
|
|
136
|
+
| `background` | ✅ | Includes `background-color` shorthand |
|
|
137
|
+
| `border` | ✅ | All border shorthand works |
|
|
138
|
+
| `border-radius` | ✅ | Works reliably |
|
|
139
|
+
| `color` | ✅ | Text color |
|
|
140
|
+
| `display` | ✅ | `flex`, `grid`, `block`, `inline-block` all work |
|
|
141
|
+
| `flex` | ✅ | Shorthand works; individual flex properties vary |
|
|
142
|
+
| `font` | ✅ | Shorthand; `font-size`, `font-weight`, `font-family` all survive |
|
|
143
|
+
| `height` / `width` | ✅ | Including `%` and `px` values |
|
|
144
|
+
| `margin` / `padding` | ✅ | All variants |
|
|
145
|
+
| `max-width` / `min-width` | ✅ | Responsive containment |
|
|
146
|
+
| `overflow` | ✅ | Useful for layout containment |
|
|
147
|
+
| `position` | ✅ | `relative`, `absolute` work |
|
|
148
|
+
| `text-align` | ✅ | |
|
|
149
|
+
| `text-decoration` | ✅ | |
|
|
150
|
+
| `vertical-align` | ✅ | |
|
|
151
|
+
| `z-index` | ✅ | |
|
|
152
|
+
| `box-shadow` | ❌ | Stripped |
|
|
153
|
+
| `filter` | ❌ | Stripped |
|
|
154
|
+
| `transform` | ❌ | Stripped |
|
|
155
|
+
| `transition` | ❌ | Stripped |
|
|
156
|
+
| `animation` | ❌ | Stripped |
|
|
157
|
+
| `opacity` | ❌ | Use `rgba()` colors instead |
|
|
158
|
+
| `gap` | ❌ | Use `margin` on children |
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## See Also
|
|
163
|
+
|
|
164
|
+
- [HTML Allowlist](./HTML-Allowlist.md) — Master reference for all allowed tags and properties
|
|
165
|
+
- [RCE Limitations And Workarounds](./RCE-Limitations-and-Workarounds.md) — Edge cases and institutional escalations
|
|
166
|
+
- [Component Library](../03-design-systems/Component-Library.md) — Pre-built components using only allowed CSS
|