@brandon_m_behring/book-scaffold-astro 4.4.0 → 4.5.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.d.ts CHANGED
@@ -1,8 +1,24 @@
1
1
  import { AstroUserConfig, AstroIntegration } from 'astro';
2
- import { c as BookConfigOptions, f as BookScaffoldIntegrationOptions, Q as volatilityLevels, h as ChaptersRenderer, n as Style } from './types-BhlCranN.js';
3
- export { A as AcademicChapter, B as BOOK_PRESETS, a as BOOK_PROFILES, b as BookConfigError, d as BookPreset, e as BookProfile, g as BookSchemasOptions, C as ChapterFor, i as CourseNotesChapter, F as FreshnessAffordance, j as FrontmatterRouteConfig, M as MinimalChapter, P as PartKey, k as PartialRouteToggles, l as ProfileDefinition, R as ResearchPortfolioChapter, m as RouteToggles, S as StatusBadge, o as StyleInput, T as ToolsChapter, V as VolatilityBadge, p as academicChapterSchema, q as academicParts, r as changeKinds, s as changelogSchema, t as chapterStatus, u as composeStyles, v as courseNotesChapterSchema, w as defineProfile, x as defineStyle, y as minimalChapterSchema, z as normalizeFrontmatterConfig, D as patternCategories, E as patternsSchema, G as researchPortfolioChapterSchema, H as resolvePreset, I as resolveProfile, J as sourceTiers, K as sourceTiersResearch, L as sourcesSchema, N as toolSlugs, O as toolsChapterSchema } from './types-BhlCranN.js';
2
+ import { c as BookConfigOptions, f as BookScaffoldIntegrationOptions, Q as volatilityLevels, h as ChaptersRenderer, n as Style } from './types-DLIpEgTm.js';
3
+ export { A as AcademicChapter, B as BOOK_PRESETS, a as BOOK_PROFILES, b as BookConfigError, d as BookPreset, e as BookProfile, g as BookSchemasOptions, C as ChapterFor, i as CourseNotesChapter, F as FreshnessAffordance, j as FrontmatterRouteConfig, M as MinimalChapter, P as PartKey, k as PartialRouteToggles, l as ProfileDefinition, R as ResearchPortfolioChapter, m as RouteToggles, S as StatusBadge, o as StyleInput, T as ToolsChapter, V as VolatilityBadge, p as academicChapterSchema, q as academicParts, r as changeKinds, s as changelogSchema, t as chapterStatus, u as composeStyles, v as courseNotesChapterSchema, w as defineProfile, x as defineStyle, y as minimalChapterSchema, z as normalizeFrontmatterConfig, D as patternCategories, E as patternsSchema, G as researchPortfolioChapterSchema, H as resolvePreset, I as resolveProfile, J as sourceTiers, K as sourceTiersResearch, L as sourcesSchema, N as toolSlugs, O as toolsChapterSchema } from './types-DLIpEgTm.js';
4
4
  import 'astro/zod';
5
5
 
6
+ /**
7
+ * v4.5.0: Default portfolio backlink baked into the scaffold. Rendered in
8
+ * the auto-injected `/` landing footer for every consumer that doesn't
9
+ * explicitly override `portfolio` in defineBookConfig.
10
+ *
11
+ * Single source of truth for the brandon-behring.dev URL across all
12
+ * consumers — update here, bump scaffold version, every consumer inherits
13
+ * on next build. This is the intentional Brandon-specific default
14
+ * discussed in plan §Phase 6-pre. Consumers outside the brandon-behring.dev
15
+ * ecosystem set `portfolio: false` (no link) or pass `{ url, label }` to
16
+ * override.
17
+ */
18
+ declare const BRANDON_PORTFOLIO_DEFAULT: {
19
+ readonly url: "https://brandon-behring.dev";
20
+ readonly label: "brandon-behring.dev";
21
+ };
6
22
  declare function defineBookConfig(opts: BookConfigOptions): Promise<AstroUserConfig>;
