@lukeashford/aurelius 4.4.0 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,5 +8,6 @@
8
8
  @import './fonts.css';
9
9
  @import './theme.css';
10
10
  @import './prose.css';
11
+ @import './deliverable.css';
11
12
 
12
13
  @plugin "@tailwindcss/typography";
@@ -0,0 +1,476 @@
1
+ /* Deliverable renderer styles.
2
+ *
3
+ * Each visual class is defined as a Tailwind v4 `@utility` so the design-system
4
+ * ESLint rule recognises them. The same DOM serves both the on-screen view
5
+ * and the PDF print path; `@page` and `@media print` rules below replace the
6
+ * dark theme with a print-friendly version (black on white, page-sized
7
+ * sections, no actions). The accent color is a CSS variable scoped to the
8
+ * deliverable root and falls back to the design-system gold.
9
+ */
10
+
11
+ @utility deliverable {
12
+ --deliverable-accent: var(--color-gold);
13
+
14
+ display: flex;
15
+ flex-direction: column;
16
+ gap: var(--spacing-16);
17
+ width: 100%;
18
+ max-width: var(--container-xl);
19
+ margin-inline: auto;
20
+ padding-inline: var(--spacing-6);
21
+ padding-block: var(--spacing-12);
22
+ color: var(--color-white);
23
+ font-family: var(--font-body);
24
+ }
25
+
26
+ @utility deliverable-page {
27
+ width: 100%;
28
+ }
29
+
30
+ @utility deliverable-heading {
31
+ font-family: var(--font-heading);
32
+ font-size: var(--text-3xl);
33
+ line-height: var(--text-3xl--line-height);
34
+ color: var(--deliverable-accent);
35
+ margin-bottom: var(--spacing-6);
36
+ letter-spacing: var(--letter-spacing-tight);
37
+ }
38
+
39
+ /* === Cover === */
40
+
41
+ @utility deliverable-cover {
42
+ min-height: min(80vh, 900px);
43
+ display: flex;
44
+ align-items: center;
45
+ justify-content: center;
46
+ text-align: center;
47
+ border: 1px solid color-mix(in oklab, var(--deliverable-accent) 30%, transparent);
48
+ background-color: var(--color-charcoal);
49
+ padding: var(--spacing-16);
50
+ }
51
+
52
+ @utility deliverable-cover-inner {
53
+ display: flex;
54
+ flex-direction: column;
55
+ gap: var(--spacing-6);
56
+ max-width: 56ch;
57
+ }
58
+
59
+ @utility deliverable-cover-eyebrow {
60
+ text-transform: uppercase;
61
+ letter-spacing: var(--letter-spacing-widest);
62
+ color: var(--color-silver);
63
+ font-size: var(--text-xs);
64
+ }
65
+
66
+ @utility deliverable-cover-title {
67
+ font-family: var(--font-heading);
68
+ font-size: var(--text-6xl);
69
+ line-height: var(--text-6xl--line-height);
70
+ color: var(--deliverable-accent);
71
+ letter-spacing: var(--letter-spacing-tight);
72
+ }
73
+
74
+ @utility deliverable-cover-subtitle {
75
+ font-size: var(--text-xl);
76
+ line-height: var(--text-xl--line-height);
77
+ color: var(--color-silver);
78
+ }
79
+
80
+ @utility deliverable-cover-client {
81
+ margin-top: var(--spacing-12);
82
+ font-size: var(--text-sm);
83
+ letter-spacing: var(--letter-spacing-wider);
84
+ text-transform: uppercase;
85
+ color: var(--color-silver);
86
+ }
87
+
88
+ @utility deliverable-cover-client-name {
89
+ color: var(--color-white);
90
+ font-weight: var(--font-weight-semibold);
91
+ }
92
+
93
+ /* === Image grid === */
94
+
95
+ @utility deliverable-image-grid {
96
+ display: grid;
97
+ gap: var(--spacing-6);
98
+ }
99
+
100
+ @utility deliverable-image-grid-cols-1 {
101
+ grid-template-columns: 1fr;
102
+ }
103
+
104
+ @utility deliverable-image-grid-cols-2 {
105
+ grid-template-columns: repeat(2, minmax(0, 1fr));
106
+ }
107
+
108
+ @utility deliverable-image-grid-cols-3 {
109
+ grid-template-columns: repeat(3, minmax(0, 1fr));
110
+ }
111
+
112
+ @utility deliverable-image-item {
113
+ display: flex;
114
+ flex-direction: column;
115
+ gap: var(--spacing-2);
116
+ break-inside: avoid;
117
+ }
118
+
119
+ @utility deliverable-image-img {
120
+ width: 100%;
121
+ height: 100%;
122
+ aspect-ratio: 4 / 3;
123
+ object-fit: cover;
124
+ background-color: var(--color-graphite);
125
+ border: 1px solid var(--color-ash);
126
+ }
127
+
128
+ @utility deliverable-image-missing {
129
+ aspect-ratio: 4 / 3;
130
+ display: flex;
131
+ align-items: center;
132
+ justify-content: center;
133
+ border: 1px dashed var(--color-ash);
134
+ color: var(--color-silver);
135
+ font-size: var(--text-sm);
136
+ }
137
+
138
+ @utility deliverable-image-caption {
139
+ font-size: var(--text-sm);
140
+ color: var(--color-silver);
141
+ line-height: var(--line-height-snug);
142
+ }
143
+
144
+ /* === Spotlight === */
145
+
146
+ @utility deliverable-spotlight-media {
147
+ margin-bottom: var(--spacing-6);
148
+ }
149
+
150
+ @utility deliverable-spotlight-img {
151
+ width: 100%;
152
+ max-height: 70vh;
153
+ object-fit: contain;
154
+ background-color: var(--color-graphite);
155
+ border: 1px solid var(--color-ash);
156
+ }
157
+
158
+ @utility deliverable-spotlight-missing {
159
+ width: 100%;
160
+ height: 50vh;
161
+ display: flex;
162
+ align-items: center;
163
+ justify-content: center;
164
+ border: 1px dashed var(--color-ash);
165
+ color: var(--color-silver);
166
+ }
167
+
168
+ @utility deliverable-spotlight-body {
169
+ max-width: 72ch;
170
+ font-size: var(--text-base);
171
+ line-height: var(--line-height-relaxed);
172
+ }
173
+
174
+ /* === Text block === */
175
+
176
+ @utility deliverable-text-block {
177
+ max-width: 72ch;
178
+ font-size: var(--text-base);
179
+ line-height: var(--line-height-relaxed);
180
+ }
181
+
182
+ /* === Color palette === */
183
+
184
+ @utility deliverable-palette {
185
+ display: grid;
186
+ grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
187
+ gap: var(--spacing-4);
188
+ }
189
+
190
+ @utility deliverable-palette-item {
191
+ display: flex;
192
+ flex-direction: column;
193
+ gap: var(--spacing-1);
194
+ align-items: center;
195
+ text-align: center;
196
+ break-inside: avoid;
197
+ }
198
+
199
+ @utility deliverable-palette-chip {
200
+ width: 100%;
201
+ aspect-ratio: 1 / 1;
202
+ border: 1px solid var(--color-ash);
203
+ }
204
+
205
+ @utility deliverable-palette-label {
206
+ font-size: var(--text-sm);
207
+ color: var(--color-white);
208
+ font-weight: var(--font-weight-medium);
209
+ }
210
+
211
+ @utility deliverable-palette-hex {
212
+ font-family: var(--font-mono);
213
+ font-size: var(--text-xs);
214
+ color: var(--color-silver);
215
+ }
216
+
217
+ /* === Quote === */
218
+
219
+ @utility deliverable-quote {
220
+ display: flex;
221
+ align-items: center;
222
+ justify-content: center;
223
+ min-height: 40vh;
224
+ }
225
+
226
+ @utility deliverable-quote-body {
227
+ max-width: 64ch;
228
+ font-family: var(--font-heading);
229
+ text-align: center;
230
+ }
231
+
232
+ @utility deliverable-quote-text {
233
+ font-size: var(--text-3xl);
234
+ line-height: var(--line-height-snug);
235
+ color: var(--color-white);
236
+ }
237
+
238
+ @utility deliverable-quote-attribution {
239
+ margin-top: var(--spacing-6);
240
+ font-family: var(--font-body);
241
+ font-size: var(--text-sm);
242
+ color: var(--color-silver);
243
+ letter-spacing: var(--letter-spacing-wider);
244
+ }
245
+
246
+ /* === Floating action bar === */
247
+
248
+ @utility deliverable-actions {
249
+ position: sticky;
250
+ bottom: var(--spacing-6);
251
+ display: flex;
252
+ justify-content: flex-end;
253
+ margin-top: var(--spacing-8);
254
+ pointer-events: none;
255
+ }
256
+
257
+ @utility deliverable-action-button {
258
+ pointer-events: auto;
259
+ }
260
+
261
+ /* === Print path ===
262
+ * Same React tree, different paint. The strategy:
263
+ * - Cover gets its own named page (`@page cover`) with no margins so it
264
+ * prints full-bleed, with the body running on default pages with
265
+ * normal margins.
266
+ * - Body sections flow naturally — only the cover forces a page break.
267
+ * `break-inside: avoid` on each block keeps headings with their content
268
+ * and stops grids from splitting awkwardly.
269
+ * - The palette and quote no longer claim a full page each — they were
270
+ * web-mode treatments, not print.
271
+ * - Running footer carries page numbers; the cover suppresses it via
272
+ * `@page :first`.
273
+ */
274
+
275
+ @page {
276
+ size: A4;
277
+ margin: 18mm 18mm 22mm;
278
+ @bottom-right {
279
+ content: counter(page);
280
+ font-family: var(--font-body);
281
+ font-size: 9pt;
282
+ color: var(--color-slate);
283
+ }
284
+ }
285
+
286
+ @page :first {
287
+ margin: 0;
288
+ @bottom-right {
289
+ content: none;
290
+ }
291
+ }
292
+
293
+ @media print {
294
+ .deliverable {
295
+ color: var(--color-obsidian);
296
+ padding: 0;
297
+ margin: 0;
298
+ max-width: none;
299
+ gap: 0;
300
+ font-size: 10.5pt;
301
+ line-height: var(--line-height-relaxed);
302
+ }
303
+
304
+ .deliverable-page {
305
+ /* Sections flow; break only when content needs more room. Avoid
306
+ splitting any single block across pages. */
307
+ page-break-inside: avoid;
308
+ break-inside: avoid;
309
+ margin-bottom: 14mm;
310
+ }
311
+
312
+ .deliverable-page + .deliverable-page {
313
+ margin-top: 0;
314
+ }
315
+
316
+ .deliverable-heading {
317
+ page-break-after: avoid;
318
+ break-after: avoid;
319
+ }
320
+
321
+ /* === Cover ===
322
+ * Full-bleed first page. The cover is always the first section, so
323
+ * `@page :first { margin: 0 }` lets it bleed; we still pad the content
324
+ * inside the cover so the type doesn't sit on the page edge.
325
+ */
326
+ .deliverable-cover {
327
+ page-break-after: always;
328
+ break-after: page;
329
+ background-color: var(--color-obsidian);
330
+ color: var(--color-white);
331
+ min-height: 297mm;
332
+ width: 210mm;
333
+ border: none;
334
+ padding: 36mm 28mm;
335
+ display: grid;
336
+ grid-template-rows: auto 1fr auto;
337
+ text-align: left;
338
+ }
339
+
340
+ .deliverable-cover-inner {
341
+ grid-row: 2;
342
+ align-self: end;
343
+ max-width: 28em;
344
+ }
345
+
346
+ .deliverable-cover-eyebrow {
347
+ color: var(--deliverable-accent);
348
+ font-size: 9pt;
349
+ }
350
+
351
+ .deliverable-cover-title {
352
+ font-size: 44pt;
353
+ line-height: 1.05;
354
+ color: var(--color-white);
355
+ }
356
+
357
+ .deliverable-cover-subtitle {
358
+ font-size: 13pt;
359
+ color: var(--color-silver);
360
+ margin-top: 2mm;
361
+ }
362
+
363
+ .deliverable-cover-client {
364
+ grid-row: 3;
365
+ margin-top: 0;
366
+ color: var(--color-silver);
367
+ }
368
+
369
+ .deliverable-cover-client-name {
370
+ color: var(--color-white);
371
+ }
372
+
373
+ /* === Body typography === */
374
+ .deliverable-heading {
375
+ font-size: 20pt;
376
+ margin-bottom: 4mm;
377
+ color: var(--deliverable-accent);
378
+ }
379
+
380
+ .deliverable-text-block,
381
+ .deliverable-spotlight-body {
382
+ font-size: 11pt;
383
+ line-height: 1.55;
384
+ max-width: 36em;
385
+ color: var(--color-obsidian);
386
+ }
387
+
388
+ /* === Image grid ===
389
+ * Tighter than on screen. Each item stays atomic; the grid can break
390
+ * between rows but not mid-cell.
391
+ */
392
+ .deliverable-image-grid {
393
+ gap: 4mm;
394
+ }
395
+
396
+ .deliverable-image-item {
397
+ page-break-inside: avoid;
398
+ break-inside: avoid;
399
+ }
400
+
401
+ .deliverable-image-img {
402
+ aspect-ratio: 4 / 3;
403
+ border: none;
404
+ }
405
+
406
+ .deliverable-image-caption {
407
+ color: var(--color-slate);
408
+ font-size: 9pt;
409
+ margin-top: 1.5mm;
410
+ }
411
+
412
+ /* === Spotlight === */
413
+ .deliverable-spotlight-img {
414
+ max-height: 140mm;
415
+ border: none;
416
+ background-color: transparent;
417
+ }
418
+
419
+ .deliverable-spotlight-media {
420
+ margin-bottom: 4mm;
421
+ }
422
+
423
+ /* === Palette ===
424
+ * Inline strip at body width — not a full-page chart. Smaller chips,
425
+ * label and hex below.
426
+ */
427
+ .deliverable-palette {
428
+ grid-template-columns: repeat(auto-fit, minmax(28mm, 1fr));
429
+ gap: 4mm;
430
+ max-width: 160mm;
431
+ }
432
+
433
+ .deliverable-palette-chip {
434
+ aspect-ratio: 1 / 1;
435
+ border: 1px solid var(--color-slate);
436
+ }
437
+
438
+ .deliverable-palette-label {
439
+ font-size: 10pt;
440
+ color: var(--color-obsidian);
441
+ margin-top: 2mm;
442
+ }
443
+
444
+ .deliverable-palette-hex {
445
+ font-size: 8pt;
446
+ color: var(--color-slate);
447
+ }
448
+
449
+ /* === Quote ===
450
+ * Editorial pull-quote, not a full page. Generous margins, no min-height
451
+ * heroics.
452
+ */
453
+ .deliverable-quote {
454
+ min-height: 0;
455
+ padding: 6mm 0 8mm;
456
+ }
457
+
458
+ .deliverable-quote-body {
459
+ max-width: 30em;
460
+ margin-inline: auto;
461
+ }
462
+
463
+ .deliverable-quote-text {
464
+ font-size: 18pt;
465
+ line-height: 1.3;
466
+ color: var(--color-obsidian);
467
+ }
468
+
469
+ .deliverable-quote-attribution {
470
+ color: var(--color-slate);
471
+ }
472
+
473
+ .deliverable-actions {
474
+ display: none;
475
+ }
476
+ }
package/llms.md CHANGED
@@ -127,7 +127,7 @@ Import from `@lukeashford/aurelius`:
127
127
  | List | variant, ordered, leading, trailing, interactive, selected, disabled, primary, secondary |
