@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.
@@ -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 get no JS islands
22
- * in the chrome row (search + theme toggle only).
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.1",
4
+ "version": "4.25.3",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "author": "Brandon Behring",
@@ -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 */
@@ -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);