book-kit 0.0.0-stage → 0.6.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.
Files changed (139) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +72 -0
  3. package/README.md +251 -2
  4. package/bin/book-kit.js +115 -0
  5. package/commands/_emoji_io.py +32 -0
  6. package/commands/audit-chapter-lengths.js +244 -0
  7. package/commands/check-epub-size.js +68 -0
  8. package/commands/check-pdf-page-count.js +162 -0
  9. package/commands/composite-kindle-emoji.py +85 -0
  10. package/commands/composite-print-emoji.py +98 -0
  11. package/commands/conventions.js +76 -0
  12. package/commands/convert-pdfx.sh +194 -0
  13. package/commands/download-icc-profile.sh +105 -0
  14. package/commands/fonts.py +212 -0
  15. package/commands/generate-reference-docx.py +344 -0
  16. package/commands/kindle-fonts.js +173 -0
  17. package/commands/links-to-footnotes.js +366 -0
  18. package/commands/markdownlint.js +25 -0
  19. package/commands/minify-css.js +43 -0
  20. package/commands/optimize-images.js +73 -0
  21. package/commands/parity.sh +150 -0
  22. package/commands/postprocess-epub.js +541 -0
  23. package/commands/prep-print-src.js +77 -0
  24. package/commands/prose.js +38 -0
  25. package/commands/release-files.js +89 -0
  26. package/commands/reorder-print-frontmatter.js +79 -0
  27. package/commands/strip-page-rules.js +1168 -0
  28. package/commands/strip-property-rules.js +93 -0
  29. package/commands/update-key-takeaways.js +314 -0
  30. package/commands/validate.js +283 -0
  31. package/configs/markdownlint-cli2.jsonc +98 -0
  32. package/configs/textlintrc.json +22 -0
  33. package/css/theme/01-tokens.css +83 -0
  34. package/css/theme/02-fonts.css +79 -0
  35. package/css/theme/03-prose.css +53 -0
  36. package/css/theme/04-base.css +226 -0
  37. package/css/theme/05-components.css +546 -0
  38. package/css/theme/06-utilities.css +40 -0
  39. package/css/theme/07-ereader.css +245 -0
  40. package/css/theme/08-epub.css +865 -0
  41. package/css/theme/09-back-matter.css +47 -0
  42. package/css/theme/10-dark.css +302 -0
  43. package/css/theme/11-print.css +1229 -0
  44. package/css/theme.css +38 -0
  45. package/defaults/book.config.yml +318 -0
  46. package/defaults/pandoc-base.yml +19 -0
  47. package/defaults/pandoc-docx.yml +6 -0
  48. package/defaults/pandoc-epub-fonts.yml +6 -0
  49. package/defaults/pandoc-epub.yml +15 -0
  50. package/defaults/pandoc-kindle.yml +6 -0
  51. package/emoji/1f382.png +0 -0
  52. package/emoji/1f389.png +0 -0
  53. package/emoji/1f440.png +0 -0
  54. package/emoji/1f44d.png +0 -0
  55. package/emoji/1f44f.png +0 -0
  56. package/emoji/1f454.png +0 -0
  57. package/emoji/1f4a1.png +0 -0
  58. package/emoji/1f4bb.png +0 -0
  59. package/emoji/1f602.png +0 -0
  60. package/emoji/1f603.png +0 -0
  61. package/emoji/1f604.png +0 -0
  62. package/emoji/1f60a.png +0 -0
  63. package/emoji/1f60f.png +0 -0
  64. package/emoji/1f64c.png +0 -0
  65. package/emoji/1f64f.png +0 -0
  66. package/emoji/1f914.png +0 -0
  67. package/emoji/1f923.png +0 -0
  68. package/emoji/2714.png +0 -0
  69. package/emoji/274c.png +0 -0
  70. package/filters/add-div-titles.lua +196 -0
  71. package/filters/arc-notice.lua +36 -0
  72. package/filters/body-emoji-images.lua +48 -0
  73. package/filters/callout-classes.lua +40 -0
  74. package/filters/lib/book_kit.lua +110 -0
  75. package/filters/revision.lua +17 -0
  76. package/filters/strip-comments.lua +40 -0
  77. package/filters/strip-emoji-kindle.lua +134 -0
  78. package/fonts/LICENSE-source-code-pro.md +93 -0
  79. package/fonts/LICENSE-source-sans.md +93 -0
  80. package/fonts/LICENSE-source-serif.md +93 -0
  81. package/fonts/recipe.json +41 -0
  82. package/just/book-kit.just +229 -0
  83. package/lib/acronyms.js +47 -0
  84. package/lib/callouts.js +17 -0
  85. package/lib/config.js +211 -0
  86. package/lib/is-main.js +21 -0
  87. package/lib/lint.js +148 -0
  88. package/lib/pandoc.js +148 -0
  89. package/lib/paragraphs.js +173 -0
  90. package/lib/revision.js +35 -0
  91. package/lib/structure.js +39 -0
  92. package/lib/textlint-github-formatter.js +58 -0
  93. package/lib/validate.js +202 -0
  94. package/package.json +98 -4
  95. package/presets/business-nonfiction/CONVENTIONS.md +35 -0
  96. package/presets/business-nonfiction/preset.yml +128 -0
  97. package/profiles/pdfx-def.ps +42 -0
  98. package/requirements.txt +14 -0
  99. package/rules/no-ai-like-patterns.js +209 -0
  100. package/rules/no-assumptive.js +76 -0
  101. package/rules/no-bare-acronyms.js +129 -0
  102. package/rules/no-cliches.js +544 -0
  103. package/rules/no-cultural-idioms.js +422 -0
  104. package/rules/no-vague-intensifiers.js +94 -0
  105. package/templates/template-epub.html +79 -0
  106. package/templates/template.html +73 -0
  107. package/toolchain.json +42 -0
  108. package/validators/acronym-expansion.js +94 -0
  109. package/validators/bold-keywords.js +56 -0
  110. package/validators/callout-balance.js +74 -0
  111. package/validators/callout-divs.js +66 -0
  112. package/validators/callout-labels.js +102 -0
  113. package/validators/chapter-lengths.js +14 -0
  114. package/validators/chapter.js +57 -0
  115. package/validators/cross-references.js +45 -0
  116. package/validators/doubled-words.js +76 -0
  117. package/validators/duplicate-headings.js +52 -0
  118. package/validators/em-dashes.js +73 -0
  119. package/validators/escaped-smallcaps.js +46 -0
  120. package/validators/footnotes.js +78 -0
  121. package/validators/heading-hierarchy.js +58 -0
  122. package/validators/hypothetical-hooks.js +103 -0
  123. package/validators/index-integrity.js +28 -0
  124. package/validators/index.js +73 -0
  125. package/validators/list-punctuation.js +123 -0
  126. package/validators/min-opener-length.js +87 -0
  127. package/validators/no-bare-url-link-text.js +38 -0
  128. package/validators/no-todo-markers.js +49 -0
  129. package/validators/no-transition-todos.js +34 -0
  130. package/validators/number-range-dashes.js +72 -0
  131. package/validators/paragraph-length.js +62 -0
  132. package/validators/quote-punctuation.js +85 -0
  133. package/validators/section-intro-final-lead.js +90 -0
  134. package/validators/section-intro-has-lead.js +41 -0
  135. package/validators/section-intro-no-tldr.js +37 -0
  136. package/validators/section-intros.js +33 -0
  137. package/validators/sentence-starters.js +132 -0
  138. package/validators/smallcaps.js +67 -0
  139. package/validators/tldr-length.js +58 -0