128
128
  | MarkdownContent | content, isMarkdown, sanitizeConfig, isStreaming, cursorClassName |
129
129
  | Menu | children, open, onOpenChange, asChild, align, side, icon, destructive |
130
- | Message | variant (user, assistant), content, isStreaming, branchInfo, actions, hideActions, attachments, onAttachmentOpen, onClick, label, children, disabled |
130
+ | Message | variant (user, assistant), content, isStreaming, branchInfo, actions, hideActions, attachments, onAttachmentOpen, onJumpHere, isActive, onClick, label, children, disabled |
131
131
  | Modal | isOpen, onClose, title, children, className |
132
132
  | Navbar | fixed, bordered, position, active, active |
133
133
  | Pagination | page, totalPages, onPageChange, siblingCount, showEdges |
@@ -156,7 +156,7 @@ Import from `@lukeashford/aurelius`:
156
156
  | ArtifactsPanel | nodes, loading, openArtifactId, onArtifactClosed, artifactCount, onExpand |
157
157
  | BranchNavigator | current, total, onPrevious, onNext, size, showIcon |
158
158
  | ChatInput | position (centered, bottom), placeholder, helperText, onSubmit, disabled, animate, isStreaming, onStop, attachments, onAttachmentsChange, onAttachmentRemove, showAttachmentButton, acceptedFileTypes, notice, onInputChange, initialInputValue, autoFocus |
