@compilr-dev/sdk 0.18.10 → 0.18.11

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.
@@ -0,0 +1,98 @@
1
+ /**
2
+ * The surface ramp the host injects.
3
+ *
4
+ * ⚠️ WHY THE HOST AND NOT CSS. A single `color-mix` cannot serve both polarities: a light
5
+ * theme's ground has no headroom above it (Catppuccin Latte sits at ~95% lightness, so a
6
+ * card 6% "above" it would be past white), while a dark theme's has plenty. CSS cannot
7
+ * branch on a palette's polarity. Whatever computes this has to know the luminance, so it
8
+ * lives here — pure, testable, and shared with the validator so the two cannot disagree
9
+ * about what "5–7% apart" means.
10
+ *
11
+ * ⚠️ THE GROUND MOVES ONLY WHEN IT MUST. The handoff's worked examples darken the ground
12
+ * in every case; this does it only when there is no room for the raised surface, so a
13
+ * dark theme's canvas keeps exactly the background its theme specifies and nothing about
14
+ * an existing canvas shifts. Latte has no room, so it darkens — there is no alternative
15
+ * that also keeps the card raised, which is the point of the ramp.
16
+ */
17
+ import { parseColor, oklabLightness, SURFACE_DELTA_TARGET, HAIRLINE_MIN_PCT, HAIRLINE_MAX_PCT, } from './color.js';
18
+ const hex = (n) => Math.round(Math.min(1, Math.max(0, n)) * 255)
19
+ .toString(16)
20
+ .padStart(2, '0');
21
+ const toHex = ({ r, g, b }) => `#${hex(r)}${hex(g)}${hex(b)}`;
22
+ const mix = (a, b, t) => ({
23
+ r: a.r + (b.r - a.r) * t,
24
+ g: a.g + (b.g - a.g) * t,
25
+ b: a.b + (b.b - a.b) * t,
26
+ });
27
+ const WHITE = { r: 1, g: 1, b: 1 };
28
+ const BLACK = { r: 0, g: 0, b: 0 };
29
+ /**
30
+ * The same colour at a different perceived lightness.
31
+ *
32
+ * ⚠️ Binary search over a mix toward white or black rather than an OKLab inverse. It
33
+ * keeps the hue of the ground (a tinted terminal ground stays tinted, which is most of
34
+ * why these palettes look like themselves) and cannot produce an out-of-gamut value,
35
+ * which an inverse transform can.
36
+ */
37
+ export function withLightness(color, targetL) {
38
+ const current = oklabLightness(color);
39
+ if (Math.abs(current - targetL) < 0.001)
40
+ return color;
41
+ const toward = targetL > current ? WHITE : BLACK;
42
+ let lo = 0;
43
+ let hi = 1;
44
+ let out = color;
45
+ for (let i = 0; i < 24; i++) {
46
+ const mid = (lo + hi) / 2;
47
+ out = mix(color, toward, mid);
48
+ const l = oklabLightness(out);
49
+ if (Math.abs(l - targetL) < 0.0005)
50
+ break;
51
+ if (targetL > current ? l < targetL : l > targetL)
52
+ lo = mid;
53
+ else
54
+ hi = mid;
55
+ }
56
+ return out;
57
+ }
58
+ /**
59
+ * Derive the three ramp tokens from a theme's ground and foreground.
60
+ *
61
+ * Raised is always lighter and inset always darker, in both polarities — a card that
62
+ * recedes from its page does not read as a card. When the ground cannot support both
63
+ * steps, the ground itself is moved just far enough to make room, and the returned `bg`
64
+ * says so.
65
+ */
66
+ export function deriveSurfaceRamp(bgInput, fgInput) {
67
+ const bg = parseColor(bgInput);
68
+ const fg = parseColor(fgInput);
69
+ if (!bg || !fg)
70
+ return null;
71
+ const step = SURFACE_DELTA_TARGET / 100;
72
+ let ground = oklabLightness(bg);
73
+ /*
74
+ Keep both steps inside the gamut by sliding the ground, never by shrinking the step —
75
+ a 3% ramp is the defect this exists to fix, so the separation is the invariant and the
76
+ ground's exact value is not.
77
+ */
78
+ const headroom = 1 - (ground + step);
79
+ const footroom = ground - step;
80
+ if (headroom < 0)
81
+ ground += headroom;
82
+ else if (footroom < 0)
83
+ ground -= footroom;
84
+ const groundRgb = withLightness(bg, ground);
85
+ /*
86
+ The hairline sits a fixed fraction of the way toward the foreground. Terminal palettes
87
+ derive their border from a comment or selection colour, which lands 35–100% of the way
88
+ there — that is the "hard borders" complaint, and it is why this ignores
89
+ --canvas-border entirely rather than trying to soften it.
90
+ */
91
+ const hairlineMix = (HAIRLINE_MIN_PCT + HAIRLINE_MAX_PCT) / 2 / 100;
92
+ return {
93
+ bg: toHex(groundRgb),
94
+ surface1: toHex(withLightness(groundRgb, ground + step)),
95
+ surface2: toHex(withLightness(groundRgb, ground - step)),
96
+ hairline: toHex(mix(groundRgb, fg, hairlineMix)),
97
+ };
98
+ }
@@ -244,11 +244,19 @@ export const CAPABILITY_PACKS = {
244
244
  'canvas_delete',
245
245
  'canvas_validate',
246
246
  'canvas_screenshot',
247
+ 'canvas_guide',
247
248
  ],
248
249
  readOnly: false,
249
250
  promptModules: ['platform-tool-hints'],
250
- promptSnippet: 'Visual canvases (infographic/carousel/board) rendered from sandboxed HTML/SVG. Create/replace with canvas_write (raw HTML only — host injects the CSP; inline <style>/<script> only, no network/remote assets; optional Tweaks controls manifest). EDIT via canvas_get (outline=true or startLine/maxLines) then canvas_edit (str_replace/append/prepend) — never re-send the whole document. After authoring, canvas_validate (static) then canvas_screenshot to SEE the render (vision models) — fix overflow/readability with canvas_edit.',
251
- estimatedPromptTokens: 150,
251
+ promptSnippet: 'Visual canvases (infographic/carousel/board) rendered from sandboxed HTML/SVG. ' +
252
+ // ⚠️ FIRST, and stated as a requirement rather than a suggestion. The craft guides
253
+ // used to be reachable only when a user typed /canvas, so most canvases were
254
+ // authored with no design guidance at all — see canvas_guide.
255
+ 'START by calling canvas_guide("canvas") — the design rules live there, not here, and a ' +
256
+ 'canvas authored without them renders correctly and still reads as generic. Then ' +
257
+ 'canvas_guide on the type you pick. ' +
258
+ 'Create/replace with canvas_write (raw HTML only — host injects the CSP; inline <style>/<script> only, no network/remote assets; optional Tweaks controls manifest). EDIT via canvas_get (outline=true or startLine/maxLines) then canvas_edit (str_replace/append/prepend) — never re-send the whole document. After authoring, canvas_validate (static) then canvas_screenshot to SEE the render (vision models) — fix overflow/readability with canvas_edit.',
259
+ estimatedPromptTokens: 190,
252
260
  estimatedToolTokens: 1500,
253
261
  },
254
262
  plans: {
@@ -29,7 +29,7 @@ export interface CanvasIssue {
29
29
  message: string;
30
30
  }
31
31
  /** Run deterministic static checks on canvas content. No rendering. */
32
- export declare function runCanvasChecks(html: string, type: CanvasType): CanvasIssue[];
32
+ export declare function runCanvasChecks(html: string, type: CanvasType, manifest?: ControlManifest): CanvasIssue[];
33
33
  export declare function createCanvasTools(config: PlatformToolsConfig): (import("@compilr-dev/agents").Tool<{
34
34
  type: string;
35
35
  title: string;
@@ -50,4 +50,6 @@ export declare function createCanvasTools(config: PlatformToolsConfig): (import(
50
50
  new_str?: string;
51
51
  content?: string;
52
52
  replace_all?: boolean;
53
+ }> | import("@compilr-dev/agents").Tool<{
54
+ topic: string;
53
55
  }>)[];
@@ -12,9 +12,13 @@
12
12
  */
13
13
  import { defineTool, createSuccessResult, createErrorResult } from '@compilr-dev/agents';
14
14
  import { truncateContent } from './truncate.js';
15
+ import { runQualityChecks } from '../../canvas/quality-checks.js';
15
16
  const PAGE_SIZES = ['16:9', '4:3', '1:1', '4:5', '9:16'];
16
17
  import { seedValues } from '../../canvas/types.js';
17
18
  import { validateControlManifest } from '../../canvas/validate.js';
19
+ import { canvasSkill, infographicSkill, carouselSkill, boardSkill, canvasStylesSkill, } from '../../skills/canvas-skills.js';
20
+ import { canvasExemplarInfographicSkill, canvasExemplarAppScreenSkill, } from '../../skills/canvas-exemplars.js';
21
+ import { canvasIconsSkill } from '../../skills/canvas-icons.js';
18
22
  const CANVAS_TYPES = ['infographic', 'carousel', 'board'];
19
23
  /** Render content as numbered lines (1-based), optionally a slice. */
20
24
  function numberedLines(content, startLine, maxLines) {
@@ -133,7 +137,7 @@ function offCanvasNodes(src, bounds) {
133
137
  return out;
134
138
  }
135
139
  /** Run deterministic static checks on canvas content. No rendering. */
136
- export function runCanvasChecks(html, type) {
140
+ export function runCanvasChecks(html, type, manifest) {
137
141
  const issues = [];
138
142
  const src = html.trim();
139
143
  if (!src) {
@@ -200,6 +204,14 @@ export function runCanvasChecks(html, type) {
200
204
  });
201
205
  }
202
206
  }
207
+ /*
208
+ The quality checks — surfaces, contrast, hue count, dead Tweaks. A separate module
209
+ because they are pure arithmetic on declared values and want testing without a
210
+ platform context; see `canvas/quality-checks.ts` for what each one deliberately
211
+ cannot know.
212
+ */
213
+ for (const issue of runQualityChecks(src, manifest))
214
+ issues.push(issue);
203
215
  return issues;
204
216
  }
205
217
  // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
@@ -294,7 +306,19 @@ export function createCanvasTools(config) {
294
306
  });
295
307
  if (!updated)
296
308
  return createErrorResult(`Canvas ${String(input.canvas_id)} not found.`);
297
- return createSuccessResult(`Updated canvas "${updated.title}" (${updated.type})\nID: ${String(updated.id)}`);
309
+ /*
310
+ ⚠️ The prose is UNCHANGED, deliberately. Desktop's auto-split parses the id out
311
+ of this exact wording (`renderer/src/lib/canvas-authored.ts`), and the model has
312
+ been reading it for every canvas it has ever written. The id now also travels as
313
+ a structured sibling so the host can stop regex-parsing prose — but both must
314
+ ship together for one version, or a Desktop that has not updated silently stops
315
+ splitting on author.
316
+ */
317
+ return {
318
+ success: true,
319
+ result: `Updated canvas "${updated.title}" (${updated.type})\nID: ${String(updated.id)}`,
320
+ canvas: { id: updated.id, title: updated.title, type: updated.type, action: 'updated' },
321
+ };
298
322
  }
299
323
  const projectId = input.project_id ?? ctx.currentProjectId;
300
324
  if (!projectId) {
@@ -310,7 +334,11 @@ export function createCanvasTools(config) {
310
334
  values: seedValues(controls),
311
335
  pageSize: input.page_size,
312
336
  });
313
- return createSuccessResult(`Created canvas "${created.title}" (${created.type})\nID: ${String(created.id)}`);
337
+ return {
338
+ success: true,
339
+ result: `Created canvas "${created.title}" (${created.type})\nID: ${String(created.id)}`,
340
+ canvas: { id: created.id, title: created.title, type: created.type, action: 'created' },
341
+ };
314
342
  }
