@brandon_m_behring/book-scaffold-astro 4.26.0 → 4.26.2
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 +19 -6
- package/dist/index.mjs +22 -2
- package/dist/schemas.d.ts +1 -1
- package/dist/schemas.mjs +14 -2
- package/dist/{types-BO5qyDqT.d.ts → types-Hue-uSeQ.d.ts} +24 -0
- package/layouts/Base.astro +12 -0
- package/package.json +1 -1
- package/src/lib/define-style.ts +2 -0
- package/src/profiles/renderers/fallback-chapters.ts +3 -3
- package/src/profiles/renderers/research-portfolio-chapters.ts +26 -0
- package/src/profiles/research-portfolio.ts +4 -3
- package/styles/chapter.css +11 -0
- package/styles/tokens.css +1 -0
- package/styles/typography.css +37 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AstroUserConfig, AstroIntegration, MarkdownHeading } from 'astro';
|
|
2
|
-
import { c as BookConfigOptions, f as BookScaffoldIntegrationOptions, h as ChaptersRenderer, l as Style } from './types-
|
|
3
|
-
export { B as BOOK_PRESETS, a as BOOK_PROFILES, b as BookConfigError, d as BookPreset, e as BookProfile, g as BookSchemasOptions, C as ChapterFor, F as FreshnessAffordance, i as FrontmatterRouteConfig, P as PartKey, j as PartialRouteToggles, k as ProfileDefinition, R as RouteToggles, S as StatusBadge, m as StyleInput, V as VolatilityBadge, n as composeStyles, o as defineProfile, p as defineStyle, q as normalizeFrontmatterConfig, r as resolvePreset, s as resolveProfile } from './types-
|
|
2
|
+
import { c as BookConfigOptions, f as BookScaffoldIntegrationOptions, h as ChaptersRenderer, l as Style } from './types-Hue-uSeQ.js';
|
|
3
|
+
export { B as BOOK_PRESETS, a as BOOK_PROFILES, b as BookConfigError, d as BookPreset, e as BookProfile, g as BookSchemasOptions, C as ChapterFor, F as FreshnessAffordance, i as FrontmatterRouteConfig, P as PartKey, j as PartialRouteToggles, k as ProfileDefinition, R as RouteToggles, S as StatusBadge, m as StyleInput, V as VolatilityBadge, n as composeStyles, o as defineProfile, p as defineStyle, q as normalizeFrontmatterConfig, r as resolvePreset, s as resolveProfile } from './types-Hue-uSeQ.js';
|
|
4
4
|
import { E as volatilityLevels, c as academicParts, Q as Question } from './schemas-CKipJ5Ie.js';
|
|
5
5
|
export { A as AcademicChapter, B as BloomLevel, C as CourseNotesChapter, G as GlossaryTerm, M as MinimalChapter, P as Provenance, a as QuestionType, R as ResearchPortfolioChapter, T as ToolsChapter, b as academicChapterSchema, d as bloomLevels, e as changeKinds, f as changelogSchema, g as chapterStatus, h as citationBackstops, i as courseNotesChapterSchema, j as glossarySchema, l as layoutModes, m as minimalChapterSchema, p as patternCategories, k as patternsSchema, n as provenanceObject, o as provenanceSchema, q as questionDifficulties, r as questionSchema, s as questionTypes, t as refineQuestion, u as refinedQuestionSchema, v as researchPortfolioChapterSchema, w as sourceTiers, x as sourceTiersResearch, y as sourcesSchema, z as toolSlugs, D as toolsChapterSchema } from './schemas-CKipJ5Ie.js';
|
|
6
6
|
export { KIND_LABEL, ResolvedTheoremLabel, THEOREM_KINDS, TheoremKind, TheoremLabelProps, resolveTheoremNumber, theoremLabel } from './lib/theorem-label.js';
|
|
@@ -144,18 +144,31 @@ declare const academicChaptersRenderer: ChaptersRenderer;
|
|
|
144
144
|
|
|
145
145
|
/**
|
|
146
146
|
* src/profiles/renderers/fallback-chapters.ts — ChaptersRenderer used by
|
|
147
|
-
* profiles that don't ship a dedicated renderer (minimal, course-notes
|
|
148
|
-
*
|
|
147
|
+
* profiles that don't ship a dedicated renderer (minimal, course-notes).
|
|
148
|
+
* Dispatches by field presence — exactly the v3.5.2
|
|
149
149
|
* logic that lived inline in pages/chapters.astro before #35.
|
|
150
150
|
*
|
|
151
151
|
* Safety net for shapes we haven't designed for explicitly. If a consumer
|
|
152
|
-
* opts a course-notes
|
|
152
|
+
* opts a course-notes book into `routes.chapters: true`,
|
|
153
153
|
* the fallback renders reasonably without crashing. Custom output for those
|
|
154
154
|
* profiles is a v4+ extension point (consumer-overridable renderer).
|
|
155
155
|
*/
|
|
156
156
|
|
|
157
157
|
declare const fallbackChaptersRenderer: ChaptersRenderer;
|
|
158
158
|
|
|
159
|
+
/**
|
|
160
|
+
* Research-portfolio /chapters renderer.
|
|
161
|
+
*
|
|
162
|
+
* The portfolio schema intentionally permits numeric Parts through 20. The
|
|
163
|
+
* generic fallback renderer inherits the tools profile's historical
|
|
164
|
+
* `part >= 6` appendix convention, which mislabels a portfolio's sixth Part
|
|
165
|
+
* as "Appendices" and its chapters as Appendix a/b/.... Keep the fallback's
|
|
166
|
+
* field-shape dispatch for every other affordance, but make numeric Parts
|
|
167
|
+
* ordinary numbered Parts throughout the portfolio schema's full range.
|
|
168
|
+
*/
|
|
169
|
+
|
|
170
|
+
declare const researchPortfolioChaptersRenderer: ChaptersRenderer;
|
|
171
|
+
|
|
159
172
|
/**
|
|
160
173
|
* src/lib/academic-parts.ts — single source of truth for academic-profile
|
|
161
174
|
* part labels (#95).
|
|
@@ -598,4 +611,4 @@ type TipsConfigInput = Omit<TipsConfig, typeof TipsConfigBrand | '__tipsConfigVe
|
|
|
598
611
|
*/
|
|
599
612
|
declare function defineTips(opts: TipsConfigInput): TipsConfig;
|
|
600
613
|
|
|
601
|
-
export { ACADEMIC_PART_NAMES, BRANDON_PORTFOLIO_DEFAULT, BUILTIN_STYLES, BookConfigOptions, BookScaffoldIntegrationOptions, type ChapterLike, ChaptersRenderer, DEFAULT_GITHUB_BRANCH, type Freshness, type FreshnessStatus, type PartReviewGroup, type PartReviewSelection, Question, type ReviewChapter, type ReviewExercise, Style, type TipsConfig, type TipsConfigInput, UNKNOWN_PART_ORDINAL, type VisibleHeading, type VolatilityLevel, academicChaptersRenderer, academicPartHeading, academicPartName, academicPartOrdinal, academicParts, academicStyle, apparatusHref, assertEnumProp, assertKnownDomain, bookOf, bookScaffoldIntegration, buildGithubUrl, chapterHref, chapterLabel, chapterSortKey, courseNotesStyle, defineBookConfig, defineMdxComponents, defineTips, deriveObjectiveMap, distinctChaptersSorted, fallbackChaptersRenderer, freshnessLabel, getFreshness, groupByChapter, groupByDomain, isCurrentChapter, minimalStyle, originUrlFromGitConfig, parseRepoSlug, pickActive, researchPortfolioStyle, resolveBookHref, resolveGithubRepo, selectPartExercises, slugOf, sortQuestions, tocHeadings, toolsChaptersRenderer, toolsStyle, volatilityLevels };
|
|
614
|
+
export { ACADEMIC_PART_NAMES, BRANDON_PORTFOLIO_DEFAULT, BUILTIN_STYLES, BookConfigOptions, BookScaffoldIntegrationOptions, type ChapterLike, ChaptersRenderer, DEFAULT_GITHUB_BRANCH, type Freshness, type FreshnessStatus, type PartReviewGroup, type PartReviewSelection, Question, type ReviewChapter, type ReviewExercise, Style, type TipsConfig, type TipsConfigInput, UNKNOWN_PART_ORDINAL, type VisibleHeading, type VolatilityLevel, academicChaptersRenderer, academicPartHeading, academicPartName, academicPartOrdinal, academicParts, academicStyle, apparatusHref, assertEnumProp, assertKnownDomain, bookOf, bookScaffoldIntegration, buildGithubUrl, chapterHref, chapterLabel, chapterSortKey, courseNotesStyle, defineBookConfig, defineMdxComponents, defineTips, deriveObjectiveMap, distinctChaptersSorted, fallbackChaptersRenderer, freshnessLabel, getFreshness, groupByChapter, groupByDomain, isCurrentChapter, minimalStyle, originUrlFromGitConfig, parseRepoSlug, pickActive, researchPortfolioChaptersRenderer, researchPortfolioStyle, resolveBookHref, resolveGithubRepo, selectPartExercises, slugOf, sortQuestions, tocHeadings, toolsChaptersRenderer, toolsStyle, volatilityLevels };
|
package/dist/index.mjs
CHANGED
|
@@ -851,6 +851,17 @@ var courseNotesProfile = defineProfile({
|
|
|
851
851
|
sitemapFilter: (page) => !page.includes("/print/")
|
|
852
852
|
});
|
|
853
853
|
|
|
854
|
+
// src/profiles/renderers/research-portfolio-chapters.ts
|
|
855
|
+
var researchPortfolioChaptersRenderer = {
|
|
856
|
+
...fallbackChaptersRenderer,
|
|
857
|
+
formatPartLabel(part) {
|
|
858
|
+
return typeof part === "number" ? `Part ${part}` : fallbackChaptersRenderer.formatPartLabel(part);
|
|
859
|
+
},
|
|
860
|
+
isAppendix(_part) {
|
|
861
|
+
return false;
|
|
862
|
+
}
|
|
863
|
+
};
|
|
864
|
+
|
|
854
865
|
// src/profiles/research-portfolio.ts
|
|
855
866
|
var researchPortfolioProfile = defineProfile({
|
|
856
867
|
name: "research-portfolio",
|
|
@@ -883,8 +894,9 @@ var researchPortfolioProfile = defineProfile({
|
|
|
883
894
|
styles: ["tokens.css", "layout.css", "callouts.css", "chapter.css", "typography.css", "print.css", "section-map.css"],
|
|
884
895
|
katex: true,
|
|
885
896
|
// math is common in research content
|
|
886
|
-
//
|
|
887
|
-
|
|
897
|
+
// Portfolio schema is a union of academic + tools shapes, but unlike the
|
|
898
|
+
// tools profile its numeric Parts remain numbered through the schema max 20.
|
|
899
|
+
chaptersRenderer: researchPortfolioChaptersRenderer
|
|
888
900
|
});
|
|
889
901
|
|
|
890
902
|
// src/profiles/index.ts
|
|
@@ -1199,6 +1211,7 @@ function bookScaffoldIntegration(opts) {
|
|
|
1199
1211
|
// v4.5.0: landing-page data, propagated via virtual module to /index.astro.
|
|
1200
1212
|
title,
|
|
1201
1213
|
subtitle,
|
|
1214
|
+
releaseStatus,
|
|
1202
1215
|
description,
|
|
1203
1216
|
portfolio,
|
|
1204
1217
|
// v4.6.0: book-level author + SEO config, propagated through the
|
|
@@ -1268,6 +1281,7 @@ function bookScaffoldIntegration(opts) {
|
|
|
1268
1281
|
makeBookConfigVitePlugin({
|
|
1269
1282
|
title: title ?? null,
|
|
1270
1283
|
subtitle: subtitle ?? null,
|
|
1284
|
+
releaseStatus: releaseStatus ?? null,
|
|
1271
1285
|
description: description ?? null,
|
|
1272
1286
|
portfolio: portfolio ?? false,
|
|
1273
1287
|
enabledRoutes: enabledRouteNames,
|
|
@@ -1413,6 +1427,8 @@ async function defineBookConfig(opts) {
|
|
|
1413
1427
|
title: opts.title,
|
|
1414
1428
|
// v4.23.0 (#135): sidebar brand subtitle.
|
|
1415
1429
|
subtitle: opts.subtitle,
|
|
1430
|
+
// v4.27.0 (#149): release-state banner (top-level beats the style chain).
|
|
1431
|
+
releaseStatus: opts.releaseStatus ?? composed.releaseStatus,
|
|
1416
1432
|
description: opts.description,
|
|
1417
1433
|
portfolio: resolvedPortfolio,
|
|
1418
1434
|
// v4.6.0: book-level author + SEO config (ogImage, twitterHandle),
|
|
@@ -1470,6 +1486,8 @@ async function defineBookConfig(opts) {
|
|
|
1470
1486
|
// v4.5.0: strip new landing-related opts so they don't leak into AstroUserConfig.
|
|
1471
1487
|
title: _title,
|
|
1472
1488
|
subtitle: _subtitle,
|
|
1489
|
+
// v4.27.0 (#149): strip the release-state banner config.
|
|
1490
|
+
releaseStatus: _releaseStatus,
|
|
1473
1491
|
description: _description,
|
|
1474
1492
|
portfolio: _portfolio,
|
|
1475
1493
|
// v4.6.0: strip new book-level SEO opts (author + seo block).
|
|
@@ -1500,6 +1518,7 @@ async function defineBookConfig(opts) {
|
|
|
1500
1518
|
void _katexMacros;
|
|
1501
1519
|
void _title;
|
|
1502
1520
|
void _subtitle;
|
|
1521
|
+
void _releaseStatus;
|
|
1503
1522
|
void _description;
|
|
1504
1523
|
void _portfolio;
|
|
1505
1524
|
void _author;
|
|
@@ -1953,6 +1972,7 @@ export {
|
|
|
1953
1972
|
refineQuestion,
|
|
1954
1973
|
refinedQuestionSchema,
|
|
1955
1974
|
researchPortfolioChapterSchema,
|
|
1975
|
+
researchPortfolioChaptersRenderer,
|
|
1956
1976
|
researchPortfolioStyle,
|
|
1957
1977
|
resolveBookHref,
|
|
1958
1978
|
resolveGithubRepo,
|
package/dist/schemas.d.ts
CHANGED
package/dist/schemas.mjs
CHANGED
|
@@ -729,6 +729,17 @@ var courseNotesProfile = defineProfile({
|
|
|
729
729
|
sitemapFilter: (page) => !page.includes("/print/")
|
|
730
730
|
});
|
|
731
731
|
|
|
732
|
+
// src/profiles/renderers/research-portfolio-chapters.ts
|
|
733
|
+
var researchPortfolioChaptersRenderer = {
|
|
734
|
+
...fallbackChaptersRenderer,
|
|
735
|
+
formatPartLabel(part) {
|
|
736
|
+
return typeof part === "number" ? `Part ${part}` : fallbackChaptersRenderer.formatPartLabel(part);
|
|
737
|
+
},
|
|
738
|
+
isAppendix(_part) {
|
|
739
|
+
return false;
|
|
740
|
+
}
|
|
741
|
+
};
|
|
742
|
+
|
|
732
743
|
// src/profiles/research-portfolio.ts
|
|
733
744
|
var researchPortfolioProfile = defineProfile({
|
|
734
745
|
name: "research-portfolio",
|
|
@@ -761,8 +772,9 @@ var researchPortfolioProfile = defineProfile({
|
|
|
761
772
|
styles: ["tokens.css", "layout.css", "callouts.css", "chapter.css", "typography.css", "print.css", "section-map.css"],
|
|
762
773
|
katex: true,
|
|
763
774
|
// math is common in research content
|
|
764
|
-
//
|
|
765
|
-
|
|
775
|
+
// Portfolio schema is a union of academic + tools shapes, but unlike the
|
|
776
|
+
// tools profile its numeric Parts remain numbered through the schema max 20.
|
|
777
|
+
chaptersRenderer: researchPortfolioChaptersRenderer
|
|
766
778
|
});
|
|
767
779
|
|
|
768
780
|
// src/profiles/index.ts
|
|
@@ -379,6 +379,12 @@ interface Style {
|
|
|
379
379
|
* - `'pages'`: Cloudflare Pages (default for research-portfolio/course-notes)
|
|
380
380
|
* Closes #50. */
|
|
381
381
|
readonly deploy?: 'pages' | 'workers';
|
|
382
|
+
/** v4.27.0 (#149): release-state banner; shallow override (last wins). */
|
|
383
|
+
readonly releaseStatus?: {
|
|
384
|
+
state: 'alpha' | 'beta' | 'rc' | 'locked';
|
|
385
|
+
dismissAt?: string;
|
|
386
|
+
message?: string;
|
|
387
|
+
};
|
|
382
388
|
/**
|
|
383
389
|
* Scoped consumer-side metadata. Ignored by the toolkit; survives composition
|
|
384
390
|
* as per-key spread (last wins per key). Use this for workflow data that
|
|
@@ -600,6 +606,17 @@ interface BookConfigOptions {
|
|
|
600
606
|
* hardcoded both strings, so every consumer shipped the placeholder).
|
|
601
607
|
*/
|
|
602
608
|
subtitle?: string;
|
|
609
|
+
/**
|
|
610
|
+
* v4.27.0 (#149): book-level release state. When set, Base.astro renders
|
|
611
|
+
* the existing <PreReleaseBanner> site-wide (top of <body>) with these
|
|
612
|
+
* props — previously the banner was author-import-only, so auto-layout
|
|
613
|
+
* consumers (ssm-foundations) had no way to wire it. Omit for no banner.
|
|
614
|
+
*/
|
|
615
|
+
releaseStatus?: {
|
|
616
|
+
state: 'alpha' | 'beta' | 'rc' | 'locked';
|
|
617
|
+
dismissAt?: string;
|
|
618
|
+
message?: string;
|
|
619
|
+
};
|
|
603
620
|
/**
|
|
604
621
|
* v4.5.0: Book description. Read by the auto-injected `/` landing page (lead paragraph + <meta description>).
|
|
605
622
|
* Optional; landing renders no description paragraph if unset.
|
|
@@ -752,6 +769,13 @@ interface BookScaffoldIntegrationOptions {
|
|
|
752
769
|
/** v4.23.0 (#135): sidebar brand subtitle, propagated via the book-config
|
|
753
770
|
* virtual module to Sidebar.astro. */
|
|
754
771
|
subtitle?: string;
|
|
772
|
+
/** v4.27.0 (#149): release-state banner, propagated via the book-config
|
|
773
|
+
* virtual module; Base.astro renders <PreReleaseBanner> when set. */
|
|
774
|
+
releaseStatus?: {
|
|
775
|
+
state: 'alpha' | 'beta' | 'rc' | 'locked';
|
|
776
|
+
dismissAt?: string;
|
|
777
|
+
message?: string;
|
|
778
|
+
};
|
|
755
779
|
/** v4.5.0: book description, propagated to `/` landing via vite.define. */
|
|
756
780
|
description?: string;
|
|
757
781
|
/**
|
package/layouts/Base.astro
CHANGED
|
@@ -59,6 +59,8 @@ import '../styles/print.css';
|
|
|
59
59
|
import VersionSelector from '@brandon_m_behring/book-scaffold-astro/components/VersionSelector';
|
|
60
60
|
import ToolFilter from '@brandon_m_behring/book-scaffold-astro/components/ToolFilter';
|
|
61
61
|
import Sidebar from '../components/Sidebar.astro';
|
|
62
|
+
// v4.27.0 (#149): site-wide release-state banner, driven by defineBookConfig.
|
|
63
|
+
import PreReleaseBanner from '../components/PreReleaseBanner.astro';
|
|
62
64
|
// v4.26.0 (#80): the mobile/tablet drawer reuses the same book-scoped nav source.
|
|
63
65
|
import NavContent from '../components/NavContent.astro';
|
|
64
66
|
// v4.6.0: SEO meta tags read book-level identity (title fallback,
|
|
@@ -165,6 +167,16 @@ const baseUrl = (import.meta.env.BASE_URL ?? '/').replace(/\/*$/, '/');
|
|
|
165
167
|
<slot name="head" />
|
|
166
168
|
</head>
|
|
167
169
|
<body>
|
|
170
|
+
{/* v4.27.0 (#149): book-level release banner — first element in <body> so
|
|
171
|
+
every page (chapters, apparatus, landing) declares its state. Renders
|
|
172
|
+
only when defineBookConfig({ releaseStatus }) is set. */}
|
|
173
|
+
{bookConfig.releaseStatus && (
|
|
174
|
+
<PreReleaseBanner
|
|
175
|
+
state={bookConfig.releaseStatus.state}
|
|
176
|
+
dismissAt={bookConfig.releaseStatus.dismissAt}
|
|
177
|
+
message={bookConfig.releaseStatus.message}
|
|
178
|
+
/>
|
|
179
|
+
)}
|
|
168
180
|
<div class="chrome-buttons">
|
|
169
181
|
{/* v4.26.0 (#80): hamburger → mobile/tablet nav drawer. <a href="#nav-drawer">
|
|
170
182
|
so it opens via :target with no JS; the controller below enhances it. */}
|
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.26.
|
|
4
|
+
"version": "4.26.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "Brandon Behring",
|
package/src/lib/define-style.ts
CHANGED
|
@@ -123,6 +123,8 @@ export interface Style {
|
|
|
123
123
|
* - `'pages'`: Cloudflare Pages (default for research-portfolio/course-notes)
|
|
124
124
|
* Closes #50. */
|
|
125
125
|
readonly deploy?: 'pages' | 'workers';
|
|
126
|
+
/** v4.27.0 (#149): release-state banner; shallow override (last wins). */
|
|
127
|
+
readonly releaseStatus?: { state: 'alpha' | 'beta' | 'rc' | 'locked'; dismissAt?: string; message?: string };
|
|
126
128
|
|
|
127
129
|
/**
|
|
128
130
|
* Scoped consumer-side metadata. Ignored by the toolkit; survives composition
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* src/profiles/renderers/fallback-chapters.ts — ChaptersRenderer used by
|
|
3
|
-
* profiles that don't ship a dedicated renderer (minimal, course-notes
|
|
4
|
-
*
|
|
3
|
+
* profiles that don't ship a dedicated renderer (minimal, course-notes).
|
|
4
|
+
* Dispatches by field presence — exactly the v3.5.2
|
|
5
5
|
* logic that lived inline in pages/chapters.astro before #35.
|
|
6
6
|
*
|
|
7
7
|
* Safety net for shapes we haven't designed for explicitly. If a consumer
|
|
8
|
-
* opts a course-notes
|
|
8
|
+
* opts a course-notes book into `routes.chapters: true`,
|
|
9
9
|
* the fallback renders reasonably without crashing. Custom output for those
|
|
10
10
|
* profiles is a v4+ extension point (consumer-overridable renderer).
|
|
11
11
|
*/
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Research-portfolio /chapters renderer.
|
|
3
|
+
*
|
|
4
|
+
* The portfolio schema intentionally permits numeric Parts through 20. The
|
|
5
|
+
* generic fallback renderer inherits the tools profile's historical
|
|
6
|
+
* `part >= 6` appendix convention, which mislabels a portfolio's sixth Part
|
|
7
|
+
* as "Appendices" and its chapters as Appendix a/b/.... Keep the fallback's
|
|
8
|
+
* field-shape dispatch for every other affordance, but make numeric Parts
|
|
9
|
+
* ordinary numbered Parts throughout the portfolio schema's full range.
|
|
10
|
+
*/
|
|
11
|
+
import type { ChaptersRenderer } from '../../lib/chapters-renderer.js';
|
|
12
|
+
import { fallbackChaptersRenderer } from './fallback-chapters.js';
|
|
13
|
+
|
|
14
|
+
export const researchPortfolioChaptersRenderer: ChaptersRenderer = {
|
|
15
|
+
...fallbackChaptersRenderer,
|
|
16
|
+
|
|
17
|
+
formatPartLabel(part) {
|
|
18
|
+
return typeof part === 'number'
|
|
19
|
+
? `Part ${part}`
|
|
20
|
+
: fallbackChaptersRenderer.formatPartLabel(part);
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
isAppendix(_part) {
|
|
24
|
+
return false;
|
|
25
|
+
},
|
|
26
|
+
};
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
*/
|
|
23
23
|
import { defineProfile } from '../profile-kit.js';
|
|
24
24
|
import { researchPortfolioChapterSchema } from '../schemas.js';
|
|
25
|
-
import {
|
|
25
|
+
import { researchPortfolioChaptersRenderer } from './renderers/research-portfolio-chapters.js';
|
|
26
26
|
|
|
27
27
|
export type { ResearchPortfolioChapter } from '../schemas.js';
|
|
28
28
|
|
|
@@ -46,6 +46,7 @@ export const researchPortfolioProfile = defineProfile({
|
|
|
46
46
|
},
|
|
47
47
|
styles: ['tokens.css', 'layout.css', 'callouts.css', 'chapter.css', 'typography.css', 'print.css', 'section-map.css'],
|
|
48
48
|
katex: true, // math is common in research content
|
|
49
|
-
//
|
|
50
|
-
|
|
49
|
+
// Portfolio schema is a union of academic + tools shapes, but unlike the
|
|
50
|
+
// tools profile its numeric Parts remain numbered through the schema max 20.
|
|
51
|
+
chaptersRenderer: researchPortfolioChaptersRenderer,
|
|
51
52
|
});
|
package/styles/chapter.css
CHANGED
|
@@ -244,4 +244,15 @@
|
|
|
244
244
|
overflow-x: auto;
|
|
245
245
|
/* a little room so the horizontal scrollbar doesn't clip the equation's descenders */
|
|
246
246
|
padding-block-end: 0.25rem;
|
|
247
|
+
/* Edge scroll-shadow when a wide equation scrolls (v4.25.3; docs/responsive-reading.md).
|
|
248
|
+
* Same Lea Verou layered technique as code blocks, page-bg covers. */
|
|
249
|
+
background-image:
|
|
250
|
+
linear-gradient(to right, var(--color-bg) 30%, rgba(0, 0, 0, 0)),
|
|
251
|
+
linear-gradient(to right, rgba(0, 0, 0, 0), var(--color-bg) 70%),
|
|
252
|
+
radial-gradient(farthest-side at 0 50%, rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0)),
|
|
253
|
+
radial-gradient(farthest-side at 100% 50%, rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0));
|
|
254
|
+
background-position: 0 0, 100% 0, 0 0, 100% 0;
|
|
255
|
+
background-repeat: no-repeat;
|
|
256
|
+
background-size: 30px 100%, 30px 100%, 12px 100%, 12px 100%;
|
|
257
|
+
background-attachment: local, local, scroll, scroll;
|
|
247
258
|
}
|
package/styles/tokens.css
CHANGED
|
@@ -108,6 +108,7 @@
|
|
|
108
108
|
*/
|
|
109
109
|
--measure-main: 60ch; /* default: main+gutter fits beside the sidebar at ≥64rem (v4.26.0, #80) */
|
|
110
110
|
--measure-side: 20ch; /* right-margin sidenote / section-map column */
|
|
111
|
+
--measure-code: 48rem; /* code-block break-out width: fits 80-char lines comfortably (≈88 mono chars @14px before padding); docs/responsive-reading.md */
|
|
111
112
|
--breakpoint-narrow: 48rem; /* ~768px — mobile fold (sidenotes inline) */
|
|
112
113
|
--breakpoint-wide: 90rem; /* ~1440px — wide-desktop tier */
|
|
113
114
|
--breakpoint-ultrawide: 120rem; /* ~1920px — ultrawide tier */
|
package/styles/typography.css
CHANGED
|
@@ -89,6 +89,43 @@ pre code {
|
|
|
89
89
|
font-size: var(--text-sm);
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
/* ===== Responsive reading (v4.25.3) — docs/responsive-reading.md =====
|
|
93
|
+
* Code blocks break out past the prose text measure to fit ~80-char lines,
|
|
94
|
+
* capped at --measure-code and centered within .prose. CONTAINER-bounded, not
|
|
95
|
+
* viewport-bounded: the width comes from the .prose column itself, so a left
|
|
96
|
+
* sidebar offset + the scrollbar gutter can never push the block into horizontal
|
|
97
|
+
* PAGE scroll. (The earlier `width: min(100vw - …)` overflowed ~8px at the
|
|
98
|
+
* 1024px sidebar boundary — #171 review finding A1, guarded by
|
|
99
|
+
* gallery/tests/fixtures/layout-overflow.spec.ts.) `.wide`/`.column-page` keep
|
|
100
|
+
* their full-bleed behavior (excluded here). */
|
|
101
|
+
.prose > pre:not(.wide):not(.column-page) {
|
|
102
|
+
max-width: var(--measure-code);
|
|
103
|
+
margin-inline: auto;
|
|
104
|
+
/* Lea Verou layered scroll-shadow: bg-colored covers move with content
|
|
105
|
+
* (attachment:local); shadow layers are fixed → shown only when scrollable. */
|
|
106
|
+
background-image:
|
|
107
|
+
linear-gradient(to right, var(--color-code-bg) 30%, rgba(0, 0, 0, 0)),
|
|
108
|
+
linear-gradient(to right, rgba(0, 0, 0, 0), var(--color-code-bg) 70%),
|
|
109
|
+
radial-gradient(farthest-side at 0 50%, rgba(0, 0, 0, 0.18), rgba(0, 0, 0, 0)),
|
|
110
|
+
radial-gradient(farthest-side at 100% 50%, rgba(0, 0, 0, 0.18), rgba(0, 0, 0, 0));
|
|
111
|
+
background-position: 0 0, 100% 0, 0 0, 100% 0;
|
|
112
|
+
background-repeat: no-repeat;
|
|
113
|
+
background-size: 40px 100%, 40px 100%, 14px 100%, 14px 100%;
|
|
114
|
+
background-attachment: local, local, scroll, scroll;
|
|
115
|
+
}
|
|
116
|
+
/* Phone (≤40rem): shrink code a touch so more fits before scrolling. Tighter
|
|
117
|
+
* than the 48rem mobile/table breakpoint below — phones benefit from the smaller
|
|
118
|
+
* glyphs; tablets (40–48rem) keep the full size. */
|
|
119
|
+
@media (max-width: 40rem) {
|
|
120
|
+
pre code { font-size: 0.75rem; }
|
|
121
|
+
}
|
|
122
|
+
/* Mobile: scroll a wide table within its own block instead of overflowing the
|
|
123
|
+
* page. Sticky thead intentionally NOT used — it can't stick inside a
|
|
124
|
+
* horizontal-scroll wrapper (CSS limitation; see docs/responsive-reading.md). */
|
|
125
|
+
@media (max-width: 48rem) {
|
|
126
|
+
.prose table { display: block; max-width: 100%; overflow-x: auto; }
|
|
127
|
+
}
|
|
128
|
+
|
|
92
129
|
/* ===== Links ===== */
|
|
93
130
|
a {
|
|
94
131
|
color: var(--color-link);
|