159
- | ChatInterface | messages, conversationTree, onTreeChange, conversations, onMessageSubmit, onEditMessage, onRetryMessage, onJumpToCheckpoint, onJumpToLatest, onStop, onSelectConversation, onNewChat, onRenameConversation, isStreaming, isThinking, thinkingLabel, placeholder, emptyStateHelper, emptyState, showAttachmentButton, enableMessageActions, attachments, onAttachmentsChange, onAttachmentRemove, onAttachmentOpen, artifactNodes, isArtifactsPanelOpen, onArtifactsPanelOpenChange, tasks, tasksTitle, onStopAllTasks |
159
+ | ChatInterface | messages, conversationTree, onTreeChange, conversations, onMessageSubmit, onEditMessage, onRetryMessage, onJumpHere, onJumpToLatest, onStop, onSelectConversation, onNewChat, onRenameConversation, isStreaming, isThinking, thinkingLabel, placeholder, emptyStateHelper, emptyState, showAttachmentButton, enableMessageActions, attachments, onAttachmentsChange, onAttachmentRemove, onAttachmentOpen, artifactNodes, isArtifactsPanelOpen, onArtifactsPanelOpenChange, tasks, tasksTitle, onStopAllTasks |
160
160
  | ChatView | items, latestUserMessageIndex, isStreaming, isThinking, thinkingLabel, onScroll |
