@brandon_m_behring/book-scaffold-astro 4.11.0 → 4.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +8 -1
- package/dist/schemas.mjs +8 -1
- package/layouts/Base.astro +7 -2
- package/package.json +1 -1
- package/pages/print.astro +2 -2
- package/pages/search.astro +2 -2
- package/recipes/06-mobile-first-layout.md +1 -1
- package/recipes/08-decisions-ledger.md +2 -0
- package/src/profiles/renderers/academic-chapters.ts +17 -2
- package/styles/tokens.css +3 -1
package/dist/index.mjs
CHANGED
|
@@ -368,6 +368,13 @@ var ACADEMIC_PART_ORDINAL = {
|
|
|
368
368
|
synthesis: 5
|
|
369
369
|
};
|
|
370
370
|
var UNKNOWN_PART_ORDINAL = 99;
|
|
371
|
+
var ACADEMIC_PART_LABEL = {
|
|
372
|
+
foundations: "Foundations",
|
|
373
|
+
"ssm-core": "SSM Core",
|
|
374
|
+
"beyond-ssm": "Beyond SSM",
|
|
375
|
+
integration: "Integration",
|
|
376
|
+
synthesis: "Synthesis"
|
|
377
|
+
};
|
|
371
378
|
function titleCase(part) {
|
|
372
379
|
return part.split("-").map((w) => w.length > 0 ? w.charAt(0).toUpperCase() + w.slice(1) : "").join(" ");
|
|
373
380
|
}
|
|
@@ -377,7 +384,7 @@ var academicChaptersRenderer = {
|
|
|
377
384
|
},
|
|
378
385
|
formatPartLabel(part) {
|
|
379
386
|
if (typeof part === "string" && part.length > 0) {
|
|
380
|
-
return titleCase(part);
|
|
387
|
+
return ACADEMIC_PART_LABEL[part] ?? titleCase(part);
|
|
381
388
|
}
|
|
382
389
|
return String(part);
|
|
383
390
|
},
|
package/dist/schemas.mjs
CHANGED
|
@@ -252,6 +252,13 @@ var ACADEMIC_PART_ORDINAL = {
|
|
|
252
252
|
synthesis: 5
|
|
253
253
|
};
|
|
254
254
|
var UNKNOWN_PART_ORDINAL = 99;
|
|
255
|
+
var ACADEMIC_PART_LABEL = {
|
|
256
|
+
foundations: "Foundations",
|
|
257
|
+
"ssm-core": "SSM Core",
|
|
258
|
+
"beyond-ssm": "Beyond SSM",
|
|
259
|
+
integration: "Integration",
|
|
260
|
+
synthesis: "Synthesis"
|
|
261
|
+
};
|
|
255
262
|
function titleCase(part) {
|
|
256
263
|
return part.split("-").map((w) => w.length > 0 ? w.charAt(0).toUpperCase() + w.slice(1) : "").join(" ");
|
|
257
264
|
}
|
|
@@ -261,7 +268,7 @@ var academicChaptersRenderer = {
|
|
|
261
268
|
},
|
|
262
269
|
formatPartLabel(part) {
|
|
263
270
|
if (typeof part === "string" && part.length > 0) {
|
|
264
|
-
return titleCase(part);
|
|
271
|
+
return ACADEMIC_PART_LABEL[part] ?? titleCase(part);
|
|
265
272
|
}
|
|
266
273
|
return String(part);
|
|
267
274
|
},
|
package/layouts/Base.astro
CHANGED
|
@@ -26,8 +26,13 @@
|
|
|
26
26
|
* import Base from '../layouts/Base.astro';
|
|
27
27
|
* ---
|
|
28
28
|
* <Base title="Chapter 1" description="...">
|
|
29
|
-
* <
|
|
29
|
+
* <article class="prose">...</article>
|
|
30
30
|
* </Base>
|
|
31
|
+
*
|
|
32
|
+
* Landmark ownership: Base emits the single `<main>` landmark for every
|
|
33
|
+
* page (both the sidebar and full-bleed branches below). Slotted content
|
|
34
|
+
* must NOT wrap itself in `<main>` — use `<article>` / `<section>` / `<div>`
|
|
35
|
+
* — or the page ends up with duplicate `<main>` landmarks (a11y, #91).
|
|
31
36
|
*/
|
|
32
37
|
import '@fontsource-variable/roboto';
|
|
33
38
|
import '@fontsource-variable/source-code-pro';
|
|
@@ -169,7 +174,7 @@ const ogDescription = description ?? bookConfig.description ?? '';
|
|
|
169
174
|
<main class="layout-main"><slot /></main>
|
|
170
175
|
</div>
|
|
171
176
|
) : (
|
|
172
|
-
<slot
|
|
177
|
+
<main><slot /></main>
|
|
173
178
|
)}
|
|
174
179
|
<script is:inline>
|
|
175
180
|
(function () {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brandon_m_behring/book-scaffold-astro",
|
|
3
3
|
"description": "Astro 6 + MDX toolkit for long-form technical books. Profile-aware (academic / tools / minimal); ships Tufte typography, KaTeX, BibTeX citations, Pagefind, Cloudflare Workers deploy. See PACKAGE_DESIGN.md for the API contract.",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.13.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "Brandon Behring",
|
package/pages/print.astro
CHANGED
|
@@ -36,12 +36,12 @@ const rendered = await Promise.all(
|
|
|
36
36
|
---
|
|
37
37
|
|
|
38
38
|
<Base title="Book (print edition)" description="Full book rendered as a single paginated document for PDF export.">
|
|
39
|
-
<
|
|
39
|
+
<div class="prose print-edition">
|
|
40
40
|
{rendered.map(({ entry, Content }) => (
|
|
41
41
|
<section class="chapter-print">
|
|
42
42
|
<ChapterHeader data={entry.data} />
|
|
43
43
|
<Content components={mdxComponents} />
|
|
44
44
|
</section>
|
|
45
45
|
))}
|
|
46
|
-
</
|
|
46
|
+
</div>
|
|
47
47
|
</Base>
|
package/pages/search.astro
CHANGED
|
@@ -19,7 +19,7 @@ import Base from '../layouts/Base.astro';
|
|
|
19
19
|
>
|
|
20
20
|
<link rel="stylesheet" href="/pagefind/pagefind-ui.css" slot="head" />
|
|
21
21
|
|
|
22
|
-
<
|
|
22
|
+
<div class="prose search-page">
|
|
23
23
|
<h1>Search</h1>
|
|
24
24
|
<p>
|
|
25
25
|
Full-text search runs in your browser. The index is generated at
|
|
@@ -27,7 +27,7 @@ import Base from '../layouts/Base.astro';
|
|
|
27
27
|
the page.
|
|
28
28
|
</p>
|
|
29
29
|
<div id="search"></div>
|
|
30
|
-
</
|
|
30
|
+
</div>
|
|
31
31
|
|
|
32
32
|
<script src="/pagefind/pagefind-ui.js" is:inline></script>
|
|
33
33
|
<script is:inline>
|
|
@@ -43,7 +43,7 @@ Re-tune with Playwright + `browser_take_screenshot` at the four viewports above
|
|
|
43
43
|
</Base>
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
Default is `showSidebar={true}`.
|
|
46
|
+
Default is `showSidebar={true}`. Set it false on full-bleed surfaces — landing pages, splash screens, search results — that have no chapter context (`Base.astro` still emits the page's single `<main>` landmark in that branch). Every chapter route inherits the default (true).
|
|
47
47
|
|
|
48
48
|
## Customizing the sidebar
|
|
49
49
|
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
The full master plan with discussion lives at `~/.claude/plans/i-want-to-investigate-recursive-yao.md`. The decisions ledger below is the operational summary.
|
|
8
8
|
|
|
9
|
+
> **Scaffold ledger vs. consumer decision log.** This file is the *scaffold's own* design ledger. Separately, since v4.12.0 (#90) `create-book` scaffolds every new book with a `decisions/` directory (numbered ADRs + `ADR_TEMPLATE.md` + `README.md`) so each book keeps its own decision log by construction. The two are independent: this ledger explains why the scaffold is shaped as it is; a book's `decisions/` explains why that book is shaped as it is.
|
|
10
|
+
|
|
9
11
|
## Strategic decisions (Round 1)
|
|
10
12
|
|
|
11
13
|
### D1. Canonical repo
|
|
@@ -28,7 +28,22 @@ const ACADEMIC_PART_ORDINAL: Record<string, number> = {
|
|
|
28
28
|
|
|
29
29
|
const UNKNOWN_PART_ORDINAL = 99;
|
|
30
30
|
|
|
31
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* Display labels for the academic-profile `part` enum. An explicit map (not
|
|
33
|
+
* naive title-casing) so acronyms render correctly: `ssm-core` → "SSM Core",
|
|
34
|
+
* not "Ssm Core" (#91). Keys mirror ACADEMIC_PART_ORDINAL; unknown/custom
|
|
35
|
+
* parts fall back to titleCase() in formatPartLabel.
|
|
36
|
+
*/
|
|
37
|
+
const ACADEMIC_PART_LABEL: Record<string, string> = {
|
|
38
|
+
foundations: 'Foundations',
|
|
39
|
+
'ssm-core': 'SSM Core',
|
|
40
|
+
'beyond-ssm': 'Beyond SSM',
|
|
41
|
+
integration: 'Integration',
|
|
42
|
+
synthesis: 'Synthesis',
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/** Title-case an enum string: "ssm-core" → "Ssm Core". Fallback for parts
|
|
46
|
+
* outside the known ACADEMIC_PART_LABEL map (e.g. consumer-custom parts). */
|
|
32
47
|
function titleCase(part: string): string {
|
|
33
48
|
return part
|
|
34
49
|
.split('-')
|
|
@@ -43,7 +58,7 @@ export const academicChaptersRenderer: ChaptersRenderer = {
|
|
|
43
58
|
|
|
44
59
|
formatPartLabel(part) {
|
|
45
60
|
if (typeof part === 'string' && part.length > 0) {
|
|
46
|
-
return titleCase(part);
|
|
61
|
+
return ACADEMIC_PART_LABEL[part] ?? titleCase(part);
|
|
47
62
|
}
|
|
48
63
|
return String(part);
|
|
49
64
|
},
|
package/styles/tokens.css
CHANGED
|
@@ -34,7 +34,9 @@
|
|
|
34
34
|
--color-bg: var(--paper);
|
|
35
35
|
--color-bg-subtle: var(--code-bg);
|
|
36
36
|
--color-text: var(--dark-text);
|
|
37
|
-
|
|
37
|
+
/* 65% clears WCAG AA on --paper (~5.4:1); 55% computed to ≈#807F7E ≈3.9:1, failing AA (#91).
|
|
38
|
+
color-mix re-resolves in the dark scope (cream over deep bg → higher contrast). */
|
|
39
|
+
--color-text-muted: color-mix(in srgb, var(--dark-text) 65%, var(--paper));
|
|
38
40
|
--color-border: var(--code-frame);
|
|
39
41
|
--color-link: var(--warm-blue);
|
|
40
42
|
--color-heading: var(--warm-blue);
|