315
343
  catch (error) {
316
344
  return createErrorResult(`Failed to write canvas: ${error instanceof Error ? error.message : String(error)}`);
@@ -537,12 +565,17 @@ export function createCanvasTools(config) {
537
565
  try {
538
566
  let html;
539
567
  let type;
568
+ // ⚠️ The manifest travels with a STORED canvas only. Validating raw html has no
569
+ // manifest to check against, so the dead-Tweak check is silent there rather than
570
+ // reporting every control as unbound — a canvas is written before it is stored.
571
+ let manifest;
540
572
  if (input.canvas_id !== undefined) {
541
573
  const c = await canvases.getById(input.canvas_id);
542
574
  if (!c)
543
575
  return createErrorResult(`Canvas ${String(input.canvas_id)} not found.`);
544
576
  html = c.content;
545
577
  type = c.type;
578
+ manifest = c.controls;
546
579
  }
547
580
  else if (input.html !== undefined) {
548
581
  html = input.html;
@@ -551,7 +584,7 @@ export function createCanvasTools(config) {
551
584
  else {
552
585
  return createErrorResult('Provide canvas_id (a stored canvas) or html (+ type) to validate.');
553
586
  }
554
- const issues = runCanvasChecks(html, type);
587
+ const issues = runCanvasChecks(html, type, manifest);
555
588
  if (issues.length === 0) {
556
589
  return createSuccessResult('✓ Passed all static checks — no structural/technical issues. (Visual/aesthetic review is a separate pass.)');
557
590
  }
@@ -625,6 +658,76 @@ export function createCanvasTools(config) {
625
658
  }
626
659
  },
627
660
  });
661
+ /*
662
+ ⚠️ THIS TOOL EXISTS BECAUSE THE CRAFT GUIDANCE WAS UNREACHABLE.
663
+
664
+ Skills are delivered by the HOST when a user types a slash command — Desktop fetches
665
+ the prompt and sends it as a user message. Nothing else delivers them: there is no
666
+ path from the agent to a skill, and the capability pack's snippet covers mechanics
667
+ only (canvas_write, the CSP, editing). So "make me an infographic" produced a canvas
668
+ authored with no design guidance at all, and every rule about hierarchy, restraint and
669
+ the elevation ramp reached the model only if the user happened to know to type
670
+ `/canvas` first.
671
+
672
+ That is the wrong shape: the agent, not the user, is the one who knows it is about to
673
+ author a canvas. So the guides become readable on demand — lazy, like the pack itself,
674
+ costing nothing until a canvas is actually being made.
675
+ */
676
+ const canvasGuideTool = defineTool({
677
+ name: 'canvas_guide',
678
+ description: 'Read the design guidance for a canvas BEFORE authoring one. Call with topic "canvas" ' +
679
+ 'first — it covers the steps, the sandbox rules and the theme tokens, and routes you to ' +
680
+ 'the right craft guide. Then read the guide for the type you picked ("infographic", ' +
681
+ '"carousel" or "board"), "styles" when choosing a look, and an "exemplar-*" topic for a ' +
682
+ 'worked example to adapt. Skipping this produces a canvas that renders but reads as ' +
683
+ 'generic — the exemplars in particular are worth more than any amount of description.',
684
+ inputSchema: {
685
+ type: 'object',
686
+ properties: {
687
+ topic: {
688
+ type: 'string',
689
+ enum: [
690
+ 'canvas',
691
+ 'infographic',
692
+ 'carousel',
693
+ 'board',
694
+ 'styles',
695
+ 'exemplar-infographic',
696
+ 'exemplar-app-screen',
697
+ 'icons',
698
+ ],
699
+ description: 'canvas = mechanics + steps (read this first) · infographic/carousel/board = the ' +
700
+ 'craft guide for that type · styles = the aesthetic catalogue · ' +
701
+ 'exemplar-infographic / exemplar-app-screen = a worked example to adapt, which is ' +
702
+ 'worth more than any amount of description.',
703
+ },
704
+ },
705
+ required: ['topic'],
706
+ },
707
+ execute: (input) => {
708
+ /*
709
+ ⚠️ `| undefined` is load-bearing. Without it `Record<string, T>` indexing claims a
710
+ value for every key, so the linter calls the guard below dead code — while at
711
+ runtime an unknown topic is exactly what it catches (asserted in canvas-guide
712
+ tests). The type was lying, not the guard.
713
+ */
714
+ const guides = {
715
+ canvas: canvasSkill,
716
+ infographic: infographicSkill,
717
+ carousel: carouselSkill,
718
+ board: boardSkill,
719
+ styles: canvasStylesSkill,
720
+ 'exemplar-infographic': canvasExemplarInfographicSkill,
721
+ 'exemplar-app-screen': canvasExemplarAppScreenSkill,
722
+ icons: canvasIconsSkill,
723
+ };
724
+ const guide = guides[input.topic];
725
+ if (!guide) {
726
+ return Promise.resolve(createErrorResult(`Unknown topic "${input.topic}". One of: ${Object.keys(guides).join(', ')}.`));
727
+ }
728
+ return Promise.resolve(createSuccessResult(guide.prompt));
729
+ },
730
+ });
628
731
  return [
629
732
  canvasWriteTool,
630
733
  canvasEditTool,
@@ -633,5 +736,6 @@ export function createCanvasTools(config) {
633
736
  canvasDeleteTool,
634
737
  canvasValidateTool,
635
738
  canvasScreenshotTool,
739
+ canvasGuideTool,
636
740
  ];
637
741
  }
@@ -0,0 +1,8 @@
1
+ /** The light theme-flat exemplar, ready to adapt. */
2
+ export declare const THEME_FLAT_EXEMPLAR = "<div style=\"--canvas-bg: #E9EAEE; --canvas-fg: #1B1C1F; --canvas-muted: #6B6D75; --canvas-accent: #C2410C; --canvas-card: #FFFFFF; --canvas-border: #D5D7DE; --canvas-surface-1: #FFFFFF; --canvas-surface-2: #F2F3F6; --canvas-hairline: #D5D7DE; width: 1000px; background: var(--canvas-bg); font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; color: var(--canvas-fg); padding: 40px;\">\n\n <div style=\"display: flex; align-items: baseline; justify-content: space-between; gap: 24px; margin-bottom: 24px;\">\n <div style=\"font-size: 11px; letter-spacing: 0.14em; font-weight: 600; color: var(--canvas-muted);\">Q3 DELIVERY REVIEW &nbsp;&middot;&nbsp; PLATFORM</div>\n <div style=\"font-size: 11px; letter-spacing: 0.08em; color: var(--canvas-muted);\">as of 6 Sep 2026</div>\n </div>\n\n <div style=\"display: grid; grid-template-columns: 1.35fr 1fr; gap: 16px; margin-bottom: 16px;\">\n <div style=\"background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 30px 32px;\">\n <div style=\"font-size: 11px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-accent); margin-bottom: 16px;\">THE QUARTER IN ONE NUMBER</div>\n <div style=\"font-size: 84px; line-height: 0.94; font-weight: 700; letter-spacing: -0.035em; font-variant-numeric: tabular-nums; margin-bottom: 12px;\">41<span style=\"font-size: 40px; font-weight: 600; color: var(--canvas-muted);\"> of 47</span></div>\n <div style=\"font-size: 20px; line-height: 1.35; font-weight: 600; letter-spacing: -0.01em; margin-bottom: 14px; max-width: 22em;\">commitments shipped, and the six that slipped share one cause.</div>\n <p style=\"font-size: 14px; line-height: 1.65; color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg)); margin: 0;\">Every delayed item was blocked on the migration, not on capacity. Team throughput rose 12% over Q2 while the queue behind a single dependency grew, which is why headcount is the wrong lever here.</p>\n </div>\n\n <div style=\"display: grid; grid-template-rows: repeat(3, 1fr); gap: 16px;\">\n <div style=\"background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 18px 20px; display: flex; align-items: baseline; justify-content: space-between; gap: 16px;\">\n <div>\n <div style=\"font-size: 10px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-muted); margin-bottom: 6px;\">CYCLE TIME</div>\n <div style=\"font-size: 34px; line-height: 1; font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums;\">6.2<span style=\"font-size: 15px; font-weight: 500; color: var(--canvas-muted);\"> days</span></div>\n </div>\n <div style=\"font-size: 13px; font-weight: 600; color: var(--canvas-accent); flex: none;\">&#9660; 1.8</div>\n </div>\n <div style=\"background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 18px 20px; display: flex; align-items: baseline; justify-content: space-between; gap: 16px;\">\n <div>\n <div style=\"font-size: 10px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-muted); margin-bottom: 6px;\">ESCAPED DEFECTS</div>\n <div style=\"font-size: 34px; line-height: 1; font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums;\">3</div>\n </div>\n <div style=\"font-size: 13px; font-weight: 600; color: var(--canvas-muted); flex: none;\">&#9660; 5</div>\n </div>\n <div style=\"background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 18px 20px; display: flex; align-items: baseline; justify-content: space-between; gap: 16px;\">\n <div>\n <div style=\"font-size: 10px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-muted); margin-bottom: 6px;\">BLOCKED, NOW</div>\n <div style=\"font-size: 34px; line-height: 1; font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums;\">6</div>\n </div>\n <div style=\"font-size: 13px; font-weight: 600; color: var(--canvas-muted); flex: none;\">&#9650; 4</div>\n </div>\n </div>\n </div>\n\n <div style=\"display: grid; grid-template-columns: 1fr 1fr; gap: 16px;\">\n\n <div style=\"background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 22px 24px 20px;\">\n <div style=\"font-size: 10px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-muted); margin-bottom: 18px;\">SHIPPED PER SPRINT</div>\n <svg width=\"100%\" height=\"150\" viewBox=\"0 0 420 150\" style=\"display: block; overflow: visible;\">\n <line x1=\"0\" y1=\"126\" x2=\"420\" y2=\"126\" style=\"stroke: var(--canvas-hairline, var(--canvas-border));\" stroke-width=\"1\"></line>\n <rect x=\"10\" y=\"72\" width=\"46\" height=\"54\" style=\"fill: color-mix(in oklab, var(--canvas-fg) 22%, var(--canvas-bg));\"></rect>\n <text x=\"33\" y=\"62\" text-anchor=\"middle\" font-size=\"13\" font-weight=\"700\" style=\"fill: var(--canvas-fg); font-family: system-ui, sans-serif;\">6</text>\n <text x=\"33\" y=\"142\" text-anchor=\"middle\" font-size=\"11\" style=\"fill: var(--canvas-muted); font-family: system-ui, sans-serif;\">S1</text>\n <rect x=\"76\" y=\"45\" width=\"46\" height=\"81\" style=\"fill: color-mix(in oklab, var(--canvas-fg) 22%, var(--canvas-bg));\"></rect>\n <text x=\"99\" y=\"35\" text-anchor=\"middle\" font-size=\"13\" font-weight=\"700\" style=\"fill: var(--canvas-fg); font-family: system-ui, sans-serif;\">9</text>\n <text x=\"99\" y=\"142\" text-anchor=\"middle\" font-size=\"11\" style=\"fill: var(--canvas-muted); font-family: system-ui, sans-serif;\">S2</text>\n <rect x=\"142\" y=\"54\" width=\"46\" height=\"72\" style=\"fill: color-mix(in oklab, var(--canvas-fg) 22%, var(--canvas-bg));\"></rect>\n <text x=\"165\" y=\"44\" text-anchor=\"middle\" font-size=\"13\" font-weight=\"700\" style=\"fill: var(--canvas-fg); font-family: system-ui, sans-serif;\">8</text>\n <text x=\"165\" y=\"142\" text-anchor=\"middle\" font-size=\"11\" style=\"fill: var(--canvas-muted); font-family: system-ui, sans-serif;\">S3</text>\n <rect x=\"208\" y=\"27\" width=\"46\" height=\"99\" style=\"fill: color-mix(in oklab, var(--canvas-fg) 22%, var(--canvas-bg));\"></rect>\n <text x=\"231\" y=\"17\" text-anchor=\"middle\" font-size=\"13\" font-weight=\"700\" style=\"fill: var(--canvas-fg); font-family: system-ui, sans-serif;\">11</text>\n <text x=\"231\" y=\"142\" text-anchor=\"middle\" font-size=\"11\" style=\"fill: var(--canvas-muted); font-family: system-ui, sans-serif;\">S4</text>\n <rect x=\"274\" y=\"99\" width=\"46\" height=\"27\" style=\"fill: var(--canvas-accent);\"></rect>\n <text x=\"297\" y=\"89\" text-anchor=\"middle\" font-size=\"13\" font-weight=\"700\" style=\"fill: var(--canvas-accent); font-family: system-ui, sans-serif;\">3</text>\n <text x=\"297\" y=\"142\" text-anchor=\"middle\" font-size=\"11\" style=\"fill: var(--canvas-muted); font-family: system-ui, sans-serif;\">S5</text>\n <rect x=\"340\" y=\"90\" width=\"46\" height=\"36\" style=\"fill: color-mix(in oklab, var(--canvas-fg) 22%, var(--canvas-bg));\"></rect>\n <text x=\"363\" y=\"80\" text-anchor=\"middle\" font-size=\"13\" font-weight=\"700\" style=\"fill: var(--canvas-fg); font-family: system-ui, sans-serif;\">4</text>\n <text x=\"363\" y=\"142\" text-anchor=\"middle\" font-size=\"11\" style=\"fill: var(--canvas-muted); font-family: system-ui, sans-serif;\">S6</text>\n </svg>\n <div style=\"font-size: 13px; line-height: 1.55; color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg)); margin-top: 20px; border-top: 1px solid var(--canvas-hairline, var(--canvas-border)); padding-top: 12px;\">Sprint 5 is when the migration landed in the critical path.</div>\n </div>\n\n <div style=\"background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 22px 24px 20px;\">\n <div style=\"font-size: 10px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-muted); margin-bottom: 14px;\">THE SIX THAT SLIPPED</div>\n <div style=\"background: var(--canvas-surface-2, var(--canvas-bg)); border: 1px solid var(--canvas-hairline, var(--canvas-border));\">\n <div style=\"display: grid; grid-template-columns: 1fr 88px 74px; gap: 12px; padding: 8px 14px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 10px; letter-spacing: 0.1em; font-weight: 600; color: var(--canvas-muted);\"><span>COMMITMENT</span><span>BLOCKED BY</span><span style=\"text-align: right;\">DAYS</span></div>\n <div style=\"display: grid; grid-template-columns: 1fr 88px 74px; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: baseline;\"><span style=\"font-weight: 600;\">Billing export</span><span style=\"color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg));\">migration</span><span style=\"text-align: right; font-variant-numeric: tabular-nums;\">21</span></div>\n <div style=\"display: grid; grid-template-columns: 1fr 88px 74px; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: baseline;\"><span style=\"font-weight: 600;\">Audit trail</span><span style=\"color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg));\">migration</span><span style=\"text-align: right; font-variant-numeric: tabular-nums;\">18</span></div>\n <div style=\"display: grid; grid-template-columns: 1fr 88px 74px; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: baseline;\"><span style=\"font-weight: 600;\">SSO for teams</span><span style=\"color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg));\">migration</span><span style=\"text-align: right; font-variant-numeric: tabular-nums;\">14</span></div>\n <div style=\"display: grid; grid-template-columns: 1fr 88px 74px; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: baseline;\"><span style=\"font-weight: 600;\">Usage alerts</span><span style=\"color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg));\">migration</span><span style=\"text-align: right; font-variant-numeric: tabular-nums;\">11</span></div>\n <div style=\"display: grid; grid-template-columns: 1fr 88px 74px; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: baseline;\"><span style=\"font-weight: 600;\">Retention job</span><span style=\"color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg));\">migration</span><span style=\"text-align: right; font-variant-numeric: tabular-nums;\">9</span></div>\n <div style=\"display: grid; grid-template-columns: 1fr 88px 74px; gap: 12px; padding: 10px 14px; font-size: 13px; align-items: baseline;\"><span style=\"font-weight: 600;\">Region failover</span><span style=\"color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg));\">migration</span><span style=\"text-align: right; font-variant-numeric: tabular-nums;\">6</span></div>\n </div>\n <div style=\"font-size: 13px; line-height: 1.55; color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg)); margin-top: 16px;\">One dependency, 79 days of accumulated delay.</div>\n </div>\n </div>\n\n <div style=\"border-top: 1px solid var(--canvas-hairline, var(--canvas-border)); margin-top: 26px; padding-top: 14px; display: flex; align-items: baseline; justify-content: space-between; gap: 24px; font-size: 11px; letter-spacing: 0.06em; color: var(--canvas-muted);\">\n <span>PLATFORM &nbsp;&middot;&nbsp; QUARTERLY REVIEW</span>\n <span>Source: delivery board, sprints 1&ndash;6</span>\n </div>\n </div>";
3
+ /** The same markup in dark: only these nine values change. */
4
+ export declare const THEME_FLAT_DARK_TOKENS = "--canvas-bg: #17181C; --canvas-fg: #ECEDF1; --canvas-muted: #9A9CA6; --canvas-accent: #FB7B4B; --canvas-card: #22242A; --canvas-border: #31333B; --canvas-surface-1: #22242A; --canvas-surface-2: #1B1D22; --canvas-hairline: #31333B";
5
+ /** The app-screen exemplar — a single UI screen, four surfaces. */
6
+ export declare const APP_SCREEN_EXEMPLAR = "<div style=\"--canvas-bg: #E9EAEE; --canvas-fg: #1B1C1F; --canvas-muted: #6B6D75; --canvas-accent: #C2410C; --canvas-card: #FFFFFF; --canvas-border: #D5D7DE; --canvas-surface-1: #FFFFFF; --canvas-surface-2: #F2F3F6; --canvas-hairline: #DCDEE4; width: 1000px; background: var(--canvas-surface-1, var(--canvas-card)); font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; color: var(--canvas-fg); display: grid; grid-template-columns: 232px 1fr;\">\n\n <div style=\"border-right: 1px solid var(--canvas-hairline, var(--canvas-border)); display: flex; flex-direction: column; min-height: 640px;\">\n <div style=\"padding: 18px 18px 16px; display: flex; align-items: center; gap: 10px;\">\n <span style=\"width: 28px; height: 28px; background: var(--canvas-fg); color: var(--canvas-surface-1, var(--canvas-card)); font-size: 11px; font-weight: 700; letter-spacing: 0.02em; display: flex; align-items: center; justify-content: center; flex: none;\">CO</span>\n <span style=\"font-size: 15px; font-weight: 700; letter-spacing: -0.01em;\">Cohort</span>\n </div>\n\n <div style=\"padding: 6px 10px 0; display: flex; flex-direction: column; gap: 1px;\">\n <div style=\"display: flex; align-items: center; gap: 10px; padding: 10px 12px; background: color-mix(in oklab, var(--canvas-accent) 10%, var(--canvas-surface-1, var(--canvas-card))); box-shadow: inset 2px 0 0 var(--canvas-accent); font-size: 13.5px; font-weight: 600;\">\n <span style=\"font-size: 13px; flex: none; color: var(--canvas-accent);\">&#9632;</span>Overview\n </div>\n <div style=\"display: flex; align-items: center; gap: 10px; padding: 10px 12px; font-size: 13.5px; color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"flex: none; color: var(--canvas-muted);\"><circle cx=\"6\" cy=\"6\" r=\"2.5\"></circle><path d=\"M2 13.5c.8-2.2 2.2-3.3 4-3.3s3.2 1.1 4 3.3\"></path><path d=\"M11 4.2a2.5 2.5 0 0 1 0 4.6\"></path></svg>Applicants\n <span style=\"margin-left: auto; font-size: 12px; color: var(--canvas-muted); font-variant-numeric: tabular-nums;\">248</span>\n </div>\n <div style=\"display: flex; align-items: center; gap: 10px; padding: 10px 12px; font-size: 13.5px; color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"flex: none; color: var(--canvas-muted);\"><rect x=\"2.5\" y=\"3.5\" width=\"11\" height=\"10\" rx=\"1\"></rect><path d=\"M2.5 6.5h11M5.5 2v2.5M10.5 2v2.5\"></path></svg>Interviews\n <span style=\"margin-left: auto; font-size: 12px; color: var(--canvas-muted); font-variant-numeric: tabular-nums;\">67</span>\n </div>\n <div style=\"display: flex; align-items: center; gap: 10px; padding: 10px 12px; font-size: 13.5px; color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"flex: none; color: var(--canvas-muted);\"><path d=\"M9.5 2H4.5A1.5 1.5 0 0 0 3 3.5v9A1.5 1.5 0 0 0 4.5 14h7a1.5 1.5 0 0 0 1.5-1.5V5.5z\"></path><path d=\"M9.5 2v3.5H13\"></path></svg>Documents\n </div>\n <div style=\"display: flex; align-items: center; gap: 10px; padding: 10px 12px; font-size: 13.5px; color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"flex: none; color: var(--canvas-muted);\"><path d=\"M2 14h12\"></path><path d=\"M4.5 14V9M8 14V4.5M11.5 14V7\"></path></svg>Reports\n </div>\n <div style=\"display: flex; align-items: center; gap: 10px; padding: 10px 12px; font-size: 13.5px; color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"flex: none; color: var(--canvas-muted);\"><path d=\"M2 5.5A1.5 1.5 0 0 1 3.5 4h2.2l1.3 1.6h5.5A1.5 1.5 0 0 1 14 7.1v5.4A1.5 1.5 0 0 1 12.5 14h-9A1.5 1.5 0 0 1 2 12.5z\"></path></svg>Programmes\n <span style=\"margin-left: auto; font-size: 12px; color: var(--canvas-muted); font-variant-numeric: tabular-nums;\">12</span>\n </div>\n </div>\n\n <div style=\"margin-top: auto; border-top: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 12px 22px; font-size: 13.5px; color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));\">Settings</div>\n <div style=\"border-top: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 14px 18px; display: flex; align-items: center; gap: 10px;\">\n <span style=\"width: 30px; height: 30px; background: var(--canvas-surface-2, var(--canvas-bg)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 11px; font-weight: 600; color: var(--canvas-muted); display: flex; align-items: center; justify-content: center; flex: none;\">RM</span>\n <span>\n <span style=\"display: block; font-size: 13px; font-weight: 600;\">Rita Marchetti</span>\n <span style=\"display: block; font-size: 11px; color: var(--canvas-muted);\">Admissions lead</span>\n </span>\n </div>\n </div>\n\n <div style=\"display: flex; flex-direction: column;\">\n <div style=\"padding: 20px 28px 18px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); display: flex; align-items: flex-end; justify-content: space-between; gap: 24px;\">\n <div>\n <div style=\"font-size: 11px; letter-spacing: 0.06em; color: var(--canvas-muted); margin-bottom: 6px;\">Autumn 2027 &nbsp;/&nbsp; Admissions</div>\n <div style=\"font-size: 26px; font-weight: 700; letter-spacing: -0.022em;\">Overview</div>\n </div>\n <div style=\"display: flex; align-items: center; gap: 8px; flex: none;\">\n <span style=\"font-size: 13px; padding: 8px 14px; border: 1px solid var(--canvas-hairline, var(--canvas-border)); color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));\">Export</span>\n <span style=\"font-size: 13px; font-weight: 600; padding: 9px 15px; background: var(--canvas-fg); color: var(--canvas-surface-1, var(--canvas-card));\">New applicant</span>\n </div>\n </div>\n <div style=\"background: var(--canvas-surface-2, var(--canvas-bg)); padding: 20px 28px 26px; flex: 1; display: flex; flex-direction: column; gap: 16px;\">\n\n <div style=\"display: grid; grid-template-columns: 1.45fr 1fr; gap: 16px;\">\n <div style=\"background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 22px 24px;\">\n <div style=\"display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-bottom: 14px;\">\n <div style=\"font-size: 10px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-accent);\">THIS WEEK</div>\n <div style=\"font-size: 11px; color: var(--canvas-muted);\">updated 4 min ago</div>\n </div>\n <div style=\"font-size: 27px; line-height: 1.2; font-weight: 700; letter-spacing: -0.022em; margin-bottom: 10px; max-width: 20em;\">Interviews are keeping pace. Document review is not.</div>\n <p style=\"font-size: 13.5px; line-height: 1.65; color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg)); margin: 0 0 16px;\">248 applicants across 12 programmes, and 67 have reached interview. The queue sits at document review, where 41 files have waited more than five days &mdash; two programmes account for 30 of them.</p>\n <span style=\"display: inline-block; font-size: 12.5px; font-weight: 600; color: var(--canvas-accent); border-bottom: 1px solid var(--canvas-accent); padding-bottom: 1px;\">Review the 41 waiting files</span>\n </div>\n\n <div style=\"background: var(--canvas-fg); color: var(--canvas-surface-1, var(--canvas-card)); padding: 20px 22px; display: flex; flex-direction: column; gap: 14px;\">\n <div style=\"display: flex; align-items: baseline; justify-content: space-between; gap: 12px;\">\n <span style=\"font-size: 10px; letter-spacing: 0.12em; font-weight: 600;\">PIPELINE</span>\n <span style=\"font-size: 10px; letter-spacing: 0.06em; opacity: 0.62;\">stage by stage</span>\n </div>\n <div style=\"display: flex; flex-direction: column; gap: 11px;\">\n <div>\n <div style=\"display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: 12px;\"><span style=\"opacity: 0.75;\">Applied</span><span style=\"font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums;\">248</span></div>\n <div style=\"height: 4px; background: rgba(255,255,255,0.16); margin-top: 5px;\"><div style=\"height: 4px; width: 100%; background: rgba(255,255,255,0.62);\"></div></div>\n </div>\n <div>\n <div style=\"display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: 12px;\"><span style=\"opacity: 0.75;\">Documents in</span><span style=\"font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums;\">193</span></div>\n <div style=\"height: 4px; background: rgba(255,255,255,0.16); margin-top: 5px;\"><div style=\"height: 4px; width: 78%; background: rgba(255,255,255,0.62);\"></div></div>\n </div>\n <div>\n <div style=\"display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: 12px;\"><span style=\"opacity: 0.75;\">Reviewed</span><span style=\"font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums;\">152</span></div>\n <div style=\"height: 4px; background: rgba(255,255,255,0.16); margin-top: 5px;\"><div style=\"height: 4px; width: 61%; background: var(--canvas-accent);\"></div></div>\n </div>\n <div>\n <div style=\"display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: 12px;\"><span style=\"opacity: 0.75;\">Interviewed</span><span style=\"font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums;\">67</span></div>\n <div style=\"height: 4px; background: rgba(255,255,255,0.16); margin-top: 5px;\"><div style=\"height: 4px; width: 27%; background: rgba(255,255,255,0.62);\"></div></div>\n </div>\n </div>\n <div style=\"margin-top: auto; border-top: 1px solid rgba(255,255,255,0.18); padding-top: 11px; font-size: 12px; opacity: 0.82;\">41 files stalled at review</div>\n </div>\n </div>\n\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n <span style=\"font-size: 10px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-muted); margin-right: 4px;\">FACULTY</span>\n <span style=\"font-size: 12.5px; font-weight: 600; padding: 6px 12px; background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-fg);\">All <span style=\"color: var(--canvas-muted); font-weight: 400;\">12</span></span>\n <span style=\"font-size: 12.5px; padding: 6px 12px; background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));\">Design <span style=\"color: var(--canvas-muted);\">4</span></span>\n <span style=\"font-size: 12.5px; padding: 6px 12px; background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));\">Business <span style=\"color: var(--canvas-muted);\">5</span></span>\n <span style=\"font-size: 12.5px; padding: 6px 12px; background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));\">Engineering <span style=\"color: var(--canvas-muted);\">3</span></span>\n </div>\n\n <div style=\"background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border));\">\n <div style=\"padding: 13px 18px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); display: flex; align-items: baseline; justify-content: space-between; gap: 16px;\">\n <span style=\"font-size: 14px; font-weight: 600;\">Programmes needing attention</span>\n <span style=\"font-size: 12px; color: var(--canvas-muted);\">4 of 12</span>\n </div>\n <div style=\"display: grid; grid-template-columns: 1.6fr 120px 84px 84px 92px; gap: 14px; padding: 9px 18px; background: var(--canvas-surface-2, var(--canvas-bg)); border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 10px; letter-spacing: 0.1em; font-weight: 600; color: var(--canvas-muted);\">\n <span>PROGRAMME</span><span>REVIEW</span><span style=\"text-align: right;\">APPLIED</span><span style=\"text-align: right;\">OFFERS</span><span style=\"text-align: right;\">WAITING</span>\n </div>\n <div style=\"display: grid; grid-template-columns: 1.6fr 120px 84px 84px 92px; gap: 14px; padding: 12px 18px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: center;\">\n <span style=\"font-weight: 600;\">MSc Product Design</span>\n <span style=\"height: 5px; background: var(--canvas-surface-2, var(--canvas-bg));\"><span style=\"display: block; height: 5px; width: 38%; background: var(--canvas-accent);\"></span></span>\n <span style=\"text-align: right; font-variant-numeric: tabular-nums;\">31</span>\n <span style=\"text-align: right; font-variant-numeric: tabular-nums;\">4</span>\n <span style=\"text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; color: var(--canvas-accent);\">17</span>\n </div>\n <div style=\"display: grid; grid-template-columns: 1.6fr 120px 84px 84px 92px; gap: 14px; padding: 12px 18px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: center;\">\n <span style=\"font-weight: 600;\">MBA Sustainable Business</span>\n <span style=\"height: 5px; background: var(--canvas-surface-2, var(--canvas-bg));\"><span style=\"display: block; height: 5px; width: 46%; background: var(--canvas-accent);\"></span></span>\n <span style=\"text-align: right; font-variant-numeric: tabular-nums;\">28</span>\n <span style=\"text-align: right; font-variant-numeric: tabular-nums;\">6</span>\n <span style=\"text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; color: var(--canvas-accent);\">13</span>\n </div>\n <div style=\"display: grid; grid-template-columns: 1.6fr 120px 84px 84px 92px; gap: 14px; padding: 12px 18px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: center;\">\n <span style=\"font-weight: 600;\">MA Curation</span>\n <span style=\"height: 5px; background: var(--canvas-surface-2, var(--canvas-bg));\"><span style=\"display: block; height: 5px; width: 71%; background: color-mix(in oklab, var(--canvas-fg) 32%, var(--canvas-bg));\"></span></span>\n <span style=\"text-align: right; font-variant-numeric: tabular-nums;\">19</span>\n <span style=\"text-align: right; font-variant-numeric: tabular-nums;\">5</span>\n <span style=\"text-align: right; font-variant-numeric: tabular-nums;\">7</span>\n </div>\n <div style=\"display: grid; grid-template-columns: 1.6fr 120px 84px 84px 92px; gap: 14px; padding: 12px 18px; font-size: 13px; align-items: center;\">\n <span style=\"font-weight: 600;\">MEng Robotics</span>\n <span style=\"height: 5px; background: var(--canvas-surface-2, var(--canvas-bg));\"><span style=\"display: block; height: 5px; width: 83%; background: color-mix(in oklab, var(--canvas-fg) 32%, var(--canvas-bg));\"></span></span>\n <span style=\"text-align: right; font-variant-numeric: tabular-nums;\">24</span>\n <span style=\"text-align: right; font-variant-numeric: tabular-nums;\">9</span>\n <span style=\"text-align: right; font-variant-numeric: tabular-nums;\">4</span>\n </div>\n </div>\n </div>\n </div>\n </div>";
7
+ export declare const canvasExemplarInfographicSkill: import("@compilr-dev/agents").Skill;
8
+ export declare const canvasExemplarAppScreenSkill: import("@compilr-dev/agents").Skill;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Worked exemplars — the samples an agent reads before authoring.
3
+ *
4
+ * ⚠️ GENERATED by scripts/build-canvas-exemplars.mjs from the design handoff. Do not
5
+ * edit by hand; re-run the script.
6
+ *
7
+ * ⚠️ WHY EXEMPLARS AND NOT MORE ADJECTIVES. The previous guidance described quality in
8
+ * words — "clean, minimal, generous whitespace" — so every session re-derived taste from
9
+ * scratch. Shown a real screenshot the model produces good work immediately, so what was
10
+ * missing was never capability; it was a reference.
11
+ *
12
+ * ⚠️ TWO SKILLS, NOT ONE. Together they are ~7.7K tokens and an agent authoring an
13
+ * infographic has no use for the app-screen markup, so canvas_guide serves them
14
+ * separately and each costs only what it is worth.
15
+ */
16
+ import { defineSkill } from '@compilr-dev/agents';
17
+ /** The light theme-flat exemplar, ready to adapt. */
18
+ export const THEME_FLAT_EXEMPLAR = '<div style="--canvas-bg: #E9EAEE; --canvas-fg: #1B1C1F; --canvas-muted: #6B6D75; --canvas-accent: #C2410C; --canvas-card: #FFFFFF; --canvas-border: #D5D7DE; --canvas-surface-1: #FFFFFF; --canvas-surface-2: #F2F3F6; --canvas-hairline: #D5D7DE; width: 1000px; background: var(--canvas-bg); font-family: system-ui, -apple-system, \'Segoe UI\', Roboto, sans-serif; color: var(--canvas-fg); padding: 40px;">\n\n <div style="display: flex; align-items: baseline; justify-content: space-between; gap: 24px; margin-bottom: 24px;">\n <div style="font-size: 11px; letter-spacing: 0.14em; font-weight: 600; color: var(--canvas-muted);">Q3 DELIVERY REVIEW &nbsp;&middot;&nbsp; PLATFORM</div>\n <div style="font-size: 11px; letter-spacing: 0.08em; color: var(--canvas-muted);">as of 6 Sep 2026</div>\n </div>\n\n <div style="display: grid; grid-template-columns: 1.35fr 1fr; gap: 16px; margin-bottom: 16px;">\n <div style="background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 30px 32px;">\n <div style="font-size: 11px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-accent); margin-bottom: 16px;">THE QUARTER IN ONE NUMBER</div>\n <div style="font-size: 84px; line-height: 0.94; font-weight: 700; letter-spacing: -0.035em; font-variant-numeric: tabular-nums; margin-bottom: 12px;">41<span style="font-size: 40px; font-weight: 600; color: var(--canvas-muted);"> of 47</span></div>\n <div style="font-size: 20px; line-height: 1.35; font-weight: 600; letter-spacing: -0.01em; margin-bottom: 14px; max-width: 22em;">commitments shipped, and the six that slipped share one cause.</div>\n <p style="font-size: 14px; line-height: 1.65; color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg)); margin: 0;">Every delayed item was blocked on the migration, not on capacity. Team throughput rose 12% over Q2 while the queue behind a single dependency grew, which is why headcount is the wrong lever here.</p>\n </div>\n\n <div style="display: grid; grid-template-rows: repeat(3, 1fr); gap: 16px;">\n <div style="background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 18px 20px; display: flex; align-items: baseline; justify-content: space-between; gap: 16px;">\n <div>\n <div style="font-size: 10px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-muted); margin-bottom: 6px;">CYCLE TIME</div>\n <div style="font-size: 34px; line-height: 1; font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums;">6.2<span style="font-size: 15px; font-weight: 500; color: var(--canvas-muted);"> days</span></div>\n </div>\n <div style="font-size: 13px; font-weight: 600; color: var(--canvas-accent); flex: none;">&#9660; 1.8</div>\n </div>\n <div style="background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 18px 20px; display: flex; align-items: baseline; justify-content: space-between; gap: 16px;">\n <div>\n <div style="font-size: 10px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-muted); margin-bottom: 6px;">ESCAPED DEFECTS</div>\n <div style="font-size: 34px; line-height: 1; font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums;">3</div>\n </div>\n <div style="font-size: 13px; font-weight: 600; color: var(--canvas-muted); flex: none;">&#9660; 5</div>\n </div>\n <div style="background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 18px 20px; display: flex; align-items: baseline; justify-content: space-between; gap: 16px;">\n <div>\n <div style="font-size: 10px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-muted); margin-bottom: 6px;">BLOCKED, NOW</div>\n <div style="font-size: 34px; line-height: 1; font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums;">6</div>\n </div>\n <div style="font-size: 13px; font-weight: 600; color: var(--canvas-muted); flex: none;">&#9650; 4</div>\n </div>\n </div>\n </div>\n\n <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 16px;">\n\n <div style="background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 22px 24px 20px;">\n <div style="font-size: 10px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-muted); margin-bottom: 18px;">SHIPPED PER SPRINT</div>\n <svg width="100%" height="150" viewBox="0 0 420 150" style="display: block; overflow: visible;">\n <line x1="0" y1="126" x2="420" y2="126" style="stroke: var(--canvas-hairline, var(--canvas-border));" stroke-width="1"></line>\n <rect x="10" y="72" width="46" height="54" style="fill: color-mix(in oklab, var(--canvas-fg) 22%, var(--canvas-bg));"></rect>\n <text x="33" y="62" text-anchor="middle" font-size="13" font-weight="700" style="fill: var(--canvas-fg); font-family: system-ui, sans-serif;">6</text>\n <text x="33" y="142" text-anchor="middle" font-size="11" style="fill: var(--canvas-muted); font-family: system-ui, sans-serif;">S1</text>\n <rect x="76" y="45" width="46" height="81" style="fill: color-mix(in oklab, var(--canvas-fg) 22%, var(--canvas-bg));"></rect>\n <text x="99" y="35" text-anchor="middle" font-size="13" font-weight="700" style="fill: var(--canvas-fg); font-family: system-ui, sans-serif;">9</text>\n <text x="99" y="142" text-anchor="middle" font-size="11" style="fill: var(--canvas-muted); font-family: system-ui, sans-serif;">S2</text>\n <rect x="142" y="54" width="46" height="72" style="fill: color-mix(in oklab, var(--canvas-fg) 22%, var(--canvas-bg));"></rect>\n <text x="165" y="44" text-anchor="middle" font-size="13" font-weight="700" style="fill: var(--canvas-fg); font-family: system-ui, sans-serif;">8</text>\n <text x="165" y="142" text-anchor="middle" font-size="11" style="fill: var(--canvas-muted); font-family: system-ui, sans-serif;">S3</text>\n <rect x="208" y="27" width="46" height="99" style="fill: color-mix(in oklab, var(--canvas-fg) 22%, var(--canvas-bg));"></rect>\n <text x="231" y="17" text-anchor="middle" font-size="13" font-weight="700" style="fill: var(--canvas-fg); font-family: system-ui, sans-serif;">11</text>\n <text x="231" y="142" text-anchor="middle" font-size="11" style="fill: var(--canvas-muted); font-family: system-ui, sans-serif;">S4</text>\n <rect x="274" y="99" width="46" height="27" style="fill: var(--canvas-accent);"></rect>\n <text x="297" y="89" text-anchor="middle" font-size="13" font-weight="700" style="fill: var(--canvas-accent); font-family: system-ui, sans-serif;">3</text>\n <text x="297" y="142" text-anchor="middle" font-size="11" style="fill: var(--canvas-muted); font-family: system-ui, sans-serif;">S5</text>\n <rect x="340" y="90" width="46" height="36" style="fill: color-mix(in oklab, var(--canvas-fg) 22%, var(--canvas-bg));"></rect>\n <text x="363" y="80" text-anchor="middle" font-size="13" font-weight="700" style="fill: var(--canvas-fg); font-family: system-ui, sans-serif;">4</text>\n <text x="363" y="142" text-anchor="middle" font-size="11" style="fill: var(--canvas-muted); font-family: system-ui, sans-serif;">S6</text>\n </svg>\n <div style="font-size: 13px; line-height: 1.55; color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg)); margin-top: 20px; border-top: 1px solid var(--canvas-hairline, var(--canvas-border)); padding-top: 12px;">Sprint 5 is when the migration landed in the critical path.</div>\n </div>\n\n <div style="background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 22px 24px 20px;">\n <div style="font-size: 10px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-muted); margin-bottom: 14px;">THE SIX THAT SLIPPED</div>\n <div style="background: var(--canvas-surface-2, var(--canvas-bg)); border: 1px solid var(--canvas-hairline, var(--canvas-border));">\n <div style="display: grid; grid-template-columns: 1fr 88px 74px; gap: 12px; padding: 8px 14px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 10px; letter-spacing: 0.1em; font-weight: 600; color: var(--canvas-muted);"><span>COMMITMENT</span><span>BLOCKED BY</span><span style="text-align: right;">DAYS</span></div>\n <div style="display: grid; grid-template-columns: 1fr 88px 74px; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: baseline;"><span style="font-weight: 600;">Billing export</span><span style="color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg));">migration</span><span style="text-align: right; font-variant-numeric: tabular-nums;">21</span></div>\n <div style="display: grid; grid-template-columns: 1fr 88px 74px; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: baseline;"><span style="font-weight: 600;">Audit trail</span><span style="color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg));">migration</span><span style="text-align: right; font-variant-numeric: tabular-nums;">18</span></div>\n <div style="display: grid; grid-template-columns: 1fr 88px 74px; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: baseline;"><span style="font-weight: 600;">SSO for teams</span><span style="color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg));">migration</span><span style="text-align: right; font-variant-numeric: tabular-nums;">14</span></div>\n <div style="display: grid; grid-template-columns: 1fr 88px 74px; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: baseline;"><span style="font-weight: 600;">Usage alerts</span><span style="color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg));">migration</span><span style="text-align: right; font-variant-numeric: tabular-nums;">11</span></div>\n <div style="display: grid; grid-template-columns: 1fr 88px 74px; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: baseline;"><span style="font-weight: 600;">Retention job</span><span style="color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg));">migration</span><span style="text-align: right; font-variant-numeric: tabular-nums;">9</span></div>\n <div style="display: grid; grid-template-columns: 1fr 88px 74px; gap: 12px; padding: 10px 14px; font-size: 13px; align-items: baseline;"><span style="font-weight: 600;">Region failover</span><span style="color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg));">migration</span><span style="text-align: right; font-variant-numeric: tabular-nums;">6</span></div>\n </div>\n <div style="font-size: 13px; line-height: 1.55; color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg)); margin-top: 16px;">One dependency, 79 days of accumulated delay.</div>\n </div>\n </div>\n\n <div style="border-top: 1px solid var(--canvas-hairline, var(--canvas-border)); margin-top: 26px; padding-top: 14px; display: flex; align-items: baseline; justify-content: space-between; gap: 24px; font-size: 11px; letter-spacing: 0.06em; color: var(--canvas-muted);">\n <span>PLATFORM &nbsp;&middot;&nbsp; QUARTERLY REVIEW</span>\n <span>Source: delivery board, sprints 1&ndash;6</span>\n </div>\n </div>';
19
+ /** The same markup in dark: only these nine values change. */
20
+ export const THEME_FLAT_DARK_TOKENS = '--canvas-bg: #17181C; --canvas-fg: #ECEDF1; --canvas-muted: #9A9CA6; --canvas-accent: #FB7B4B; --canvas-card: #22242A; --canvas-border: #31333B; --canvas-surface-1: #22242A; --canvas-surface-2: #1B1D22; --canvas-hairline: #31333B';
21
+ /** The app-screen exemplar — a single UI screen, four surfaces. */
22
+ export const APP_SCREEN_EXEMPLAR = '<div style="--canvas-bg: #E9EAEE; --canvas-fg: #1B1C1F; --canvas-muted: #6B6D75; --canvas-accent: #C2410C; --canvas-card: #FFFFFF; --canvas-border: #D5D7DE; --canvas-surface-1: #FFFFFF; --canvas-surface-2: #F2F3F6; --canvas-hairline: #DCDEE4; width: 1000px; background: var(--canvas-surface-1, var(--canvas-card)); font-family: system-ui, -apple-system, \'Segoe UI\', Roboto, sans-serif; color: var(--canvas-fg); display: grid; grid-template-columns: 232px 1fr;">\n\n <div style="border-right: 1px solid var(--canvas-hairline, var(--canvas-border)); display: flex; flex-direction: column; min-height: 640px;">\n <div style="padding: 18px 18px 16px; display: flex; align-items: center; gap: 10px;">\n <span style="width: 28px; height: 28px; background: var(--canvas-fg); color: var(--canvas-surface-1, var(--canvas-card)); font-size: 11px; font-weight: 700; letter-spacing: 0.02em; display: flex; align-items: center; justify-content: center; flex: none;">CO</span>\n <span style="font-size: 15px; font-weight: 700; letter-spacing: -0.01em;">Cohort</span>\n </div>\n\n <div style="padding: 6px 10px 0; display: flex; flex-direction: column; gap: 1px;">\n <div style="display: flex; align-items: center; gap: 10px; padding: 10px 12px; background: color-mix(in oklab, var(--canvas-accent) 10%, var(--canvas-surface-1, var(--canvas-card))); box-shadow: inset 2px 0 0 var(--canvas-accent); font-size: 13.5px; font-weight: 600;">\n <span style="font-size: 13px; flex: none; color: var(--canvas-accent);">&#9632;</span>Overview\n </div>\n <div style="display: flex; align-items: center; gap: 10px; padding: 10px 12px; font-size: 13.5px; color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" style="flex: none; color: var(--canvas-muted);"><circle cx="6" cy="6" r="2.5"></circle><path d="M2 13.5c.8-2.2 2.2-3.3 4-3.3s3.2 1.1 4 3.3"></path><path d="M11 4.2a2.5 2.5 0 0 1 0 4.6"></path></svg>Applicants\n <span style="margin-left: auto; font-size: 12px; color: var(--canvas-muted); font-variant-numeric: tabular-nums;">248</span>\n </div>\n <div style="display: flex; align-items: center; gap: 10px; padding: 10px 12px; font-size: 13.5px; color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" style="flex: none; color: var(--canvas-muted);"><rect x="2.5" y="3.5" width="11" height="10" rx="1"></rect><path d="M2.5 6.5h11M5.5 2v2.5M10.5 2v2.5"></path></svg>Interviews\n <span style="margin-left: auto; font-size: 12px; color: var(--canvas-muted); font-variant-numeric: tabular-nums;">67</span>\n </div>\n <div style="display: flex; align-items: center; gap: 10px; padding: 10px 12px; font-size: 13.5px; color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" style="flex: none; color: var(--canvas-muted);"><path d="M9.5 2H4.5A1.5 1.5 0 0 0 3 3.5v9A1.5 1.5 0 0 0 4.5 14h7a1.5 1.5 0 0 0 1.5-1.5V5.5z"></path><path d="M9.5 2v3.5H13"></path></svg>Documents\n </div>\n <div style="display: flex; align-items: center; gap: 10px; padding: 10px 12px; font-size: 13.5px; color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" style="flex: none; color: var(--canvas-muted);"><path d="M2 14h12"></path><path d="M4.5 14V9M8 14V4.5M11.5 14V7"></path></svg>Reports\n </div>\n <div style="display: flex; align-items: center; gap: 10px; padding: 10px 12px; font-size: 13.5px; color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" style="flex: none; color: var(--canvas-muted);"><path d="M2 5.5A1.5 1.5 0 0 1 3.5 4h2.2l1.3 1.6h5.5A1.5 1.5 0 0 1 14 7.1v5.4A1.5 1.5 0 0 1 12.5 14h-9A1.5 1.5 0 0 1 2 12.5z"></path></svg>Programmes\n <span style="margin-left: auto; font-size: 12px; color: var(--canvas-muted); font-variant-numeric: tabular-nums;">12</span>\n </div>\n </div>\n\n <div style="margin-top: auto; border-top: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 12px 22px; font-size: 13.5px; color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));">Settings</div>\n <div style="border-top: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 14px 18px; display: flex; align-items: center; gap: 10px;">\n <span style="width: 30px; height: 30px; background: var(--canvas-surface-2, var(--canvas-bg)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 11px; font-weight: 600; color: var(--canvas-muted); display: flex; align-items: center; justify-content: center; flex: none;">RM</span>\n <span>\n <span style="display: block; font-size: 13px; font-weight: 600;">Rita Marchetti</span>\n <span style="display: block; font-size: 11px; color: var(--canvas-muted);">Admissions lead</span>\n </span>\n </div>\n </div>\n\n <div style="display: flex; flex-direction: column;">\n <div style="padding: 20px 28px 18px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); display: flex; align-items: flex-end; justify-content: space-between; gap: 24px;">\n <div>\n <div style="font-size: 11px; letter-spacing: 0.06em; color: var(--canvas-muted); margin-bottom: 6px;">Autumn 2027 &nbsp;/&nbsp; Admissions</div>\n <div style="font-size: 26px; font-weight: 700; letter-spacing: -0.022em;">Overview</div>\n </div>\n <div style="display: flex; align-items: center; gap: 8px; flex: none;">\n <span style="font-size: 13px; padding: 8px 14px; border: 1px solid var(--canvas-hairline, var(--canvas-border)); color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));">Export</span>\n <span style="font-size: 13px; font-weight: 600; padding: 9px 15px; background: var(--canvas-fg); color: var(--canvas-surface-1, var(--canvas-card));">New applicant</span>\n </div>\n </div>\n <div style="background: var(--canvas-surface-2, var(--canvas-bg)); padding: 20px 28px 26px; flex: 1; display: flex; flex-direction: column; gap: 16px;">\n\n <div style="display: grid; grid-template-columns: 1.45fr 1fr; gap: 16px;">\n <div style="background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 22px 24px;">\n <div style="display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-bottom: 14px;">\n <div style="font-size: 10px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-accent);">THIS WEEK</div>\n <div style="font-size: 11px; color: var(--canvas-muted);">updated 4 min ago</div>\n </div>\n <div style="font-size: 27px; line-height: 1.2; font-weight: 700; letter-spacing: -0.022em; margin-bottom: 10px; max-width: 20em;">Interviews are keeping pace. Document review is not.</div>\n <p style="font-size: 13.5px; line-height: 1.65; color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg)); margin: 0 0 16px;">248 applicants across 12 programmes, and 67 have reached interview. The queue sits at document review, where 41 files have waited more than five days &mdash; two programmes account for 30 of them.</p>\n <span style="display: inline-block; font-size: 12.5px; font-weight: 600; color: var(--canvas-accent); border-bottom: 1px solid var(--canvas-accent); padding-bottom: 1px;">Review the 41 waiting files</span>\n </div>\n\n <div style="background: var(--canvas-fg); color: var(--canvas-surface-1, var(--canvas-card)); padding: 20px 22px; display: flex; flex-direction: column; gap: 14px;">\n <div style="display: flex; align-items: baseline; justify-content: space-between; gap: 12px;">\n <span style="font-size: 10px; letter-spacing: 0.12em; font-weight: 600;">PIPELINE</span>\n <span style="font-size: 10px; letter-spacing: 0.06em; opacity: 0.62;">stage by stage</span>\n </div>\n <div style="display: flex; flex-direction: column; gap: 11px;">\n <div>\n <div style="display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: 12px;"><span style="opacity: 0.75;">Applied</span><span style="font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums;">248</span></div>\n <div style="height: 4px; background: rgba(255,255,255,0.16); margin-top: 5px;"><div style="height: 4px; width: 100%; background: rgba(255,255,255,0.62);"></div></div>\n </div>\n <div>\n <div style="display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: 12px;"><span style="opacity: 0.75;">Documents in</span><span style="font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums;">193</span></div>\n <div style="height: 4px; background: rgba(255,255,255,0.16); margin-top: 5px;"><div style="height: 4px; width: 78%; background: rgba(255,255,255,0.62);"></div></div>\n </div>\n <div>\n <div style="display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: 12px;"><span style="opacity: 0.75;">Reviewed</span><span style="font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums;">152</span></div>\n <div style="height: 4px; background: rgba(255,255,255,0.16); margin-top: 5px;"><div style="height: 4px; width: 61%; background: var(--canvas-accent);"></div></div>\n </div>\n <div>\n <div style="display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: 12px;"><span style="opacity: 0.75;">Interviewed</span><span style="font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums;">67</span></div>\n <div style="height: 4px; background: rgba(255,255,255,0.16); margin-top: 5px;"><div style="height: 4px; width: 27%; background: rgba(255,255,255,0.62);"></div></div>\n </div>\n </div>\n <div style="margin-top: auto; border-top: 1px solid rgba(255,255,255,0.18); padding-top: 11px; font-size: 12px; opacity: 0.82;">41 files stalled at review</div>\n </div>\n </div>\n\n <div style="display: flex; align-items: center; gap: 8px;">\n <span style="font-size: 10px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-muted); margin-right: 4px;">FACULTY</span>\n <span style="font-size: 12.5px; font-weight: 600; padding: 6px 12px; background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-fg);">All <span style="color: var(--canvas-muted); font-weight: 400;">12</span></span>\n <span style="font-size: 12.5px; padding: 6px 12px; background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));">Design <span style="color: var(--canvas-muted);">4</span></span>\n <span style="font-size: 12.5px; padding: 6px 12px; background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));">Business <span style="color: var(--canvas-muted);">5</span></span>\n <span style="font-size: 12.5px; padding: 6px 12px; background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));">Engineering <span style="color: var(--canvas-muted);">3</span></span>\n </div>\n\n <div style="background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border));">\n <div style="padding: 13px 18px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); display: flex; align-items: baseline; justify-content: space-between; gap: 16px;">\n <span style="font-size: 14px; font-weight: 600;">Programmes needing attention</span>\n <span style="font-size: 12px; color: var(--canvas-muted);">4 of 12</span>\n </div>\n <div style="display: grid; grid-template-columns: 1.6fr 120px 84px 84px 92px; gap: 14px; padding: 9px 18px; background: var(--canvas-surface-2, var(--canvas-bg)); border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 10px; letter-spacing: 0.1em; font-weight: 600; color: var(--canvas-muted);">\n <span>PROGRAMME</span><span>REVIEW</span><span style="text-align: right;">APPLIED</span><span style="text-align: right;">OFFERS</span><span style="text-align: right;">WAITING</span>\n </div>\n <div style="display: grid; grid-template-columns: 1.6fr 120px 84px 84px 92px; gap: 14px; padding: 12px 18px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: center;">\n <span style="font-weight: 600;">MSc Product Design</span>\n <span style="height: 5px; background: var(--canvas-surface-2, var(--canvas-bg));"><span style="display: block; height: 5px; width: 38%; background: var(--canvas-accent);"></span></span>\n <span style="text-align: right; font-variant-numeric: tabular-nums;">31</span>\n <span style="text-align: right; font-variant-numeric: tabular-nums;">4</span>\n <span style="text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; color: var(--canvas-accent);">17</span>\n </div>\n <div style="display: grid; grid-template-columns: 1.6fr 120px 84px 84px 92px; gap: 14px; padding: 12px 18px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: center;">\n <span style="font-weight: 600;">MBA Sustainable Business</span>\n <span style="height: 5px; background: var(--canvas-surface-2, var(--canvas-bg));"><span style="display: block; height: 5px; width: 46%; background: var(--canvas-accent);"></span></span>\n <span style="text-align: right; font-variant-numeric: tabular-nums;">28</span>\n <span style="text-align: right; font-variant-numeric: tabular-nums;">6</span>\n <span style="text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; color: var(--canvas-accent);">13</span>\n </div>\n <div style="display: grid; grid-template-columns: 1.6fr 120px 84px 84px 92px; gap: 14px; padding: 12px 18px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: center;">\n <span style="font-weight: 600;">MA Curation</span>\n <span style="height: 5px; background: var(--canvas-surface-2, var(--canvas-bg));"><span style="display: block; height: 5px; width: 71%; background: color-mix(in oklab, var(--canvas-fg) 32%, var(--canvas-bg));"></span></span>\n <span style="text-align: right; font-variant-numeric: tabular-nums;">19</span>\n <span style="text-align: right; font-variant-numeric: tabular-nums;">5</span>\n <span style="text-align: right; font-variant-numeric: tabular-nums;">7</span>\n </div>\n <div style="display: grid; grid-template-columns: 1.6fr 120px 84px 84px 92px; gap: 14px; padding: 12px 18px; font-size: 13px; align-items: center;">\n <span style="font-weight: 600;">MEng Robotics</span>\n <span style="height: 5px; background: var(--canvas-surface-2, var(--canvas-bg));"><span style="display: block; height: 5px; width: 83%; background: color-mix(in oklab, var(--canvas-fg) 32%, var(--canvas-bg));"></span></span>\n <span style="text-align: right; font-variant-numeric: tabular-nums;">24</span>\n <span style="text-align: right; font-variant-numeric: tabular-nums;">9</span>\n <span style="text-align: right; font-variant-numeric: tabular-nums;">4</span>\n </div>\n </div>\n </div>\n </div>\n </div>';
23
+ export const canvasExemplarInfographicSkill = defineSkill({
24
+ name: 'canvas-exemplar-infographic',
25
+ description: 'A worked theme-flat infographic to read before authoring one — sandbox-legal markup ' +
26
+ 'showing the hierarchy, grid and restraint the style calls for.',
27
+ tags: ['visual', 'canvas', 'design', 'exemplar'],
28
+ prompt: 'A worked **theme-flat infographic**. Read it, then build yours to the same shape.\n\n⚠️ This is a reference to ADAPT, not a template to fill in. Copying the words produces\na canvas about someone else\'s quarter. What to carry over is the SHAPE: one dominant\nelement, a claim rather than a label as the headline, the accent used once, figures that\nreconcile, density that varies.\n\n⚠️ It is already sandbox-legal — system fonts, inline styles, theme tokens, an explicit\nbackground, no network. Keep the outer div that declares the tokens: it is what lets the\ncanvas render on any theme, and the var(--canvas-surface-1, var(--canvas-card)) fallbacks\nkeep it working on a host that has not shipped the elevation ramp.\n\n```html\n<div style="--canvas-bg: #E9EAEE; --canvas-fg: #1B1C1F; --canvas-muted: #6B6D75; --canvas-accent: #C2410C; --canvas-card: #FFFFFF; --canvas-border: #D5D7DE; --canvas-surface-1: #FFFFFF; --canvas-surface-2: #F2F3F6; --canvas-hairline: #D5D7DE; width: 1000px; background: var(--canvas-bg); font-family: system-ui, -apple-system, \'Segoe UI\', Roboto, sans-serif; color: var(--canvas-fg); padding: 40px;">\n\n <div style="display: flex; align-items: baseline; justify-content: space-between; gap: 24px; margin-bottom: 24px;">\n <div style="font-size: 11px; letter-spacing: 0.14em; font-weight: 600; color: var(--canvas-muted);">Q3 DELIVERY REVIEW &nbsp;&middot;&nbsp; PLATFORM</div>\n <div style="font-size: 11px; letter-spacing: 0.08em; color: var(--canvas-muted);">as of 6 Sep 2026</div>\n </div>\n\n <div style="display: grid; grid-template-columns: 1.35fr 1fr; gap: 16px; margin-bottom: 16px;">\n <div style="background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 30px 32px;">\n <div style="font-size: 11px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-accent); margin-bottom: 16px;">THE QUARTER IN ONE NUMBER</div>\n <div style="font-size: 84px; line-height: 0.94; font-weight: 700; letter-spacing: -0.035em; font-variant-numeric: tabular-nums; margin-bottom: 12px;">41<span style="font-size: 40px; font-weight: 600; color: var(--canvas-muted);"> of 47</span></div>\n <div style="font-size: 20px; line-height: 1.35; font-weight: 600; letter-spacing: -0.01em; margin-bottom: 14px; max-width: 22em;">commitments shipped, and the six that slipped share one cause.</div>\n <p style="font-size: 14px; line-height: 1.65; color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg)); margin: 0;">Every delayed item was blocked on the migration, not on capacity. Team throughput rose 12% over Q2 while the queue behind a single dependency grew, which is why headcount is the wrong lever here.</p>\n </div>\n\n <div style="display: grid; grid-template-rows: repeat(3, 1fr); gap: 16px;">\n <div style="background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 18px 20px; display: flex; align-items: baseline; justify-content: space-between; gap: 16px;">\n <div>\n <div style="font-size: 10px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-muted); margin-bottom: 6px;">CYCLE TIME</div>\n <div style="font-size: 34px; line-height: 1; font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums;">6.2<span style="font-size: 15px; font-weight: 500; color: var(--canvas-muted);"> days</span></div>\n </div>\n <div style="font-size: 13px; font-weight: 600; color: var(--canvas-accent); flex: none;">&#9660; 1.8</div>\n </div>\n <div style="background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 18px 20px; display: flex; align-items: baseline; justify-content: space-between; gap: 16px;">\n <div>\n <div style="font-size: 10px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-muted); margin-bottom: 6px;">ESCAPED DEFECTS</div>\n <div style="font-size: 34px; line-height: 1; font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums;">3</div>\n </div>\n <div style="font-size: 13px; font-weight: 600; color: var(--canvas-muted); flex: none;">&#9660; 5</div>\n </div>\n <div style="background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 18px 20px; display: flex; align-items: baseline; justify-content: space-between; gap: 16px;">\n <div>\n <div style="font-size: 10px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-muted); margin-bottom: 6px;">BLOCKED, NOW</div>\n <div style="font-size: 34px; line-height: 1; font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums;">6</div>\n </div>\n <div style="font-size: 13px; font-weight: 600; color: var(--canvas-muted); flex: none;">&#9650; 4</div>\n </div>\n </div>\n </div>\n\n <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 16px;">\n\n <div style="background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 22px 24px 20px;">\n <div style="font-size: 10px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-muted); margin-bottom: 18px;">SHIPPED PER SPRINT</div>\n <svg width="100%" height="150" viewBox="0 0 420 150" style="display: block; overflow: visible;">\n <line x1="0" y1="126" x2="420" y2="126" style="stroke: var(--canvas-hairline, var(--canvas-border));" stroke-width="1"></line>\n <rect x="10" y="72" width="46" height="54" style="fill: color-mix(in oklab, var(--canvas-fg) 22%, var(--canvas-bg));"></rect>\n <text x="33" y="62" text-anchor="middle" font-size="13" font-weight="700" style="fill: var(--canvas-fg); font-family: system-ui, sans-serif;">6</text>\n <text x="33" y="142" text-anchor="middle" font-size="11" style="fill: var(--canvas-muted); font-family: system-ui, sans-serif;">S1</text>\n <rect x="76" y="45" width="46" height="81" style="fill: color-mix(in oklab, var(--canvas-fg) 22%, var(--canvas-bg));"></rect>\n <text x="99" y="35" text-anchor="middle" font-size="13" font-weight="700" style="fill: var(--canvas-fg); font-family: system-ui, sans-serif;">9</text>\n <text x="99" y="142" text-anchor="middle" font-size="11" style="fill: var(--canvas-muted); font-family: system-ui, sans-serif;">S2</text>\n <rect x="142" y="54" width="46" height="72" style="fill: color-mix(in oklab, var(--canvas-fg) 22%, var(--canvas-bg));"></rect>\n <text x="165" y="44" text-anchor="middle" font-size="13" font-weight="700" style="fill: var(--canvas-fg); font-family: system-ui, sans-serif;">8</text>\n <text x="165" y="142" text-anchor="middle" font-size="11" style="fill: var(--canvas-muted); font-family: system-ui, sans-serif;">S3</text>\n <rect x="208" y="27" width="46" height="99" style="fill: color-mix(in oklab, var(--canvas-fg) 22%, var(--canvas-bg));"></rect>\n <text x="231" y="17" text-anchor="middle" font-size="13" font-weight="700" style="fill: var(--canvas-fg); font-family: system-ui, sans-serif;">11</text>\n <text x="231" y="142" text-anchor="middle" font-size="11" style="fill: var(--canvas-muted); font-family: system-ui, sans-serif;">S4</text>\n <rect x="274" y="99" width="46" height="27" style="fill: var(--canvas-accent);"></rect>\n <text x="297" y="89" text-anchor="middle" font-size="13" font-weight="700" style="fill: var(--canvas-accent); font-family: system-ui, sans-serif;">3</text>\n <text x="297" y="142" text-anchor="middle" font-size="11" style="fill: var(--canvas-muted); font-family: system-ui, sans-serif;">S5</text>\n <rect x="340" y="90" width="46" height="36" style="fill: color-mix(in oklab, var(--canvas-fg) 22%, var(--canvas-bg));"></rect>\n <text x="363" y="80" text-anchor="middle" font-size="13" font-weight="700" style="fill: var(--canvas-fg); font-family: system-ui, sans-serif;">4</text>\n <text x="363" y="142" text-anchor="middle" font-size="11" style="fill: var(--canvas-muted); font-family: system-ui, sans-serif;">S6</text>\n </svg>\n <div style="font-size: 13px; line-height: 1.55; color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg)); margin-top: 20px; border-top: 1px solid var(--canvas-hairline, var(--canvas-border)); padding-top: 12px;">Sprint 5 is when the migration landed in the critical path.</div>\n </div>\n\n <div style="background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 22px 24px 20px;">\n <div style="font-size: 10px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-muted); margin-bottom: 14px;">THE SIX THAT SLIPPED</div>\n <div style="background: var(--canvas-surface-2, var(--canvas-bg)); border: 1px solid var(--canvas-hairline, var(--canvas-border));">\n <div style="display: grid; grid-template-columns: 1fr 88px 74px; gap: 12px; padding: 8px 14px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 10px; letter-spacing: 0.1em; font-weight: 600; color: var(--canvas-muted);"><span>COMMITMENT</span><span>BLOCKED BY</span><span style="text-align: right;">DAYS</span></div>\n <div style="display: grid; grid-template-columns: 1fr 88px 74px; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: baseline;"><span style="font-weight: 600;">Billing export</span><span style="color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg));">migration</span><span style="text-align: right; font-variant-numeric: tabular-nums;">21</span></div>\n <div style="display: grid; grid-template-columns: 1fr 88px 74px; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: baseline;"><span style="font-weight: 600;">Audit trail</span><span style="color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg));">migration</span><span style="text-align: right; font-variant-numeric: tabular-nums;">18</span></div>\n <div style="display: grid; grid-template-columns: 1fr 88px 74px; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: baseline;"><span style="font-weight: 600;">SSO for teams</span><span style="color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg));">migration</span><span style="text-align: right; font-variant-numeric: tabular-nums;">14</span></div>\n <div style="display: grid; grid-template-columns: 1fr 88px 74px; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: baseline;"><span style="font-weight: 600;">Usage alerts</span><span style="color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg));">migration</span><span style="text-align: right; font-variant-numeric: tabular-nums;">11</span></div>\n <div style="display: grid; grid-template-columns: 1fr 88px 74px; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: baseline;"><span style="font-weight: 600;">Retention job</span><span style="color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg));">migration</span><span style="text-align: right; font-variant-numeric: tabular-nums;">9</span></div>\n <div style="display: grid; grid-template-columns: 1fr 88px 74px; gap: 12px; padding: 10px 14px; font-size: 13px; align-items: baseline;"><span style="font-weight: 600;">Region failover</span><span style="color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg));">migration</span><span style="text-align: right; font-variant-numeric: tabular-nums;">6</span></div>\n </div>\n <div style="font-size: 13px; line-height: 1.55; color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg)); margin-top: 16px;">One dependency, 79 days of accumulated delay.</div>\n </div>\n </div>\n\n <div style="border-top: 1px solid var(--canvas-hairline, var(--canvas-border)); margin-top: 26px; padding-top: 14px; display: flex; align-items: baseline; justify-content: space-between; gap: 24px; font-size: 11px; letter-spacing: 0.06em; color: var(--canvas-muted);">\n <span>PLATFORM &nbsp;&middot;&nbsp; QUARTERLY REVIEW</span>\n <span>Source: delivery board, sprints 1&ndash;6</span>\n </div>\n </div>\n```\n\n## The same design, dark\n\nNothing about the markup changes — only these nine values on the wrapper. A palette swap\nis not a different design, and if you find yourself restructuring for dark, something in\nthe structure was carrying the colour\'s weight.\n\n```\n--canvas-bg: #17181C; --canvas-fg: #ECEDF1; --canvas-muted: #9A9CA6; --canvas-accent: #FB7B4B; --canvas-card: #22242A; --canvas-border: #31333B; --canvas-surface-1: #22242A; --canvas-surface-2: #1B1D22; --canvas-hairline: #31333B\n```',
29
+ });
30
+ export const canvasExemplarAppScreenSkill = defineSkill({
31
+ name: 'canvas-exemplar-app-screen',
32
+ description: 'A worked app-screen mock to read before drawing a UI — four surfaces, one active ' +
33
+ 'state, a finding rather than a page name.',
34
+ tags: ['visual', 'canvas', 'design', 'exemplar'],
35
+ prompt: 'A worked **app-screen mock** — one screen of an application, not a wireframe.\n\n⚠️ This is a reference to ADAPT, not a template to fill in. Copying the words produces\na canvas about someone else\'s quarter. What to carry over is the SHAPE: one dominant\nelement, a claim rather than a label as the headline, the accent used once, figures that\nreconcile, density that varies.\n\n⚠️ It is already sandbox-legal — system fonts, inline styles, theme tokens, an explicit\nbackground, no network. Keep the outer div that declares the tokens: it is what lets the\ncanvas render on any theme, and the var(--canvas-surface-1, var(--canvas-card)) fallbacks\nkeep it working on a host that has not shipped the elevation ramp.\n\n⚠️ Note what it does NOT draw: no traffic lights, no browser tab bar, no URL field.\nWindow chrome costs vertical space and dates the mock; the app\'s own header is the frame.\n\n```html\n<div style="--canvas-bg: #E9EAEE; --canvas-fg: #1B1C1F; --canvas-muted: #6B6D75; --canvas-accent: #C2410C; --canvas-card: #FFFFFF; --canvas-border: #D5D7DE; --canvas-surface-1: #FFFFFF; --canvas-surface-2: #F2F3F6; --canvas-hairline: #DCDEE4; width: 1000px; background: var(--canvas-surface-1, var(--canvas-card)); font-family: system-ui, -apple-system, \'Segoe UI\', Roboto, sans-serif; color: var(--canvas-fg); display: grid; grid-template-columns: 232px 1fr;">\n\n <div style="border-right: 1px solid var(--canvas-hairline, var(--canvas-border)); display: flex; flex-direction: column; min-height: 640px;">\n <div style="padding: 18px 18px 16px; display: flex; align-items: center; gap: 10px;">\n <span style="width: 28px; height: 28px; background: var(--canvas-fg); color: var(--canvas-surface-1, var(--canvas-card)); font-size: 11px; font-weight: 700; letter-spacing: 0.02em; display: flex; align-items: center; justify-content: center; flex: none;">CO</span>\n <span style="font-size: 15px; font-weight: 700; letter-spacing: -0.01em;">Cohort</span>\n </div>\n\n <div style="padding: 6px 10px 0; display: flex; flex-direction: column; gap: 1px;">\n <div style="display: flex; align-items: center; gap: 10px; padding: 10px 12px; background: color-mix(in oklab, var(--canvas-accent) 10%, var(--canvas-surface-1, var(--canvas-card))); box-shadow: inset 2px 0 0 var(--canvas-accent); font-size: 13.5px; font-weight: 600;">\n <span style="font-size: 13px; flex: none; color: var(--canvas-accent);">&#9632;</span>Overview\n </div>\n <div style="display: flex; align-items: center; gap: 10px; padding: 10px 12px; font-size: 13.5px; color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" style="flex: none; color: var(--canvas-muted);"><circle cx="6" cy="6" r="2.5"></circle><path d="M2 13.5c.8-2.2 2.2-3.3 4-3.3s3.2 1.1 4 3.3"></path><path d="M11 4.2a2.5 2.5 0 0 1 0 4.6"></path></svg>Applicants\n <span style="margin-left: auto; font-size: 12px; color: var(--canvas-muted); font-variant-numeric: tabular-nums;">248</span>\n </div>\n <div style="display: flex; align-items: center; gap: 10px; padding: 10px 12px; font-size: 13.5px; color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" style="flex: none; color: var(--canvas-muted);"><rect x="2.5" y="3.5" width="11" height="10" rx="1"></rect><path d="M2.5 6.5h11M5.5 2v2.5M10.5 2v2.5"></path></svg>Interviews\n <span style="margin-left: auto; font-size: 12px; color: var(--canvas-muted); font-variant-numeric: tabular-nums;">67</span>\n </div>\n <div style="display: flex; align-items: center; gap: 10px; padding: 10px 12px; font-size: 13.5px; color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" style="flex: none; color: var(--canvas-muted);"><path d="M9.5 2H4.5A1.5 1.5 0 0 0 3 3.5v9A1.5 1.5 0 0 0 4.5 14h7a1.5 1.5 0 0 0 1.5-1.5V5.5z"></path><path d="M9.5 2v3.5H13"></path></svg>Documents\n </div>\n <div style="display: flex; align-items: center; gap: 10px; padding: 10px 12px; font-size: 13.5px; color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" style="flex: none; color: var(--canvas-muted);"><path d="M2 14h12"></path><path d="M4.5 14V9M8 14V4.5M11.5 14V7"></path></svg>Reports\n </div>\n <div style="display: flex; align-items: center; gap: 10px; padding: 10px 12px; font-size: 13.5px; color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" style="flex: none; color: var(--canvas-muted);"><path d="M2 5.5A1.5 1.5 0 0 1 3.5 4h2.2l1.3 1.6h5.5A1.5 1.5 0 0 1 14 7.1v5.4A1.5 1.5 0 0 1 12.5 14h-9A1.5 1.5 0 0 1 2 12.5z"></path></svg>Programmes\n <span style="margin-left: auto; font-size: 12px; color: var(--canvas-muted); font-variant-numeric: tabular-nums;">12</span>\n </div>\n </div>\n\n <div style="margin-top: auto; border-top: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 12px 22px; font-size: 13.5px; color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));">Settings</div>\n <div style="border-top: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 14px 18px; display: flex; align-items: center; gap: 10px;">\n <span style="width: 30px; height: 30px; background: var(--canvas-surface-2, var(--canvas-bg)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 11px; font-weight: 600; color: var(--canvas-muted); display: flex; align-items: center; justify-content: center; flex: none;">RM</span>\n <span>\n <span style="display: block; font-size: 13px; font-weight: 600;">Rita Marchetti</span>\n <span style="display: block; font-size: 11px; color: var(--canvas-muted);">Admissions lead</span>\n </span>\n </div>\n </div>\n\n <div style="display: flex; flex-direction: column;">\n <div style="padding: 20px 28px 18px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); display: flex; align-items: flex-end; justify-content: space-between; gap: 24px;">\n <div>\n <div style="font-size: 11px; letter-spacing: 0.06em; color: var(--canvas-muted); margin-bottom: 6px;">Autumn 2027 &nbsp;/&nbsp; Admissions</div>\n <div style="font-size: 26px; font-weight: 700; letter-spacing: -0.022em;">Overview</div>\n </div>\n <div style="display: flex; align-items: center; gap: 8px; flex: none;">\n <span style="font-size: 13px; padding: 8px 14px; border: 1px solid var(--canvas-hairline, var(--canvas-border)); color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));">Export</span>\n <span style="font-size: 13px; font-weight: 600; padding: 9px 15px; background: var(--canvas-fg); color: var(--canvas-surface-1, var(--canvas-card));">New applicant</span>\n </div>\n </div>\n <div style="background: var(--canvas-surface-2, var(--canvas-bg)); padding: 20px 28px 26px; flex: 1; display: flex; flex-direction: column; gap: 16px;">\n\n <div style="display: grid; grid-template-columns: 1.45fr 1fr; gap: 16px;">\n <div style="background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); padding: 22px 24px;">\n <div style="display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-bottom: 14px;">\n <div style="font-size: 10px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-accent);">THIS WEEK</div>\n <div style="font-size: 11px; color: var(--canvas-muted);">updated 4 min ago</div>\n </div>\n <div style="font-size: 27px; line-height: 1.2; font-weight: 700; letter-spacing: -0.022em; margin-bottom: 10px; max-width: 20em;">Interviews are keeping pace. Document review is not.</div>\n <p style="font-size: 13.5px; line-height: 1.65; color: color-mix(in oklab, var(--canvas-fg) 78%, var(--canvas-bg)); margin: 0 0 16px;">248 applicants across 12 programmes, and 67 have reached interview. The queue sits at document review, where 41 files have waited more than five days &mdash; two programmes account for 30 of them.</p>\n <span style="display: inline-block; font-size: 12.5px; font-weight: 600; color: var(--canvas-accent); border-bottom: 1px solid var(--canvas-accent); padding-bottom: 1px;">Review the 41 waiting files</span>\n </div>\n\n <div style="background: var(--canvas-fg); color: var(--canvas-surface-1, var(--canvas-card)); padding: 20px 22px; display: flex; flex-direction: column; gap: 14px;">\n <div style="display: flex; align-items: baseline; justify-content: space-between; gap: 12px;">\n <span style="font-size: 10px; letter-spacing: 0.12em; font-weight: 600;">PIPELINE</span>\n <span style="font-size: 10px; letter-spacing: 0.06em; opacity: 0.62;">stage by stage</span>\n </div>\n <div style="display: flex; flex-direction: column; gap: 11px;">\n <div>\n <div style="display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: 12px;"><span style="opacity: 0.75;">Applied</span><span style="font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums;">248</span></div>\n <div style="height: 4px; background: rgba(255,255,255,0.16); margin-top: 5px;"><div style="height: 4px; width: 100%; background: rgba(255,255,255,0.62);"></div></div>\n </div>\n <div>\n <div style="display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: 12px;"><span style="opacity: 0.75;">Documents in</span><span style="font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums;">193</span></div>\n <div style="height: 4px; background: rgba(255,255,255,0.16); margin-top: 5px;"><div style="height: 4px; width: 78%; background: rgba(255,255,255,0.62);"></div></div>\n </div>\n <div>\n <div style="display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: 12px;"><span style="opacity: 0.75;">Reviewed</span><span style="font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums;">152</span></div>\n <div style="height: 4px; background: rgba(255,255,255,0.16); margin-top: 5px;"><div style="height: 4px; width: 61%; background: var(--canvas-accent);"></div></div>\n </div>\n <div>\n <div style="display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: 12px;"><span style="opacity: 0.75;">Interviewed</span><span style="font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums;">67</span></div>\n <div style="height: 4px; background: rgba(255,255,255,0.16); margin-top: 5px;"><div style="height: 4px; width: 27%; background: rgba(255,255,255,0.62);"></div></div>\n </div>\n </div>\n <div style="margin-top: auto; border-top: 1px solid rgba(255,255,255,0.18); padding-top: 11px; font-size: 12px; opacity: 0.82;">41 files stalled at review</div>\n </div>\n </div>\n\n <div style="display: flex; align-items: center; gap: 8px;">\n <span style="font-size: 10px; letter-spacing: 0.12em; font-weight: 600; color: var(--canvas-muted); margin-right: 4px;">FACULTY</span>\n <span style="font-size: 12.5px; font-weight: 600; padding: 6px 12px; background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-fg);">All <span style="color: var(--canvas-muted); font-weight: 400;">12</span></span>\n <span style="font-size: 12.5px; padding: 6px 12px; background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));">Design <span style="color: var(--canvas-muted);">4</span></span>\n <span style="font-size: 12.5px; padding: 6px 12px; background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));">Business <span style="color: var(--canvas-muted);">5</span></span>\n <span style="font-size: 12.5px; padding: 6px 12px; background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border)); color: color-mix(in oklab, var(--canvas-fg) 82%, var(--canvas-bg));">Engineering <span style="color: var(--canvas-muted);">3</span></span>\n </div>\n\n <div style="background: var(--canvas-surface-1, var(--canvas-card)); border: 1px solid var(--canvas-hairline, var(--canvas-border));">\n <div style="padding: 13px 18px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); display: flex; align-items: baseline; justify-content: space-between; gap: 16px;">\n <span style="font-size: 14px; font-weight: 600;">Programmes needing attention</span>\n <span style="font-size: 12px; color: var(--canvas-muted);">4 of 12</span>\n </div>\n <div style="display: grid; grid-template-columns: 1.6fr 120px 84px 84px 92px; gap: 14px; padding: 9px 18px; background: var(--canvas-surface-2, var(--canvas-bg)); border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 10px; letter-spacing: 0.1em; font-weight: 600; color: var(--canvas-muted);">\n <span>PROGRAMME</span><span>REVIEW</span><span style="text-align: right;">APPLIED</span><span style="text-align: right;">OFFERS</span><span style="text-align: right;">WAITING</span>\n </div>\n <div style="display: grid; grid-template-columns: 1.6fr 120px 84px 84px 92px; gap: 14px; padding: 12px 18px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: center;">\n <span style="font-weight: 600;">MSc Product Design</span>\n <span style="height: 5px; background: var(--canvas-surface-2, var(--canvas-bg));"><span style="display: block; height: 5px; width: 38%; background: var(--canvas-accent);"></span></span>\n <span style="text-align: right; font-variant-numeric: tabular-nums;">31</span>\n <span style="text-align: right; font-variant-numeric: tabular-nums;">4</span>\n <span style="text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; color: var(--canvas-accent);">17</span>\n </div>\n <div style="display: grid; grid-template-columns: 1.6fr 120px 84px 84px 92px; gap: 14px; padding: 12px 18px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: center;">\n <span style="font-weight: 600;">MBA Sustainable Business</span>\n <span style="height: 5px; background: var(--canvas-surface-2, var(--canvas-bg));"><span style="display: block; height: 5px; width: 46%; background: var(--canvas-accent);"></span></span>\n <span style="text-align: right; font-variant-numeric: tabular-nums;">28</span>\n <span style="text-align: right; font-variant-numeric: tabular-nums;">6</span>\n <span style="text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; color: var(--canvas-accent);">13</span>\n </div>\n <div style="display: grid; grid-template-columns: 1.6fr 120px 84px 84px 92px; gap: 14px; padding: 12px 18px; border-bottom: 1px solid var(--canvas-hairline, var(--canvas-border)); font-size: 13px; align-items: center;">\n <span style="font-weight: 600;">MA Curation</span>\n <span style="height: 5px; background: var(--canvas-surface-2, var(--canvas-bg));"><span style="display: block; height: 5px; width: 71%; background: color-mix(in oklab, var(--canvas-fg) 32%, var(--canvas-bg));"></span></span>\n <span style="text-align: right; font-variant-numeric: tabular-nums;">19</span>\n <span style="text-align: right; font-variant-numeric: tabular-nums;">5</span>\n <span style="text-align: right; font-variant-numeric: tabular-nums;">7</span>\n </div>\n <div style="display: grid; grid-template-columns: 1.6fr 120px 84px 84px 92px; gap: 14px; padding: 12px 18px; font-size: 13px; align-items: center;">\n <span style="font-weight: 600;">MEng Robotics</span>\n <span style="height: 5px; background: var(--canvas-surface-2, var(--canvas-bg));"><span style="display: block; height: 5px; width: 83%; background: color-mix(in oklab, var(--canvas-fg) 32%, var(--canvas-bg));"></span></span>\n <span style="text-align: right; font-variant-numeric: tabular-nums;">24</span>\n <span style="text-align: right; font-variant-numeric: tabular-nums;">9</span>\n <span style="text-align: right; font-variant-numeric: tabular-nums;">4</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n```',
36
+ });