7
23
 
8
24
  declare function bookScaffoldIntegration(opts: BookScaffoldIntegrationOptions): AstroIntegration;
@@ -244,4 +260,4 @@ type TipsConfigInput = Omit<TipsConfig, typeof TipsConfigBrand | '__tipsConfigVe
244
260
  */
245
261
  declare function defineTips(opts: TipsConfigInput): TipsConfig;
246
262
 
247
- export { BUILTIN_STYLES, BookConfigOptions, BookScaffoldIntegrationOptions, ChaptersRenderer, type Freshness, type FreshnessStatus, Style, type TipsConfig, type TipsConfigInput, type VolatilityLevel, academicChaptersRenderer, academicStyle, bookScaffoldIntegration, chapterSortKey, courseNotesStyle, defineBookConfig, defineMdxComponents, defineTips, fallbackChaptersRenderer, freshnessLabel, getFreshness, minimalStyle, researchPortfolioStyle, toolsChaptersRenderer, toolsStyle, volatilityLevels };
263
+ export { BRANDON_PORTFOLIO_DEFAULT, BUILTIN_STYLES, BookConfigOptions, BookScaffoldIntegrationOptions, ChaptersRenderer, type Freshness, type FreshnessStatus, Style, type TipsConfig, type TipsConfigInput, type VolatilityLevel, academicChaptersRenderer, academicStyle, bookScaffoldIntegration, chapterSortKey, courseNotesStyle, defineBookConfig, defineMdxComponents, defineTips, fallbackChaptersRenderer, freshnessLabel, getFreshness, minimalStyle, researchPortfolioStyle, toolsChaptersRenderer, toolsStyle, volatilityLevels };
package/dist/index.mjs CHANGED
@@ -380,8 +380,10 @@ var academicProfile = defineProfile({
380
380
  // opt-in per book; see #7
381
381
  tips: false,
382
382
  // v4.3.0 #70: opt-in per book; requires build-tips
383
- exercises: false
383
+ exercises: false,
384
384
  // v4.4.0: opt-in per book; requires build-exercises
385
+ landing: true
386
+ // v4.5.0: auto-inject minimal root landing; consumers override via src/pages/index.astro
385
387
  },
386
388
  styles: ["tokens.css", "layout.css", "callouts.css", "chapter.css", "typography.css", "print.css"],
387
389
  katex: true,
@@ -498,8 +500,10 @@ var toolsProfile = defineProfile({
498
500
  // opt-in per book; see #7
499
501
  tips: false,
500
502
  // v4.3.0 #70: opt-in per book
501
- exercises: false
503
+ exercises: false,
502
504
  // v4.4.0: opt-in per book
505
+ landing: true
506
+ // v4.5.0: auto-inject minimal root landing
503
507
  },
504
508
  styles: [
505
509
  "tokens.css",
@@ -580,8 +584,10 @@ var minimalProfile = defineProfile({
580
584
  // opt-in per book; see #7
581
585
  tips: false,
582
586
  // v4.3.0 #70: opt-in per book
583
- exercises: false
587
+ exercises: false,
584
588
  // v4.4.0: opt-in per book
589
+ landing: true
590
+ // v4.5.0: auto-inject minimal root landing
585
591
  },
586
592
  styles: ["tokens.css", "layout.css", "callouts.css", "chapter.css", "typography.css", "print.css"],
587
593
  // v3.7.0 (#35): minimal aliases tools schema; fallback renderer field-dispatches if a consumer opts into routes.chapters
@@ -603,8 +609,10 @@ var courseNotesProfile = defineProfile({
603
609
  // opt-in per book; see #7
604
610
  tips: false,
605
611
  // v4.3.0 #70: opt-in per book
606
- exercises: false
612
+ exercises: false,
607
613
  // v4.4.0: opt-in per book
614
+ landing: true
615
+ // v4.5.0: auto-inject minimal root landing
608
616
  },
609
617
  styles: ["tokens.css", "layout.css", "callouts.css", "chapter.css", "typography.css", "print.css"],
610
618
  // v3.7.0 (#35): course-notes schema has tools-style fields (chapter, volatility, sources) — fallback renderer dispatches via tools renderer
@@ -627,8 +635,10 @@ var researchPortfolioProfile = defineProfile({
627
635
  // portfolios universally need title/disclosure/banner pages
628
636
  tips: false,
629
637
  // v4.3.0 #70: opt-in per book
630
- exercises: false
638
+ exercises: false,
631
639
  // v4.4.0: opt-in per book
640
+ landing: true
641
+ // v4.5.0: auto-inject minimal root landing
632
642
  },
633
643
  styles: ["tokens.css", "layout.css", "callouts.css", "chapter.css", "typography.css", "print.css"],
634
644
  katex: true,
@@ -833,6 +843,11 @@ var ROUTE_REGISTRY = {
833
843
  // v4.4.0: exercises index by chapter. Opt-in via routes.exercises: true;
834
844
  // pairs with build-exercises script + <ExerciseSolutions auto /> mode.
835
845
  exercises: { pattern: "/exercises", file: "exercises.astro" },
846
+ // v4.5.0: minimal root landing page. Reads title/description/portfolio/routes
847
+ // from vite.define-injected import.meta.env vars. Default-on per profile;
848
+ // consumers with their own src/pages/index.astro override (file-system route
849
+ // wins over injectRoute).
850
+ landing: { pattern: "/", file: "index.astro" },
836
851
  // v3.4.0 (#7): consumer-collection-backed frontmatter route. Opt-in via
837
852
  // routes: { frontmatter: true } AND content.config.ts defining the
838
853
  // collection (use frontmatterCollection() helper from /schemas subpath).
@@ -850,7 +865,16 @@ function resolvePage(file) {
850
865
  return fileURLToPath(new URL(`../pages/${file}`, import.meta.url));
851
866
  }
852
867
  function bookScaffoldIntegration(opts) {
853
- const { profile, routes: userOverrides = {}, extraStyles = [], mdxComponentsModule } = opts;
868
+ const {
869
+ profile,
870
+ routes: userOverrides = {},
871
+ extraStyles = [],
872
+ mdxComponentsModule,
873
+ // v4.5.0: landing-page data, propagated via vite.define to /index.astro.
874
+ title,
875
+ description,
876
+ portfolio
877
+ } = opts;
854
878
  const def = PROFILES[profile];
855
879
  const fmNormalized = normalizeFrontmatterConfig(userOverrides.frontmatter);
856
880
  const fmEnabled = fmNormalized?.enabled ?? def.routes.frontmatter;
@@ -891,12 +915,20 @@ function bookScaffoldIntegration(opts) {
891
915
  const consumerRoot = fileURLToPath(config.root);
892
916
  const resolvedMdxPath = resolveMdxComponentsPath(consumerRoot, mdxComponentsModule);
893
917
  const presetLiteral = JSON.stringify(profile);
918
+ const enabledRouteNames = Object.entries(enabledRoutes).filter(([, on]) => on).map(([name]) => name);
894
919
  updateConfig({
895
920
  vite: {
896
921
  plugins: [makeMdxComponentsVitePlugin(resolvedMdxPath)],
897
922
  define: {
898
923
  "import.meta.env.BOOK_PRESET": presetLiteral,
899
- "import.meta.env.BOOK_PROFILE": presetLiteral
924
+ "import.meta.env.BOOK_PROFILE": presetLiteral,
925
+ // v4.5.0: landing-page data. JSON.stringify on undefined → 'undefined'
926
+ // (which evaluates to JavaScript undefined at use site); on object →
927
+ // the JSON literal; on false → 'false'.
928
+ "import.meta.env.BOOK_TITLE": JSON.stringify(title ?? null),
929
+ "import.meta.env.BOOK_DESCRIPTION": JSON.stringify(description ?? null),
930
+ "import.meta.env.BOOK_PORTFOLIO": JSON.stringify(portfolio ?? null),
931
+ "import.meta.env.BOOK_ROUTES_ENABLED": JSON.stringify(enabledRouteNames)
900
932
  }
901
933
  }
902
934
  });
@@ -906,6 +938,10 @@ function bookScaffoldIntegration(opts) {
906
938
  }
907
939
 
908
940
  // src/config.ts
941
+ var BRANDON_PORTFOLIO_DEFAULT = {
942
+ url: "https://brandon-behring.dev",
943
+ label: "brandon-behring.dev"
944
+ };
909
945
  function v3MigrationError(opts) {
910
946
  const v3Value = opts.preset ?? opts.profile;
911
947
  const v3FieldUsed = "preset" in opts ? "preset" : "profile";
@@ -986,6 +1022,7 @@ async function defineBookConfig(opts) {
986
1022
  }
987
1023
  ]);
988
1024
  }
1025
+ const resolvedPortfolio = opts.portfolio === false ? false : opts.portfolio ?? BRANDON_PORTFOLIO_DEFAULT;
989
1026
  const integrations = [
990
1027
  mdx(),
991
1028
  preact(),
@@ -993,7 +1030,12 @@ async function defineBookConfig(opts) {
993
1030
  profile,
994
1031
  routes: mergedRoutes,
995
1032
  mdxComponentsModule,
996
- extraStyles: mergedExtraStyles
1033
+ extraStyles: mergedExtraStyles,
1034
+ // v4.5.0: pass landing-page data through to the integration so it can
1035
+ // be exposed to the auto-injected /index.astro via vite.define.
1036
+ title: opts.title,
1037
+ description: opts.description,
1038
+ portfolio: resolvedPortfolio
997
1039
  }),
998
1040
  ...mergedExtraIntegrations
999
1041
  ];
@@ -1028,6 +1070,10 @@ async function defineBookConfig(opts) {
1028
1070
  extraStyles: _extraStyles,
1029
1071
  markdown: _markdown,
1030
1072
  katexMacros: _katexMacros,
1073
+ // v4.5.0: strip new landing-related opts so they don't leak into AstroUserConfig.
1074
+ title: _title,
1075
+ description: _description,
1076
+ portfolio: _portfolio,
1031
1077
  ...rest
1032
1078
  } = opts;
1033
1079
  void _styles;
@@ -1039,6 +1085,9 @@ async function defineBookConfig(opts) {
1039
1085
  void _extraStyles;
1040
1086
  void _markdown;
1041
1087
  void _katexMacros;
1088
+ void _title;
1089
+ void _description;
1090
+ void _portfolio;
1042
1091
  const katexExternals = wantsKatex ? [] : ["remark-math", "rehype-katex", "katex"];
1043
1092
  const config = {
1044
1093
  site,
@@ -1115,6 +1164,7 @@ function defineTips(opts) {
1115
1164
  export {
1116
1165
  BOOK_PRESETS,
1117
1166
  BOOK_PROFILES,
1167
+ BRANDON_PORTFOLIO_DEFAULT,
1118
1168
  BUILTIN_STYLES,
1119
1169
  BookConfigError,
1120
1170
  academicChapterSchema,
package/dist/schemas.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { defineCollection } from 'astro:content';
2
- import { g as BookSchemasOptions } from './types-BhlCranN.js';
2
+ import { g as BookSchemasOptions } from './types-DLIpEgTm.js';
3
3
  import 'astro';
4
4
  import 'astro/zod';
5
5
 
package/dist/schemas.mjs CHANGED
@@ -265,8 +265,10 @@ var academicProfile = defineProfile({
265
265
  // opt-in per book; see #7
266
266
  tips: false,
267
267
  // v4.3.0 #70: opt-in per book; requires build-tips
268
- exercises: false
268
+ exercises: false,
269
269
  // v4.4.0: opt-in per book; requires build-exercises
270
+ landing: true
271
+ // v4.5.0: auto-inject minimal root landing; consumers override via src/pages/index.astro
270
272
  },
271
273
  styles: ["tokens.css", "layout.css", "callouts.css", "chapter.css", "typography.css", "print.css"],
272
274
  katex: true,
@@ -383,8 +385,10 @@ var toolsProfile = defineProfile({
383
385
  // opt-in per book; see #7
384
386
  tips: false,
385
387
  // v4.3.0 #70: opt-in per book
386
- exercises: false
388
+ exercises: false,
387
389
  // v4.4.0: opt-in per book
390
+ landing: true
391
+ // v4.5.0: auto-inject minimal root landing
388
392
  },
389
393
  styles: [
390
394
  "tokens.css",
@@ -465,8 +469,10 @@ var minimalProfile = defineProfile({
465
469
  // opt-in per book; see #7
466
470
  tips: false,
467
471
  // v4.3.0 #70: opt-in per book
468
- exercises: false
472
+ exercises: false,
469
473
  // v4.4.0: opt-in per book
474
+ landing: true
475
+ // v4.5.0: auto-inject minimal root landing
470
476
  },
471
477
  styles: ["tokens.css", "layout.css", "callouts.css", "chapter.css", "typography.css", "print.css"],
472
478
  // v3.7.0 (#35): minimal aliases tools schema; fallback renderer field-dispatches if a consumer opts into routes.chapters
@@ -488,8 +494,10 @@ var courseNotesProfile = defineProfile({
488
494
  // opt-in per book; see #7
489
495
  tips: false,
490
496
  // v4.3.0 #70: opt-in per book
491
- exercises: false
497
+ exercises: false,
492
498
  // v4.4.0: opt-in per book
499
+ landing: true
500
+ // v4.5.0: auto-inject minimal root landing
493
501
  },
494
502
  styles: ["tokens.css", "layout.css", "callouts.css", "chapter.css", "typography.css", "print.css"],
495
503
  // v3.7.0 (#35): course-notes schema has tools-style fields (chapter, volatility, sources) — fallback renderer dispatches via tools renderer
@@ -512,8 +520,10 @@ var researchPortfolioProfile = defineProfile({
512
520
  // portfolios universally need title/disclosure/banner pages
513
521
  tips: false,
514
522
  // v4.3.0 #70: opt-in per book
515
- exercises: false
523
+ exercises: false,
516
524
  // v4.4.0: opt-in per book
525
+ landing: true
526
+ // v4.5.0: auto-inject minimal root landing
517
527
  },
518
528
  styles: ["tokens.css", "layout.css", "callouts.css", "chapter.css", "typography.css", "print.css"],
519
529
  katex: true,
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.0",
4
+ "version": "4.5.0",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "author": "Brandon Behring",
@@ -0,0 +1,111 @@
1
+ ---
2
+ /**
3
+ * /index — minimal default landing page (v4.5.0).
4
+ *
5
+ * Auto-injected by bookScaffoldIntegration when routes.landing === true
6
+ * (default for every profile). Consumers with their own src/pages/index.astro
7
+ * override automatically — file-system routes win over injectRoute, no extra
8
+ * config needed.
9
+ *
10
+ * Reads book identity + portfolio + enabled-routes from vite.define-injected
11
+ * env vars (see integration.ts §4.5.0). Renders:
12
+ * - h1 with book title (fallback: 'book-scaffold-astro')
13
+ * - lead paragraph with description (omitted if not set)
14
+ * - "Read" list of links to enabled scaffold routes (filtered to only
15
+ * routes the integration actually injected; respects routes.<x>: false)
16
+ * - portfolio backlink in the footer (omitted if portfolio: false)
17
+ *
18
+ * Override paths:
19
+ * - Disable entirely: defineBookConfig({ routes: { landing: false } })
20
+ * - Compose differently: create src/pages/index.astro in your consumer
21
+ * repo (file wins; this page never renders)
22
+ * - Change portfolio target: defineBookConfig({ portfolio: { url, label } })
23
+ * or defineBookConfig({ portfolio: false })
24
+ */
25
+ import Base from '../layouts/Base.astro';
26
+
27
+ // Vite-injected at build time. JSON.stringify(value ?? null) is the
28
+ // integration's convention; null means "not set", an object/string means real value.
29
+ const title = (import.meta.env.BOOK_TITLE as string | null) ?? 'book-scaffold-astro';
30
+ const description = import.meta.env.BOOK_DESCRIPTION as string | null;
31
+ const portfolio = import.meta.env.BOOK_PORTFOLIO as { url: string; label: string } | false | null;
32
+ const enabledRoutes = (import.meta.env.BOOK_ROUTES_ENABLED as string[] | undefined) ?? [];
33
+
34
+ // Map from internal route name → display label + URL. Only routes that
35
+ // produce a single landing-list entry are listed here (frontmatter is a
36
+ // slug pattern; chaptersSlug is dynamic; landing IS this page).
37
+ const ROUTE_LABELS: Record<string, { label: string; href: string }> = {
38
+ chapters: { label: 'Chapters', href: '/chapters/' },
39
+ search: { label: 'Search', href: '/search/' },
40
+ references: { label: 'References', href: '/references/' },
41
+ print: { label: 'Print view', href: '/print/' },
42
+ convergence: { label: 'Convergence', href: '/convergence/' },
43
+ tips: { label: 'Tips', href: '/tips/' },
44
+ exercises: { label: 'Exercises', href: '/exercises/' },
45
+ };
46
+
47
+ const visibleRoutes = enabledRoutes
48
+ .filter((name) => name in ROUTE_LABELS)
49
+ .map((name) => ROUTE_LABELS[name]!);
50
+ ---
51
+
52
+ <Base title={title} description={description ?? undefined}>
53
+ <article class="prose landing">
54
+ <h1>{title}</h1>
55
+ {description && <p class="lead">{description}</p>}
56
+
57
+ {visibleRoutes.length > 0 && (
58
+ <>
59
+ <h2 class="read-heading">Read</h2>
60
+ <ul class="route-list">
61
+ {visibleRoutes.map((r) => (
62
+ <li><a href={r.href}>{r.label}</a></li>
63
+ ))}
64
+ </ul>
65
+ </>
66
+ )}
67
+
68
+ {portfolio && portfolio !== false && (
69
+ <p class="portfolio-footer">
70
+ <small>
71
+ Part of <a href={portfolio.url}>{portfolio.label}</a>
72
+ </small>
73
+ </p>
74
+ )}
75
+ </article>
76
+ </Base>
77
+
78
+ <style>
79
+ .landing {
80
+ max-width: 60ch;
81
+ margin: 2rem auto;
82
+ }
83
+ .lead {
84
+ font-size: 1.1rem;
85
+ line-height: 1.5;
86
+ margin: 1.25rem 0 2.5rem 0;
87
+ }
88
+ .read-heading {
89
+ font-size: 0.85rem;
90
+ text-transform: uppercase;
91
+ letter-spacing: 0.08em;
92
+ color: var(--color-text-muted, #555);
93
+ margin-top: 2.5rem;
94
+ margin-bottom: 0.75rem;
95
+ }
96
+ .route-list {
97
+ list-style: none;
98
+ padding: 0;
99
+ margin: 0;
100
+ }
101
+ .route-list li {
102
+ padding: 0.4rem 0;
103
+ font-family: var(--font-sans, sans-serif);
104
+ font-size: 1rem;
105
+ }
106
+ .portfolio-footer {
107
+ margin-top: 3rem;
108
+ color: var(--color-text-muted, #555);
109
+ font-family: var(--font-sans, sans-serif);
110
+ }
111
+ </style>
@@ -41,6 +41,16 @@ export interface RouteToggles {
41
41
  print: boolean;
42
42
  chapters: boolean;
43
43
  convergence: boolean;
44
+ /**
45
+ * v4.5.0: auto-inject a minimal `/` landing page that reads the book's
46
+ * `title`, `description`, and `portfolio` from defineBookConfig and
47
+ * renders a route list (filtered to enabled routes). Defaults to `true`
48
+ * on every profile. Consumers with their own `src/pages/index.astro` keep
49
+ * their custom landing (file-system routes win over `injectRoute`). Set
50
+ * to `false` to suppress the auto-injection entirely without writing
51
+ * a custom landing.
52
+ */
53
+ landing: boolean;
44
54
  /**
45
55
  * v3.4.0 (closes #7): auto-inject `/frontmatter/[slug]/` rendering a
46
56
  * consumer-defined `frontmatter` content collection. Default `false` per
@@ -25,6 +25,7 @@ export const academicProfile = defineProfile({
25
25
  frontmatter: false, // opt-in per book; see #7
26
26
  tips: false, // v4.3.0 #70: opt-in per book; requires build-tips
27
27
  exercises: false, // v4.4.0: opt-in per book; requires build-exercises
28
+ landing: true, // v4.5.0: auto-inject minimal root landing; consumers override via src/pages/index.astro
28
29
  },
29
30
  styles: ['tokens.css', 'layout.css', 'callouts.css', 'chapter.css', 'typography.css', 'print.css'],
30
31
  katex: true,
@@ -27,6 +27,7 @@ export const courseNotesProfile = defineProfile({
27
27
  frontmatter: false, // opt-in per book; see #7
28
28
  tips: false, // v4.3.0 #70: opt-in per book
29
29
  exercises: false, // v4.4.0: opt-in per book
30
+ landing: true, // v4.5.0: auto-inject minimal root landing
30
31
  },
31
32
  styles: ['tokens.css', 'layout.css', 'callouts.css', 'chapter.css', 'typography.css', 'print.css'],
32
33
  // v3.7.0 (#35): course-notes schema has tools-style fields (chapter, volatility, sources) — fallback renderer dispatches via tools renderer
@@ -22,6 +22,7 @@ export const minimalProfile = defineProfile({
22
22
  frontmatter: false, // opt-in per book; see #7
23
23
  tips: false, // v4.3.0 #70: opt-in per book
24
24
  exercises: false, // v4.4.0: opt-in per book
25
+ landing: true, // v4.5.0: auto-inject minimal root landing
25
26
  },
26
27
  styles: ['tokens.css', 'layout.css', 'callouts.css', 'chapter.css', 'typography.css', 'print.css'],
27
28
  // v3.7.0 (#35): minimal aliases tools schema; fallback renderer field-dispatches if a consumer opts into routes.chapters
@@ -38,6 +38,7 @@ export const researchPortfolioProfile = defineProfile({
38
38
  frontmatter: true, // portfolios universally need title/disclosure/banner pages
39
39
  tips: false, // v4.3.0 #70: opt-in per book
40
40
  exercises: false, // v4.4.0: opt-in per book
41
+ landing: true, // v4.5.0: auto-inject minimal root landing
41
42
  },
42
43
  styles: ['tokens.css', 'layout.css', 'callouts.css', 'chapter.css', 'typography.css', 'print.css'],
43
44
  katex: true, // math is common in research content
@@ -22,6 +22,7 @@ export const toolsProfile = defineProfile({
22
22
  frontmatter: false, // opt-in per book; see #7
23
23
  tips: false, // v4.3.0 #70: opt-in per book
24
24
  exercises: false, // v4.4.0: opt-in per book
25
+ landing: true, // v4.5.0: auto-inject minimal root landing
25
26
  },
26
27
  styles: [
27
28
  'tokens.css', 'layout.css', 'callouts.css', 'chapter.css',