161
161
  | Checkpoint | name, executionKind (task, submit, rename, init, ingest), status (completed, failed, cancelled), isActive, muted, branchInfo, onJumpHere |
162
162
  | GreyedDivider | messageCount, checkpointCount, onJumpToLatest |
@@ -166,6 +166,13 @@ Import from `@lukeashford/aurelius`:
166
166
  | TodosList | tasks, title, onStopAllTasks |
167
167
  | ToolPanelContainer | topContent, bottomContent, width, initialTopPercent, onResizeStart, side |
168
168
  | ToolSidebar | tools, activeTools, onToggleTool, side |
169
+ | ArtifactImageGridSection | data |
170
+ | ArtifactSpotlightSection | data |
171
+ | ColorPaletteSection | data |
172
+ | CoverSection | data |
173
+ | DeliverableRenderer | deliverable, onDownloadPdf, hideActions, className |
174
+ | QuoteBlockSection | data |
175
+ | TextBlockSection | data |
169
176
  | ChatBubbleIcon | children |
170
177
  | CheckSquareIcon | children |
171
178
  | ChevronLeftIcon | children |
@@ -276,6 +283,8 @@ navigate for groups).
276
283
  - **hideActions**: * Whether to hide actions (e.g., during streaming)
277
284
  - **attachments**: * Attachments to render above the bubble. Used by user messages to show the files that were attached to that turn. Empty/undefined renders nothing.
