@brandon_m_behring/book-scaffold-astro 4.25.1 → 4.25.3
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/layouts/Base.astro +19 -3
- package/package.json +1 -1
- package/styles/chapter.css +26 -0
- package/styles/tokens.css +1 -0
- package/styles/typography.css +37 -0
package/layouts/Base.astro
CHANGED
|
@@ -16,10 +16,14 @@
|
|
|
16
16
|
* showSidebar — render the left chapter-navigation sidebar (default: true).
|
|
17
17
|
* Set false for the landing page or any full-bleed surface.
|
|
18
18
|
* Below 1024px the sidebar is auto-hidden via CSS regardless.
|
|
19
|
+
* showChrome — render the tools chrome (ToolFilter + VersionSelector)
|
|
20
|
+
* (default: true). Set false on a landing/hub page with no
|
|
21
|
+
* chapters/tools/versions; search + theme toggle always render.
|
|
19
22
|
*
|
|
20
23
|
* Tools chrome (ToolFilter, VersionSelector): only mounted when
|
|
21
|
-
* BOOK_PROFILE !== 'academic'. Academic-profile books
|
|
22
|
-
*
|
|
24
|
+
* BOOK_PROFILE !== 'academic' AND showChrome !== false. Academic-profile books
|
|
25
|
+
* (and any page with showChrome={false}) get no JS islands in the chrome row
|
|
26
|
+
* (search + theme toggle only).
|
|
23
27
|
*
|
|
24
28
|
* Usage:
|
|
25
29
|
* ---
|
|
@@ -61,13 +65,17 @@ import Sidebar from '../components/Sidebar.astro';
|
|
|
61
65
|
import bookConfig from 'virtual:book-scaffold/book-config';
|
|
62
66
|
|
|
63
67
|
const profile = import.meta.env.BOOK_PROFILE ?? 'minimal';
|
|
64
|
-
const showToolsChrome = profile !== 'academic';
|
|
65
68
|
|
|
66
69
|
interface Props {
|
|
67
70
|
title: string;
|
|
68
71
|
description?: string;
|
|
69
72
|
lang?: string;
|
|
70
73
|
showSidebar?: boolean;
|
|
74
|
+
/** #163: render the optional "tools chrome" — the ToolFilter +
|
|
75
|
+
* VersionSelector islands (default true). Set false on landing/hub pages
|
|
76
|
+
* with no chapters/tools/versions; the search + theme-toggle cluster always
|
|
77
|
+
* renders. (No-op for the academic profile, which never shows them.) */
|
|
78
|
+
showChrome?: boolean;
|
|
71
79
|
/** v4.6.0: Open Graph image URL (relative to site root, or absolute). */
|
|
72
80
|
ogImage?: string;
|
|
73
81
|
/** v4.6.0: Open Graph type. Defaults to 'website'; Chapter.astro passes 'article'. */
|
|
@@ -79,10 +87,18 @@ const {
|
|
|
79
87
|
description,
|
|
80
88
|
lang = 'en',
|
|
81
89
|
showSidebar = true,
|
|
90
|
+
showChrome = true,
|
|
82
91
|
ogImage,
|
|
83
92
|
ogType = 'website',
|
|
84
93
|
} = Astro.props;
|
|
85
94
|
|
|
95
|
+
// Tools chrome (ToolFilter + VersionSelector) renders only for non-academic
|
|
96
|
+
// profiles AND when the page opts in via showChrome (default true). A
|
|
97
|
+
// landing/hub page (no chapters/tools/versions) passes showChrome={false} to
|
|
98
|
+
// get the search + theme-toggle cluster only — the chrome-free path that
|
|
99
|
+
// previously forced borrowing the academic profile (and its katex deps). #163.
|
|
100
|
+
const showToolsChrome = (profile !== 'academic') && showChrome;
|
|
101
|
+
|
|
86
102
|
// v4.6.0: canonical + og:url need Astro.site. defineBookConfig throws at
|
|
87
103
|
// config-load if `site` is missing, so Astro.site is guaranteed populated
|
|
88
104
|
// here. `new URL` resolves the relative pathname against 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.25.
|
|
4
|
+
"version": "4.25.3",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "Brandon Behring",
|
package/styles/chapter.css
CHANGED
|
@@ -230,3 +230,29 @@
|
|
|
230
230
|
}
|
|
231
231
|
.chapter-nav .next { grid-column: 1; text-align: left; }
|
|
232
232
|
}
|
|
233
|
+
|
|
234
|
+
/* Display math (KaTeX) — scroll a too-wide equation WITHIN its own block instead
|
|
235
|
+
of forcing a horizontal scroll on the whole page. KaTeX sets no `overflow` on
|
|
236
|
+
`.katex-display`, so it defaults to `visible`; a wide equation (long
|
|
237
|
+
derivations, big matrices) then overflows the viewport and the page scrolls
|
|
238
|
+
sideways on mobile. WCAG 1.4.10 Reflow. See book-scaffold-astro#162.
|
|
239
|
+
overflow-y is deliberately NOT set: once overflow-x is non-visible the CSS
|
|
240
|
+
overflow rule already computes overflow-y to `auto`, so there is no spurious
|
|
241
|
+
vertical scrollbar — and an explicit `hidden` would silently clip tall
|
|
242
|
+
equations if a consumer ever constrains .katex-display's height. */
|
|
243
|
+
.katex-display {
|
|
244
|
+
overflow-x: auto;
|
|
245
|
+
/* a little room so the horizontal scrollbar doesn't clip the equation's descenders */
|
|
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;
|
|
258
|
+
}
|
package/styles/tokens.css
CHANGED
|
@@ -108,6 +108,7 @@
|
|
|
108
108
|
*/
|
|
109
109
|
--measure-main: 65ch; /* default: laptop-friendly typographic measure */
|
|
110
110
|
--measure-side: 28ch; /* right-margin sidenote column (desktop) */
|
|
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);
|