@@ -0,0 +1,1229 @@
1
+ /* ============================================
2
+ PRINT STYLES — KDP Paperback & IngramSpark
3
+ Rendered by WeasyPrint into PDF.
4
+
5
+ Key constraints:
6
+ • WeasyPrint ignores variable font-weight ranges
7
+ → explicit @font-face for weights 400/700
8
+ • calc() supported in WeasyPrint 67+ (no longer a limitation)
9
+ • float:footnote for page-bottom notes (CSS Paged Media)
10
+ • string-set for dynamic running headers
11
+ • B&W interior: colors must be grayscale-friendly
12
+ • 6"×9" trim, 1" gutter, 0.75" outside margins
13
+ ============================================ */
14
+
15
+ /* Print @font-face — Explicit Weight Declarations
16
+ WeasyPrint ignores variable font-weight ranges (e.g., 200 900),
17
+ so we redeclare each family × style × weight explicitly for print.
18
+ Same variable WOFF2 files — WeasyPrint selects the correct weight
19
+ instance from the variable font when given exact font-weight values. */
20
+ @media print {
21
+ /* Source Serif 4 — Body text */
22
+ @font-face {
23
+ font-family: "Source Serif 4";
24
+ font-style: normal;
25
+ font-weight: 400;
26
+ src: url("../fonts/SourceSerif4-Variable-Latin.woff2") format("woff2");
27
+ }
28
+ @font-face {
29
+ font-family: "Source Serif 4";
30
+ font-style: normal;
31
+ font-weight: 700;
32
+ src: url("../fonts/SourceSerif4-Variable-Latin.woff2") format("woff2");
33
+ }
34
+ @font-face {
35
+ font-family: "Source Serif 4";
36
+ font-style: italic;
37
+ font-weight: 400;
38
+ src: url("../fonts/SourceSerif4-Italic-Variable-Latin.woff2")
39
+ format("woff2");
40
+ }
41
+ @font-face {
42
+ font-family: "Source Serif 4";
43
+ font-style: italic;
44
+ font-weight: 700;
45
+ src: url("../fonts/SourceSerif4-Italic-Variable-Latin.woff2")
46
+ format("woff2");
47
+ }
48
+ @font-face {
49
+ font-family: "Source Serif 4 NotEqual";
50
+ font-style: normal;
51
+ font-weight: 400;
52
+ src: url("../fonts/SourceSerif4-NotEqual.woff2") format("woff2");
53
+ }
54
+ @font-face {
55
+ font-family: "Source Serif 4 NotEqual";
56
+ font-style: normal;
57
+ font-weight: 700;
58
+ src: url("../fonts/SourceSerif4-NotEqual.woff2") format("woff2");
59
+ }
60
+ @font-face {
61
+ font-family: "Source Serif 4 NotEqual";
62
+ font-style: italic;
63
+ font-weight: 400;
64
+ src: url("../fonts/SourceSerif4-Italic-NotEqual.woff2") format("woff2");
65
+ }
66
+ @font-face {
67
+ font-family: "Source Serif 4 NotEqual";
68
+ font-style: italic;
69
+ font-weight: 700;
70
+ src: url("../fonts/SourceSerif4-Italic-NotEqual.woff2") format("woff2");
71
+ }
72
+
73
+ /* Source Sans 3 — Headings */
74
+ @font-face {
75
+ font-family: "Source Sans 3";
76
+ font-style: normal;
77
+ font-weight: 400;
78
+ src: url("../fonts/SourceSans3-Variable-Latin.woff2") format("woff2");
79
+ }
80
+ @font-face {
81
+ font-family: "Source Sans 3";
82
+ font-style: normal;
83
+ font-weight: 700;
84
+ src: url("../fonts/SourceSans3-Variable-Latin.woff2") format("woff2");
85
+ }
86
+ @font-face {
87
+ font-family: "Source Sans 3";
88
+ font-style: italic;
89
+ font-weight: 400;
90
+ src: url("../fonts/SourceSans3-Italic-Variable-Latin.woff2") format("woff2");
91
+ }
92
+ @font-face {
93
+ font-family: "Source Sans 3";
94
+ font-style: italic;
95
+ font-weight: 700;
96
+ src: url("../fonts/SourceSans3-Italic-Variable-Latin.woff2") format("woff2");
97
+ }
98
+
99
+ /* Source Code Pro — Code */
100
+ @font-face {
101
+ font-family: "Source Code Pro";
102
+ font-style: normal;
103
+ font-weight: 400;
104
+ src: url("../fonts/SourceCodePro-Variable-Latin.woff2") format("woff2");
105
+ }
106
+ @font-face {
107
+ font-family: "Source Code Pro";
108
+ font-style: normal;
109
+ font-weight: 700;
110
+ src: url("../fonts/SourceCodePro-Variable-Latin.woff2") format("woff2");
111
+ }
112
+ }
113
+
114
+ @media print {
115
+ /* Print Page Layout — KDP Paperback (6×9" Trim)
116
+ =============================================
117
+ Amazon KDP minimum inside (gutter) margins by page count:
118
+ 24–150 pp → 0.375" 151–300 pp → 0.500"
119
+ 301–500 pp → 0.625" 501–700 pp → 0.750"
120
+ 701+ pp → 0.875"
121
+ The theme's 1" inside margin clears every tier, so a book can grow or
122
+ shrink without a margin change, and it leaves generous reading space.
123
+ Outside/top/bottom: 0.75" (KDP minimum is ~0.25").
124
+ See: https://kdp.amazon.com/en_US/help/topic/G201834180 */
125
+ @page {
126
+ size: 6in 9in;
127
+ margin: 0.75in 0.75in 0.75in 1in;
128
+
129
+ @footnote {
130
+ border-top: 0.75pt solid #999;
131
+ padding-top: 8pt;
132
+ margin-top: 8pt;
133
+ }
134
+ }
135
+
136
+ /* Page footnotes — the Lua filter converts pandoc Notes to inline
137
+ <span class="fn-inline"> elements. CSS float:footnote moves them
138
+ to the @footnote area at page bottom. Superscript markers are
139
+ auto-generated by ::footnote-call / ::footnote-marker. */
140
+ .fn-inline {
141
+ float: footnote;
142
+ font-size: 9pt;
143
+ line-height: 1.35;
144
+ color: #333;
145
+ text-align: left;
146
+ word-wrap: break-word;
147
+ overflow-wrap: anywhere;
148
+ }
149
+
150
+ ::footnote-call {
151
+ font-size: 0.8em;
152
+ vertical-align: super;
153
+ line-height: 0;
154
+ font-variant-numeric: lining-nums;
155
+ }
156
+
157
+ ::footnote-marker {
158
+ font-weight: normal;
159
+ font-variant-numeric: lining-nums tabular-nums;
160
+ }
161
+
162
+ @page :first {
163
+ @top-left {
164
+ content: none;
165
+ }
166
+ @top-right {
167
+ content: none;
168
+ }
169
+ @bottom-center {
170
+ content: none;
171
+ }
172
+ }
173
+
174
+ @page :left {
175
+ margin: 0.75in 1in 0.75in 0.75in;
176
+ /* Verso running head: the current section's URL slug (its anchor ID),
177
+ set like a path in the code face. It tells a reader flipping pages
178
+ which part of the book they're in, which the book title can't. Margin
179
+ boxes sit outside the text block, so this can't move a line break.
180
+ (Not all-small-caps: the Source Sans 3 Latin subset has no smcp glyphs,
181
+ so it would print as letterspaced mixed case.) */
182
+ @top-left {
183
+ content: string(section);
184
+ font-size: 7pt;
185
+ font-family: "Source Code Pro", monospace;
186
+ font-weight: 400;
187
+ text-transform: lowercase;
188
+ color: #555;
189
+ }
190
+ @bottom-left {
191
+ content: counter(page);
192
+ font-size: 9pt;
193
+ font-family: var(--font-heading);
194
+ font-variant-numeric: lining-nums tabular-nums;
195
+ }
196
+ @bottom-center {
197
+ content: none;
198
+ }
199
+ }
200
+
201
+ @page :right {
202
+ margin: 0.75in 0.75in 0.75in 1in;
203
+ @top-right {
204
+ content: string(chapter-title);
205
+ font-size: 7.5pt;
206
+ font-family: var(--font-heading);
207
+ font-style: italic;
208
+ /* #888 at 7.5pt thins out on uncoated POD stock. */
209
+ color: #555;
210
+ }
211
+ @bottom-right {
212
+ content: counter(page);
213
+ font-size: 9pt;
214
+ font-family: var(--font-heading);
215
+ font-variant-numeric: lining-nums tabular-nums;
216
+ }
217
+ @bottom-center {
218
+ content: none;
219
+ }
220
+ }
221
+
222
+ @page chapter {
223
+ @top-left {
224
+ content: none;
225
+ }
226
+ @top-right {
227
+ content: none;
228
+ }
229
+ @top-center {
230
+ content: none;
231
+ }
232
+ }
233
+
234
+ /* Copyright page: no running head (no book title in the top margin), per
235
+ convention. A named page overrides the verso @page :left book-title rule
236
+ (named selectors outrank :left/:right); margins and the page-number folio
237
+ are inherited from @page :left/:right and kept. */
238
+ @page copyright {
239
+ @top-left {
240
+ content: none;
241
+ }
242
+ @top-right {
243
+ content: none;
244
+ }
245
+ @top-center {
246
+ content: none;
247
+ }
248
+ }
249
+
250
+
251
+ /* About the Author: the screen styles' 2px top rule landed at the head of
252
+ a fresh page in print, above the chapter's top padding, as a stray line. */
253
+ #about-the-author {
254
+ border-top: none !important;
255
+ }
256
+
257
+ /* Force B&W optimization.
258
+ print-color-adjust tells browsers to preserve exact colors when printing.
259
+ WeasyPrint ignores this property but it's kept for browser print support. */
260
+ * {
261
+ color-adjust: exact !important;
262
+ print-color-adjust: exact !important;
263
+ -webkit-print-color-adjust: exact !important;
264
+ }
265
+
266
+ body {
267
+ color: #000 !important;
268
+ background: #fff !important;
269
+ /* text-rendering: optimizeLegibility — not supported by WeasyPrint 68.1
270
+ but kept as a progressive enhancement for browser print dialogs */
271
+ text-rendering: optimizeLegibility !important;
272
+ font-size: 11pt !important;
273
+ line-height: 1.55 !important;
274
+ font-family: "Source Serif 4", "Source Serif 4 NotEqual", Georgia, serif !important;
275
+ font-kerning: normal !important;
276
+ /* font-optical-sizing: auto — not supported by WeasyPrint 68.1
277
+ but kept as a progressive enhancement for browser print dialogs */
278
+ font-optical-sizing: auto !important;
279
+ font-variant-numeric: oldstyle-nums proportional-nums !important;
280
+ font-variant-ligatures: common-ligatures contextual !important;
281
+ orphans: 3 !important;
282
+ widows: 3 !important;
283
+ }
284
+
285
+ /* Print Headings — use sans-serif for clear visual hierarchy.
286
+ Sans-serif headings create contrast with the serif body text,
287
+ improving scanability and giving a modern, professional look.
288
+ All headings use weight 700 (bold). Source Sans 3 at 600 (semibold)
289
+ appears visually lighter than Source Serif 4 body text at 400 due to
290
+ the serif's thicker stems and higher stroke contrast. Bold weight
291
+ ensures headings always read heavier than the surrounding body.
292
+
293
+ font-kerning + font-feature-settings ensure kerning tables are
294
+ applied consistently across WeasyPrint and browser print.
295
+ Positive letter-spacing loosens sans-serif text where kerning pairs
296
+ can appear too tight at larger sizes. */
297
+ h1,
298
+ .h1 {
299
+ font-family: var(--font-heading) !important;
300
+ font-size: 22pt !important;
301
+ line-height: 1.15 !important;
302
+ margin-top: 0 !important;
303
+ margin-bottom: 0.75rem !important;
304
+ page-break-before: always !important;
305
+ page-break-after: avoid !important;
306
+ font-weight: 700 !important;
307
+ letter-spacing: normal !important;
308
+ font-kerning: normal !important;
309
+ font-feature-settings:
310
+ "kern" 1,
311
+ "liga" 1 !important;
312
+ color: #000 !important;
313
+ page: chapter !important;
314
+ }
315
+
316
+ /* Section intro heading decoration — single rule.
317
+ Section openers are h1; only h2 chapters set the running-header string
318
+ by default, so without this a section opener's pages inherit the prior
319
+ chapter's title (and the next chapter's title leaks in a page early).
320
+ Set the string here so section-opener pages carry their own title. */
321
+ h1:not(.title) {
322
+ padding-top: 1.5in !important;
323
+ string-set: chapter-title content() !important;
324
+ }
325
+
326
+ /* Verso running-head string (see @page :left): each section's anchor ID.
327
+ A section whose ID sits on its wrapping <section> instead of the h1 can
328
+ name it the same way in the book's CSS, e.g.
329
+ #appendix > h1 { string-set: chapter-title content(), section "appendix" !important; }
330
+ string-set must list chapter-title again, or the declaration drops it. */
331
+ h1.section-opener[id] {
332
+ string-set:
333
+ chapter-title content(),
334
+ section attr(id) !important;
335
+ }
336
+
337
+ /* The ToC pages had no label at all; name them in the running heads. */
338
+ #TOC {
339
+ string-set:
340
+ chapter-title "Contents",
341
+ section "contents" !important;
342
+ }
343
+
344
+ h1:not(.title)::after {
345
+ content: "" !important;
346
+ display: block !important;
347
+ width: 2.5in !important;
348
+ border-top: 1px solid #000 !important;
349
+ height: 0 !important;
350
+ margin: 0.5rem 0 0 0 !important;
351
+ }
352
+
353
+ h2,
354
+ .h2 {
355
+ font-family: var(--font-heading) !important;
356
+ font-size: 16pt !important;
357
+ line-height: 1.2 !important;
358
+ margin-top: 0 !important;
359
+ margin-bottom: 1rem !important;
360
+ padding-top: 1.75in !important;
361
+ page-break-before: always !important;
362
+ page-break-after: avoid !important;
363
+ font-weight: 700 !important;
364
+ letter-spacing: normal !important;
365
+ font-kerning: normal !important;
366
+ font-feature-settings:
367
+ "kern" 1,
368
+ "liga" 1 !important;
369
+ color: #000 !important;
370
+ string-set: chapter-title content() !important;
371
+ page: chapter !important;
372
+ }
373
+
374
+ /* Print heading hierarchy — sized relative to 11pt body.
375
+ h3: 14pt (1.27×), h4: 12pt (1.09×) provide clear steps.
376
+ h5/h6 match body size but are differentiated by style:
377
+ h5 uses uppercase + letter-spacing, h6 uses italic. */
378
+ h3,
379
+ .h3 {
380
+ font-family: var(--font-heading) !important;
381
+ font-size: 14pt !important;
382
+ line-height: 1.25 !important;
383
+ margin-top: 1.25rem !important;
384
+ margin-bottom: 0.4rem !important;
385
+ page-break-after: avoid !important;
386
+ font-weight: 700 !important;
387
+ letter-spacing: normal !important;
388
+ font-kerning: normal !important;
389
+ font-feature-settings:
390
+ "kern" 1,
391
+ "liga" 1 !important;
392
+ color: #000 !important;
393
+ }
394
+
395
+ h4,
396
+ .h4 {
397
+ font-family: var(--font-heading) !important;
398
+ font-size: 12pt !important;
399
+ line-height: 1.35 !important;
400
+ margin-top: 1rem !important;
401
+ margin-bottom: 0.35rem !important;
402
+ page-break-after: avoid !important;
403
+ font-weight: 700 !important;
404
+ letter-spacing: normal !important;
405
+ font-kerning: normal !important;
406
+ font-feature-settings:
407
+ "kern" 1,
408
+ "liga" 1 !important;
409
+ color: #000 !important;
410
+ }
411
+
412
+ h5,
413
+ .h5 {
414
+ font-family: var(--font-heading) !important;
415
+ font-size: 11pt !important;
416
+ line-height: 1.35 !important;
417
+ margin-top: 1rem !important;
418
+ margin-bottom: 0.3rem !important;
419
+ page-break-after: avoid !important;
420
+ font-weight: 700 !important;
421
+ text-transform: uppercase !important;
422
+ letter-spacing: 0.07em !important;
423
+ font-kerning: normal !important;
424
+ font-feature-settings:
425
+ "kern" 1,
426
+ "liga" 1 !important;
427
+ color: #000 !important;
428
+ }
429
+
430
+ h6,
431
+ .h6 {
432
+ font-family: var(--font-heading) !important;
433
+ font-size: 11pt !important;
434
+ line-height: 1.35 !important;
435
+ margin-top: 1rem !important;
436
+ margin-bottom: 0.3rem !important;
437
+ page-break-after: avoid !important;
438
+ font-weight: 700 !important;
439
+ letter-spacing: normal !important;
440
+ font-kerning: normal !important;
441
+ font-feature-settings:
442
+ "kern" 1,
443
+ "liga" 1 !important;
444
+ font-style: italic !important;
445
+ color: #000 !important;
446
+ }
447
+
448
+ /* Print Paragraph Styling */
449
+ p {
450
+ margin: 0 0 0.7rem 0 !important;
451
+ text-align: justify !important;
452
+ hyphens: auto !important;
453
+ hyphenate-limit-chars: 6 3 2 !important;
454
+ /* hyphenate-limit-lines — not supported by WeasyPrint 68.1
455
+ but kept as a progressive enhancement for browser print dialogs */
456
+ hyphenate-limit-lines: 2 !important;
457
+ orphans: 3 !important;
458
+ widows: 3 !important;
459
+ color: #000 !important;
460
+ }
461
+
462
+ /* Print Small Caps for Acronyms
463
+ * IMPORTANT: Do NOT add font-size reduction here.
464
+ * all-small-caps renders at x-height (matching lowercase).
465
+ * Adding font-size < 1em would make small caps shorter than lowercase letters.
466
+ * font-size: inherit overrides the EPUB 1.05em from @media not screen
467
+ * (which matches both EPUB and print media) so PDF uses real OpenType
468
+ * glyph sizing without compensation.
469
+ */
470
+ span.smallcaps {
471
+ font-variant-caps: all-small-caps !important;
472
+ font-size: inherit !important;
473
+ letter-spacing: 0.05em !important;
474
+ }
475
+
476
+ /* Keep headings with following content */
477
+ h1 + p,
478
+ h1 + ul,
479
+ h1 + ol,
480
+ h2 + p,
481
+ h2 + ul,
482
+ h2 + ol,
483
+ h3 + p,
484
+ h3 + ul,
485
+ h3 + ol,
486
+ h4 + p,
487
+ h4 + ul,
488
+ h4 + ol,
489
+ h5 + p,
490
+ h5 + ul,
491
+ h5 + ol,
492
+ h6 + p,
493
+ h6 + ul,
494
+ h6 + ol {
495
+ page-break-before: avoid !important;
496
+ }
497
+
498
+ /* Print Lists */
499
+ ul,
500
+ ol {
501
+ margin: 0.75rem 0 !important;
502
+ padding-left: 1.5rem !important;
503
+ page-break-inside: auto !important;
504
+ orphans: 2 !important;
505
+ widows: 2 !important;
506
+ }
507
+
508
+ ul li,
509
+ ol li {
510
+ margin-bottom: 0.4rem !important;
511
+ line-height: 1.4 !important;
512
+ color: #000 !important;
513
+ page-break-inside: avoid !important;
514
+ }
515
+
516
+ /* Print Images
517
+ Note: filter: grayscale() is NOT supported by WeasyPrint 68.1 — images
518
+ render in full color in the PDF. This is acceptable because KDP converts
519
+ paperback interiors to B&W during processing. All colors in the book use
520
+ grayscale-friendly values with sufficient contrast for B&W reproduction. */
521
+ img {
522
+ max-width: 100% !important;
523
+ height: auto !important;
524
+ margin: 1rem 0 !important;
525
+ border: 1px solid #ccc !important;
526
+ page-break-inside: avoid !important;
527
+ }
528
+
529
+ /* Emoji images should not have figure-style borders or margins */
530
+ img.callout-emoji,
531
+ img.emoji {
532
+ border: none !important;
533
+ margin: 0 !important;
534
+ }
535
+
536
+ figure {
537
+ margin: 1rem 0 !important;
538
+ page-break-inside: avoid !important;
539
+ text-align: center !important;
540
+ }
541
+
542
+ figcaption {
543
+ font-size: 9pt !important;
544
+ font-style: italic !important;
545
+ color: #333 !important;
546
+ margin-top: 0.5rem !important;
547
+ }
548
+
549
+ /* Print Code Blocks */
550
+ code {
551
+ font-size: 0.9em !important;
552
+ padding: 0.1em 0.2em !important;
553
+ background-color: #f5f5f5 !important;
554
+ border: 1px solid #ddd !important;
555
+ border-radius: 0.125rem !important;
556
+ overflow-wrap: break-word !important;
557
+ font-family: var(--font-mono) !important;
558
+ color: #000 !important;
559
+ }
560
+
561
+ pre {
562
+ page-break-inside: avoid !important;
563
+ font-size: 9.5pt !important;
564
+ line-height: 1.3 !important;
565
+ margin: 0.75rem 0 !important;
566
+ padding: 0.75rem !important;
567
+ background-color: #f8f8f8 !important;
568
+ border: 1px solid #999 !important;
569
+ border-radius: 0.25rem !important;
570
+ font-family: var(--font-mono) !important;
571
+ color: #000 !important;
572
+ }
573
+
574
+ pre code {
575
+ background-color: transparent !important;
576
+ border: none !important;
577
+ padding: 0 !important;
578
+ }
579
+
580
+ /* Print Lead Paragraph - Section introduction.
581
+ Use pt to match the rest of the print section (12pt ≈ 1.1× the 11pt body). */
582
+ .lead,
583
+ section.section-opener > p,
584
+ section.section-opener > ul,
585
+ section.section-opener > ol {
586
+ font-size: 12pt !important;
587
+ font-weight: 300 !important;
588
+ line-height: 1.5 !important;
589
+ color: #333 !important;
590
+ margin-bottom: 1.25rem !important;
591
+ page-break-before: avoid !important;
592
+ }
593
+
594
+ /* The lead treatment is for a section's opening pages only. Where a
595
+ section's chapters sit directly in its <section> (a closing section, say),
596
+ their body paragraphs follow an h2 and would otherwise all render as light,
597
+ gray lead text. Restore the print body values from p and body above. */
598
+ section.section-opener > h2 ~ p,
599
+ section.section-opener > h2 ~ ul,
600
+ section.section-opener > h2 ~ ol {
601
+ font-weight: 400 !important;
602
+ color: #000 !important;
603
+ }
604
+
605
+ /* Print Callouts - Refined, unified treatment
606
+ All callouts use the same simple left border. The label text
607
+ (TL;DR, Pro tip, For managers, etc.) provides sufficient
608
+ differentiation without needing distinct border patterns or font
609
+ switching.
610
+
611
+ Fill and border are dark enough for the B&W paperback: a faint tint
612
+ (#f5f5f5) can drop out when a POD press converts the CMYK PDF to
613
+ grayscale. #e8e8e8 must match the backdrop composite-print-emoji.py
614
+ bakes into img/emoji-print-callout/, or each emoji prints as a visible
615
+ square. Colors only; nothing here may change box geometry, which would
616
+ reflow a locked page count. */
617
+ .tldr,
618
+ [class*="tldr"],
619
+ .callout,
620
+ .note,
621
+ .tip,
622
+ .warning,
623
+ .pro-tip,
624
+ .for-managers,
625
+ .for-ics,
626
+ .common-objection {
627
+ font-family: "Source Serif 4", "Source Serif 4 NotEqual", Georgia, serif !important;
628
+ background-color: #e8e8e8 !important;
629
+ border: none !important;
630
+ border-left: 4px solid #4d4d4d !important;
631
+ border-radius: 2px !important;
632
+ padding: 0.625rem 1rem !important;
633
+ margin: 0.625rem 0 !important;
634
+ page-break-inside: auto !important;
635
+ color: #000 !important;
636
+ orphans: 2 !important;
637
+ widows: 2 !important;
638
+ }
639
+
640
+ /* The TL;DR opens every chapter; a near-black rule sets it apart from the
641
+ other callouts without any change in size. */
642
+ .tldr,
643
+ [class*="tldr"] {
644
+ border-left-color: #1a1a1a !important;
645
+ }
646
+
647
+ /* All callout ::before suppressed — labels now come from add-div-titles.lua
648
+ (Lua filter runs with --metadata pdf=true in the PDF build pipeline).
649
+ Emoji callouts use Twemoji <img> elements; TL;DR uses text-only label.
650
+ Without content: none, labels would appear twice (CSS + Lua). */
651
+ .tldr::before,
652
+ .callout::before,
653
+ .note::before,
654
+ .tip::before,
655
+ .warning::before,
656
+ .pro-tip::before,
657
+ .for-managers::before,
658
+ .for-ics::before,
659
+ .common-objection::before {
660
+ content: none !important;
661
+ }
662
+
663
+ /* Restore breathing room between chapter title and TL;DR */
664
+ h2 + .tldr {
665
+ margin-top: 1rem !important;
666
+ }
667
+
668
+ /* Print callout labels from Lua filter.
669
+ Matches the screen ::before styling for visual consistency. */
670
+ .callout-label {
671
+ font-variant-caps: all-small-caps !important;
672
+ font-size: inherit !important;
673
+ font-weight: 700 !important;
674
+ font-style: normal !important;
675
+ letter-spacing: 0.04em !important;
676
+ font-family: var(--font-heading) !important;
677
+ color: #000 !important;
678
+ }
679
+
680
+ /* Callout emoji images — sized to match label text height.
681
+ Transparent Twemoji PNGs from img/emoji/ render as grayscale in B&W print. */
682
+ img.callout-emoji {
683
+ height: 0.9em !important;
684
+ width: 0.9em !important;
685
+ vertical-align: -0.1em !important;
686
+ display: inline !important;
687
+ }
688
+
689
+ /* Body-text inline emoji — converted from raw characters to <img> by
690
+ body-emoji-images.lua (PDF only). WeasyPrint's fallback emoji font renders
691
+ them undersized and baseline-high; size them to ~cap height and drop them
692
+ onto the baseline so they sit with the surrounding serif text. Scoped away
693
+ from callout-label glyphs, which keep their smaller 0.9em treatment. */
694
+ img.emoji:not(.callout-emoji) {
695
+ height: 1.15em !important;
696
+ width: 1.15em !important;
697
+ vertical-align: -0.2em !important;
698
+ display: inline !important;
699
+ }
700
+
701
+ .tldr p:first-child,
702
+ .callout p:first-child,
703
+ .note p:first-child,
704
+ .tip p:first-child,
705
+ .warning p:first-child,
706
+ .pro-tip p:first-child,
707
+ .for-managers p:first-child,
708
+ .for-ics p:first-child,
709
+ .common-objection p:first-child {
710
+ display: inline !important;
711
+ margin: 0 !important;
712
+ }
713
+
714
+ .callout p,
715
+ .note p,
716
+ .tip p,
717
+ .warning p,
718
+ .pro-tip p,
719
+ .for-managers p,
720
+ .for-ics p,
721
+ .common-objection p {
722
+ margin-bottom: 0.5rem !important;
723
+ }
724
+
725
+ .callout p:last-child,
726
+ .note p:last-child,
727
+ .tip p:last-child,
728
+ .warning p:last-child,
729
+ .pro-tip p:last-child,
730
+ .for-managers p:last-child,
731
+ .for-ics p:last-child,
732
+ .common-objection p:last-child {
733
+ margin-bottom: 0 !important;
734
+ }
735
+
736
+ .tldr p:first-child + p,
737
+ .callout p:first-child + p,
738
+ .note p:first-child + p,
739
+ .tip p:first-child + p,
740
+ .warning p:first-child + p,
741
+ .pro-tip p:first-child + p,
742
+ .for-managers p:first-child + p,
743
+ .for-ics p:first-child + p,
744
+ .common-objection p:first-child + p {
745
+ margin-top: 0.5rem !important;
746
+ }
747
+
748
+ .takeaways {
749
+ font-family: var(--font-heading) !important;
750
+ background-color: transparent !important;
751
+ border: none !important;
752
+ border-top: 1px solid #888 !important;
753
+ border-bottom: 1px solid #888 !important;
754
+ border-radius: 0 !important;
755
+ padding: 0.625rem 0 !important;
756
+ margin: 0.625rem 0 !important;
757
+ page-break-inside: auto !important;
758
+ color: #000 !important;
759
+ }
760
+
761
+ .takeaways h3 {
762
+ margin-top: 0 !important;
763
+ font-size: 1em !important;
764
+ font-weight: 600 !important;
765
+ letter-spacing: normal !important;
766
+ color: #000 !important;
767
+ }
768
+
769
+ /* Print Tables — Booktabs Style */
770
+ table {
771
+ font-size: 9pt !important;
772
+ font-family: var(--font-heading) !important;
773
+ width: 100% !important;
774
+ border-collapse: collapse !important;
775
+ margin: 0.75rem 0 !important;
776
+ page-break-inside: avoid !important;
777
+ background-color: #fff !important;
778
+ color: #000 !important;
779
+ border-top: 2px solid #000 !important;
780
+ border-bottom: 2px solid #000 !important;
781
+ border-left: none !important;
782
+ border-right: none !important;
783
+ }
784
+
785
+ table th,
786
+ table td {
787
+ padding: 0.4rem 0.6rem !important;
788
+ border: none !important;
789
+ border-bottom: 1px solid #ccc !important;
790
+ color: #000 !important;
791
+ background-color: #fff !important;
792
+ }
793
+
794
+ table th {
795
+ background-color: #fff !important;
796
+ font-weight: 600 !important;
797
+ border-bottom: 2px solid #000 !important;
798
+ }
799
+
800
+ table tbody tr:last-child td {
801
+ border-bottom: none !important;
802
+ }
803
+
804
+ /* Print Footnotes */
805
+ .footnotes {
806
+ margin-top: 2rem !important;
807
+ padding-top: 1rem !important;
808
+ border-top: 1px solid #333 !important;
809
+ font-size: 10pt !important;
810
+ line-height: 1.3 !important;
811
+ text-align: left !important;
812
+ }
813
+
814
+ .footnotes ol {
815
+ padding-left: 1rem !important;
816
+ text-align: left !important;
817
+ }
818
+
819
+ .footnotes ol li {
820
+ margin-bottom: 0.5rem !important;
821
+ color: #000 !important;
822
+ text-align: left !important;
823
+ }
824
+
825
+ /* Print Blockquotes — elegant traditional style */
826
+ blockquote {
827
+ margin: 1rem 1.5rem !important;
828
+ padding: 0 0 0 1.25rem !important;
829
+ border-left: 3px solid #aaa !important;
830
+ background-color: transparent !important;
831
+ font-style: italic !important;
832
+ font-size: 10.5pt !important;
833
+ line-height: 1.45 !important;
834
+ page-break-inside: avoid !important;
835
+ color: #333 !important;
836
+ }
837
+
838
+ /* Print Links */
839
+ a {
840
+ color: #000 !important;
841
+ text-decoration: underline !important;
842
+ }
843
+
844
+ a[href^="#"] {
845
+ color: #000 !important;
846
+ text-decoration: none !important;
847
+ }
848
+
849
+ /* Print Section Dividers — short centered rule */
850
+ hr {
851
+ border: none !important;
852
+ height: auto !important;
853
+ width: auto !important;
854
+ background: none !important;
855
+ margin: 1.5rem auto !important;
856
+ text-align: center !important;
857
+ page-break-after: avoid !important;
858
+ page-break-before: avoid !important;
859
+ }
860
+
861
+ hr::after {
862
+ content: "⁕ ⁕ ⁕" !important;
863
+ display: block !important;
864
+ color: #999 !important;
865
+ font-size: 9pt !important;
866
+ letter-spacing: 0.15em !important;
867
+ }
868
+
869
+ /* Print TOC */
870
+ .toc,
871
+ #toc,
872
+ nav[role="doc-toc"],
873
+ #TOC {
874
+ page-break-after: always !important;
875
+ margin-bottom: 1.5rem !important;
876
+ text-align: left !important;
877
+ }
878
+
879
+ #TOC ul {
880
+ list-style: none !important;
881
+ padding-left: 0 !important;
882
+ }
883
+
884
+ #TOC > ul > li {
885
+ margin-bottom: 0.6rem !important;
886
+ text-align: left !important;
887
+ font-weight: 600 !important;
888
+ padding-bottom: 0.2rem !important;
889
+ }
890
+
891
+ #TOC ul li {
892
+ margin-bottom: 0.35rem !important;
893
+ text-align: left !important;
894
+ }
895
+
896
+ #TOC ul li a {
897
+ text-decoration: none !important;
898
+ color: #000 !important;
899
+ display: block !important;
900
+ }
901
+
902
+ /* Add page numbers with leader dots for TOC entries */
903
+ #TOC ul li a::after {
904
+ content: leader(dotted) " " target-counter(attr(href), page) !important;
905
+ font-variant-numeric: lining-nums tabular-nums !important;
906
+ color: #000 !important;
907
+ white-space: nowrap !important;
908
+ }
909
+
910
+ #TOC ul ul {
911
+ padding-left: 1.25rem !important;
912
+ margin-top: 0.15rem !important;
913
+ }
914
+
915
+ #TOC ul ul li {
916
+ font-size: 0.9em !important;
917
+ font-weight: 400 !important;
918
+ margin-bottom: 0.15rem !important;
919
+ }
920
+
921
+ /* Print Special Pages */
922
+ #copyright-page {
923
+ page: copyright !important;
924
+ page-break-before: always !important;
925
+ page-break-after: always !important;
926
+ /* Bottom alignment using flexbox
927
+ Content area: 7.5in (9in page height - 0.75in top margin - 0.75in bottom margin) */
928
+ display: flex !important;
929
+ align-items: flex-end !important;
930
+ min-height: 7.5in !important;
931
+ padding: 0 !important;
932
+ color: #000 !important;
933
+ }
934
+
935
+ /* The invisible copyright heading needs print-specific collapsing.
936
+ The base sr-only rule (#copyright-page .invisible > h2) hides it with
937
+ position:absolute + clip, which macOS WeasyPrint honors but the
938
+ Linux/Docker CI build does NOT — there the heading falls back to the
939
+ generic print h2 styling (page-break-before:always, page:chapter, 16pt)
940
+ and renders "Copyright" on its own page before the colophon. Collapse it
941
+ in normal flow instead — zero height/size, same page name, no break —
942
+ which every WeasyPrint platform renders identically. Keep it in flow
943
+ (not display:none) so string-set still clears the running-header title:
944
+ the generic h2 rule otherwise sets `chapter-title` to "Copyright",
945
+ leaking it into the running headers of the following front-matter pages
946
+ (dedication, table of contents), which carry no running head. */
947
+ #copyright-page h2 {
948
+ string-set: chapter-title "" !important;
949
+ position: static !important;
950
+ width: auto !important;
951
+ height: 0 !important;
952
+ margin: 0 !important;
953
+ padding: 0 !important;
954
+ overflow: hidden !important;
955
+ font-size: 0 !important;
956
+ color: transparent !important;
957
+ clip: auto !important;
958
+ page: copyright !important;
959
+ page-break-before: avoid !important;
960
+ page-break-after: avoid !important;
961
+ }
962
+
963
+ #copyright-container {
964
+ font-size: 0.875em !important;
965
+ }
966
+
967
+ #copyright-container > p {
968
+ margin-bottom: 0.3rem !important;
969
+ }
970
+
971
+ .dedication {
972
+ page-break-before: always !important;
973
+ page-break-after: always !important;
974
+ text-align: center !important;
975
+ padding-top: 3in !important;
976
+ color: #000 !important;
977
+ }
978
+
979
+ /* Print back matter — distinct typographic treatment */
980
+ #acknowledgements {
981
+ page-break-before: always !important;
982
+ }
983
+
984
+ #acknowledgements ul {
985
+ font-size: 10pt !important;
986
+ line-height: 1.35 !important;
987
+ columns: 2 !important;
988
+ column-gap: 1.5rem !important;
989
+ }
990
+
991
+ #acknowledgements ul li {
992
+ margin-bottom: 0.2rem !important;
993
+ page-break-inside: avoid !important;
994
+ }
995
+
996
+ #about-the-author {
997
+ page-break-before: always !important;
998
+ }
999
+
1000
+ .back-cover {
1001
+ page-break-before: always !important;
1002
+ font-family: var(--font-heading) !important;
1003
+ font-size: 10.5pt !important;
1004
+ line-height: 1.5 !important;
1005
+ color: #000 !important;
1006
+ }
1007
+
1008
+ /* Remove shadows and filters for WeasyPrint compatibility */
1009
+ * {
1010
+ box-shadow: none !important;
1011
+ text-shadow: none !important;
1012
+ backdrop-filter: none !important;
1013
+ }
1014
+
1015
+ /* Print Footnote References
1016
+ font-variant-position: super uses Source Serif 4's OpenType sups feature
1017
+ for optically-correct superscripts (better alignment/kerning than manual
1018
+ font-size + vertical-align). Falls back to synthesis if feature missing.
1019
+
1020
+ Pandoc generates <a class="footnote-ref"><sup>N</sup></a>. The inner
1021
+ <sup> must be neutralized so the <a>'s font-variant-position handles
1022
+ superscript rendering. Without this, the <sup>'s default
1023
+ vertical-align: super expands the line box, creating uneven line
1024
+ spacing on lines that contain footnote references.
1025
+
1026
+ line-height: 0 on the <a> prevents the inline box from contributing
1027
+ to line-box height — the superscript glyph still renders (it overflows
1028
+ its zero-height box) but adjacent lines stay evenly spaced. */
1029
+ .footnote-ref {
1030
+ font-variant-position: super !important;
1031
+ font-size: inherit !important;
1032
+ vertical-align: baseline !important;
1033
+ position: static !important;
1034
+ top: auto !important;
1035
+ line-height: 0 !important;
1036
+ color: #000 !important;
1037
+ }
1038
+
1039
+ .footnote-ref sup {
1040
+ vertical-align: baseline !important;
1041
+ font-size: inherit !important;
1042
+ }
1043
+
1044
+ /* Hide footnote back-references (↩︎) — not useful in print */
1045
+ .footnote-back {
1046
+ display: none !important;
1047
+ }
1048
+
1049
+ /* Title Page Styling for Print - Polished Manuscript Cover
1050
+ Page size: 6in × 9in (KDP trade paperback)
1051
+ Margins: 0.75in top/bottom
1052
+ Content height: 9in - 1.5in = 7.5in */
1053
+ #title-block-header {
1054
+ display: block !important;
1055
+ min-height: 7.5in !important;
1056
+ margin: 0 !important;
1057
+ padding: 0 !important;
1058
+ page-break-after: always !important;
1059
+ text-align: center !important;
1060
+ position: relative !important;
1061
+ }
1062
+
1063
+ /* Title rules. These were fading gradients, which read as a web hero, not
1064
+ a title page, and a fade can halftone unevenly. Flat, the rule above the
1065
+ title doubled up with the title block's own full-width top rule, so it's
1066
+ now an invisible spacer that keeps the page's spacing; the hairline
1067
+ below the title (::after) carries the structure. */
1068
+ h1.title::before {
1069
+ content: "" !important;
1070
+ display: block !important;
1071
+ width: 3in !important;
1072
+ height: 1px !important;
1073
+ background: transparent !important;
1074
+ margin: 0 auto 1.75rem auto !important;
1075
+ }
1076
+
1077
+ h1.title {
1078
+ display: block !important;
1079
+ box-sizing: border-box !important;
1080
+ font-size: 30pt !important;
1081
+ line-height: 1.1 !important;
1082
+ font-weight: 700 !important;
1083
+ margin-top: 0 !important;
1084
+ margin-bottom: 0 !important;
1085
+ margin-left: 0 !important;
1086
+ margin-right: 0 !important;
1087
+ padding: 0 !important;
1088
+ font-family: var(--font-heading) !important;
1089
+ color: #000 !important;
1090
+ letter-spacing: -0.02em !important;
1091
+ text-transform: none !important;
1092
+ width: 100% !important;
1093
+ max-width: none !important;
1094
+ text-align: center !important;
1095
+ }
1096
+
1097
+ h1.title::after {
1098
+ content: "" !important;
1099
+ display: block !important;
1100
+ width: 3in !important;
1101
+ height: 1px !important;
1102
+ background: #000 !important;
1103
+ margin: 1.75rem auto 0 auto !important;
1104
+ }
1105
+
1106
+ p.subtitle {
1107
+ display: block !important;
1108
+ box-sizing: border-box !important;
1109
+ font-size: 14pt !important;
1110
+ line-height: 1.4 !important;
1111
+ font-weight: 400 !important;
1112
+ margin-top: 1.25rem !important;
1113
+ margin-bottom: 2.5rem !important;
1114
+ margin-left: 0 !important;
1115
+ margin-right: 0 !important;
1116
+ padding: 0 0 1.75rem 0 !important;
1117
+ font-family: var(--font-heading) !important;
1118
+ font-style: italic !important;
1119
+ color: #444 !important;
1120
+ width: 100% !important;
1121
+ max-width: none !important;
1122
+ text-align: center !important;
1123
+ }
1124
+
1125
+ /* "By" prefix for author - traditional book style */
1126
+ p.author::before {
1127
+ content: "By " !important;
1128
+ font-weight: 300 !important;
1129
+ font-style: normal !important;
1130
+ text-transform: none !important;
1131
+ letter-spacing: normal !important;
1132
+ }
1133
+
1134
+ p.author {
1135
+ display: block !important;
1136
+ box-sizing: border-box !important;
1137
+ font-size: 13pt !important;
1138
+ line-height: 1.4 !important;
1139
+ font-weight: 500 !important;
1140
+ margin-top: 0 !important;
1141
+ margin-bottom: 0.5rem !important;
1142
+ margin-left: 0 !important;
1143
+ margin-right: 0 !important;
1144
+ padding: 0 0 2.5rem 0 !important;
1145
+ font-family: var(--font-heading) !important;
1146
+ color: #000 !important;
1147
+ text-transform: none !important;
1148
+ letter-spacing: 0.04em !important;
1149
+ width: 100% !important;
1150
+ max-width: none !important;
1151
+ text-align: center !important;
1152
+ }
1153
+
1154
+ /* Version/date - positioned at bottom of title page content area
1155
+ The container (#title-block-header) has min-height: 7.5in which is the
1156
+ content area after page margins, so bottom: 0 places this at the very
1157
+ bottom of the printable area */
1158
+ p.date {
1159
+ display: block !important;
1160
+ box-sizing: border-box !important;
1161
+ font-size: 8pt !important;
1162
+ line-height: 1.4 !important;
1163
+ font-weight: 400 !important;
1164
+ margin: 0 !important;
1165
+ padding: 0 !important;
1166
+ font-family: var(--font-heading) !important;
1167
+ font-variant-numeric: lining-nums tabular-nums !important;
1168
+ color: #888 !important;
1169
+ letter-spacing: 0.06em !important;
1170
+ width: 100% !important;
1171
+ max-width: none !important;
1172
+ text-align: center !important;
1173
+ position: absolute !important;
1174
+ bottom: 0 !important;
1175
+ left: 0 !important;
1176
+ }
1177
+ }
1178
+
1179
+ /* ---------------------------------------------------------------------------
1180
+ Print-only restore: undo the e-reader line-box fixes that leaked into the
1181
+ PDF. WeasyPrint renders with media type `print`, which ALSO matches
1182
+ `@media not screen` — so the Kindle fixes in the `@media not screen` blocks
1183
+ above can silently tighten callout spacing in print and change a book's
1184
+ locked page count. `strip-page-rules.js` strips `@media print` from
1185
+ the EPUB CSS, so re-pinning the original print values here restores the
1186
+ print layout WITHOUT touching the e-reader fixes. Declarations use `!important` (idiomatic for the print
1187
+ blocks in this file) so they win regardless of how PostCSS orders the
1188
+ compiled media queries relative to the `@media not screen` blocks. */
1189
+ @media print {
1190
+ /* Two of the leaked `@media not screen` declarations actually reach the PDF
1191
+ (inline-code and callout-emoji don't — they already have dedicated
1192
+ `@media print` !important rules above, so their e-reader changes never
1193
+ touched print):
1194
+
1195
+ 1. Callout paragraph line-height. No print rule pinned it, so the e-reader
1196
+ `line-height: inherit` tightened every callout body paragraph. */
1197
+ .tldr p,
1198
+ .callout p,
1199
+ .note p,
1200
+ .tip p,
1201
+ .warning p,
1202
+ .pro-tip p,
1203
+ .for-managers p,
1204
+ .for-ics p,
1205
+ .common-objection p {
1206
+ line-height: 1.5 !important;
1207
+ }
1208
+
1209
+ /* 2. box-decoration-break. Callouts use page-break-inside: auto in print, so
1210
+ they DO split across pages — and `clone` repeats the box's top/bottom
1211
+ padding + border on each fragment, while the leaked `slice` drops it.
1212
+ That repeated padding is real vertical space, so slice silently
1213
+ shortens a book. List ALL the callout selectors the leaked rule
1214
+ targets (.tldr and .pro-tip included; a chapter-opening TL;DR splits
1215
+ often) or the restore is incomplete. */
1216
+ .tldr,
1217
+ .callout,
1218
+ .note,
1219
+ .tip,
1220
+ .warning,
1221
+ .pro-tip,
1222
+ .for-managers,
1223
+ .for-ics,
1224
+ .common-objection,
1225
+ .takeaways {
1226
+ -webkit-box-decoration-break: clone !important;
1227
+ box-decoration-break: clone !important;
1228
+ }
1229
+ }