278
285
  - **onAttachmentOpen**: * Click handler invoked with an attachment's `artifactId`. Wire to open the artifact-card modal in the host app.
286
+ - **onJumpHere**: * Click handler for the bubble — when provided, the message becomes a navigational anchor (mirrors Checkpoint's `onJumpHere`): clicking the bubble moves the active leaf to this node. Suppressed when `isActive` is true (already here) or when the user is selecting text or clicking a markdown link inside the bubble.
287
+ - **isActive**: * When true, this message is the active leaf — `onJumpHere` is suppressed (no point jumping to where you already are) and the affordance hover styling is skipped.
279
288
 
280
289
  **PdfCard**
281
290
  A card for displaying PDF documents with an embedded viewer.
@@ -447,7 +456,7 @@ artifactNodes prop.
447
456
  - **onMessageSubmit**: * Called when a message is submitted from the input. Provides the text content and any files attached.
448
457
  - **onEditMessage**: * Called when a user message is edited. In tree mode, this creates a new branch.
449
458
  - **onRetryMessage**: * Called when an assistant message is retried. In tree mode, this creates a new branch.
450
- - **onJumpToCheckpoint**: * Called when the user clicks a non-active checkpoint to rewind. Receives the checkpoint id; the consumer should move the active leaf there (without forking) so the artifacts panel and chat re-anchor. In tree mode only.
459
+ - **onJumpHere**: * Called when the user clicks a non-active node — checkpoint or message — to move the active leaf there. Receives the node id; the consumer should move the active leaf without forking so the artifacts panel and chat re-anchor. Mirrors the per-component `onJumpHere`. In tree mode only.
451
460
  - **onJumpToLatest**: * Called when the user clicks "Jump to latest" on the greyed-future divider or otherwise asks to return to the deepest leaf they had reached. In tree mode only.
452
461
  - **onStop**: * Called when the Stop button is clicked during assistant streaming.
453
462
  - **onSelectConversation**: * Called when a conversation is selected from the sidebar.
@@ -484,6 +493,8 @@ Key behaviors:
484
493
  - **ChatViewMessageItem.branchInfo**: Branch navigation info — chevrons render only when total > 1.
485
494
  - **ChatViewMessageItem.actions**: Actions configuration (copy / edit / retry).
486
495
  - **ChatViewMessageItem.muted**: When true, this row is rendered in the greyed-future region.
496
+ - **ChatViewMessageItem.isActive**: * When true, this message is the active leaf — Message will suppress its `onJumpHere` click target. Mirrors `ChatViewCheckpointItem.isActive`.
497
+ - **ChatViewMessageItem.onJumpHere**: * Click handler for the bubble. When provided, the bubble becomes a navigational anchor that moves the active leaf to this node. Aurelius suppresses the click for `isActive` rows, link / button targets inside the bubble, and active text selections.
487
498
  - **items**: * Rows to render in the chat stream. Heterogeneous: messages, checkpoints, and the greyed-future divider live in the same list, ordered top-to-bottom.
488
499
  - **latestUserMessageIndex**: * Index of the latest user-message row to anchor scroll to. When this index changes, the corresponding row scrolls to the top. Defaults to the last-found user message in `items`.
489
500
  - **isStreaming**: * Whether the assistant is currently streaming a response. Drives the streaming cursor on the last assistant message and the thinking indicator.
@@ -597,6 +608,50 @@ side of the chat interface. It follows the IntelliJ pattern:
597
608
  - **onToggleTool**: * Called when a tool button is clicked (toggle)
598
609
  - **side**: * Which side this sidebar is on — controls border direction
599
610
 
611
+ **ArtifactImageGridSection**
612
+ Grid of project artifact images with optional captions. The number of
613
+ columns is fixed by the spec (1–3); the renderer enforces a sensible aspect
614
+ ratio per item and lets the browser flow rows.
615
+
616
+
617
+ **ArtifactSpotlightSection**
618
+ A single hero artifact image with optional prose alongside. Reads at full
619
+ page width on screen and prints to a single page.
620
+
621
+
622
+ **ColorPaletteSection**
623
+ Color palette presented as labelled swatches with hex values.
624
+
625
+
626
+ **CoverSection**
627
+ Title page for a deliverable. Always rendered as the first section.
628
+
629
+
630
+ **DeliverableRenderer**
631
+ Render a presentable deliverable (moodboard, pitch deck) from a structured
632
+ spec. The same component drives the on-screen view and the print/PDF
633
+ version — `@media print` styles in `aurelius/styles/base.css` keep them in
634
+ sync. To produce a PDF, drive the page with headless Chromium and let the
635
+ print stylesheet do the work.
636
+
637
+ The renderer is purely presentational: it takes a fully resolved spec
638
+ (artifact URLs already inflated by the caller) and dispatches each section
639
+ to its typed sub-renderer. Unknown section types are skipped silently
640
+ forward-compat for new section variants added by the backend.
641
+
642
+ - **deliverable**: Resolved deliverable spec — every artifact reference already inflated.
643
+ - **onDownloadPdf**: * Called when the viewer requests a PDF download. The host application is responsible for fetching and triggering the file save (the URL knows about share tokens and credentials we don't). When omitted, the download affordance is hidden.
644
+ - **hideActions**: Hide the floating action bar entirely. Used when rendering for print.
645
+
646
+ **QuoteBlockSection**
647
+ Pulled quote with optional attribution. The renderer adds the surrounding
648
+ quotation marks.
649
+
650
+
651
+ **TextBlockSection**
652
+ Prose section. Body is rendered as Markdown.
653
+
654
+
600
655
  **CrossSquareIcon**
601
656
  - **variant**: * Visual variant for different states - 'cancelled': subtle ash coloring - 'failed': error red coloring
602
657
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lukeashford/aurelius",
3
- "version": "4.4.0",
3
+ "version": "4.6.0",
4
4
  "description": "Design system for Aurelius applications — A cohesive visual language for creative technologists",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -107,10 +107,12 @@ export function createAureliusESLintConfig(options = {}) {
107
107
  },
108
108
  },
109
109
 
110
- // CSS files: enforce Tailwind v4 CSS usage and tokens (exclude fonts.css and theme.css)
110
+ // CSS files: enforce Tailwind v4 CSS usage and tokens (exclude foundation
111
+ // sheets — fonts/theme/deliverable — which define the primitives the
112
+ // tokens rule would otherwise flag as hard-coded).
111
113
  {
112
114
  files: ['**/*.css'],
113
- ignores: ['**/fonts.css', '**/theme.css'],
115
+ ignores: ['**/fonts.css', '**/theme.css', '**/deliverable.css'],
114
116
  language: 'css/css',
115
117
  languageOptions: {
116
118
  customSyntax: tailwind4,