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,546 @@
1
+ /* ============================================
2
+ COMPONENTS LAYER - Reusable Callout Patterns
3
+ ============================================ */
4
+ @layer components {
5
+ /* Lead Paragraph - Bootstrap-style introductory text */
6
+ .lead {
7
+ font-size: 1.25rem;
8
+ font-weight: 300;
9
+ line-height: 1.5;
10
+ color: var(--color-muted);
11
+ margin-bottom: 1.5rem;
12
+ }
13
+
14
+ /* Section Opener — page-level lead styling for section introduction chapters.
15
+ Applies lead treatment to all direct paragraphs and lists within the section,
16
+ while leaving callout divs (.tldr, .common-objection, .for-managers, .for-ics,
17
+ .pro-tip) styled normally via their own rules. */
18
+ section.section-opener > p,
19
+ section.section-opener > ul,
20
+ section.section-opener > ol {
21
+ font-size: 1.25rem;
22
+ font-weight: 300;
23
+ line-height: 1.5;
24
+ color: var(--color-muted);
25
+ margin-bottom: 1.5rem;
26
+ }
27
+
28
+ /* TL;DR Summary Callout — uses body serif for readable paragraph text.
29
+ The label ("TL;DR:") is injected as bold by the Lua filter and
30
+ styled via the ::before rule (screen) or <strong> (EPUB). */
31
+ .tldr {
32
+ font-family: var(--font-body);
33
+ font-size: 1em;
34
+ font-weight: 400;
35
+ line-height: 1.5;
36
+ margin-top: 0.25rem;
37
+ margin-bottom: 0.25rem;
38
+ padding: 0.875rem 1.25rem;
39
+ background-color: var(--color-summary-bg);
40
+ border-left: 4px solid var(--color-summary-border);
41
+ border-radius: var(--radius-callout);
42
+ page-break-before: avoid;
43
+ page-break-inside: avoid;
44
+ /* When a callout is too tall to keep on one page (avoid can't help), break
45
+ it cleanly: each page fragment gets its own complete border/background
46
+ instead of an orphaned, square-cut open edge at the page boundary. */
47
+ -webkit-box-decoration-break: clone;
48
+ box-decoration-break: clone;
49
+ }
50
+
51
+ .tldr::before {
52
+ content: "TL;DR: ";
53
+ font-variant-caps: all-small-caps;
54
+ font-size: inherit; /* Prevent browser synthesis from reducing size */
55
+ font-weight: 700;
56
+ font-style: normal;
57
+ line-height: 1;
58
+ vertical-align: baseline;
59
+ letter-spacing: 0.04em;
60
+ font-family: var(--font-heading);
61
+ display: inline;
62
+ }
63
+
64
+ .tldr p:first-child {
65
+ display: inline;
66
+ margin: 0;
67
+ }
68
+
69
+ /* Key Takeaways Box */
70
+ .takeaways {
71
+ font-family: var(--font-body);
72
+ margin: 0.75rem 0;
73
+ padding: 1rem 1.25rem;
74
+ background-color: var(--color-takeaway-bg);
75
+ border-left: 3px solid var(--color-takeaway-border);
76
+ border-radius: var(--radius-callout);
77
+ page-break-before: avoid;
78
+ page-break-inside: avoid;
79
+ /* When a callout is too tall to keep on one page (avoid can't help), break
80
+ it cleanly: each page fragment gets its own complete border/background
81
+ instead of an orphaned, square-cut open edge at the page boundary. */
82
+ -webkit-box-decoration-break: clone;
83
+ box-decoration-break: clone;
84
+ }
85
+
86
+ .takeaways h3 {
87
+ margin-top: 0;
88
+ font-family: var(--font-heading);
89
+ font-size: 1em;
90
+ font-weight: 600;
91
+ letter-spacing: 0.02em;
92
+ color: var(--color-emphasis);
93
+ }
94
+
95
+ .takeaways ul {
96
+ margin-bottom: 0;
97
+ }
98
+
99
+ .takeaways ul li {
100
+ margin-bottom: 0.4rem;
101
+ }
102
+
103
+ /* Pro-Tip Callout */
104
+ .pro-tip {
105
+ font-family: var(--font-body);
106
+ margin: 0.75rem 0;
107
+ padding: 0.875rem 1.25rem;
108
+ background-color: var(--color-tip-bg);
109
+ border-left: 3px solid var(--color-tip-accent);
110
+ border-radius: var(--radius-callout);
111
+ page-break-before: avoid;
112
+ page-break-inside: avoid;
113
+ /* When a callout is too tall to keep on one page (avoid can't help), break
114
+ it cleanly: each page fragment gets its own complete border/background
115
+ instead of an orphaned, square-cut open edge at the page boundary. */
116
+ -webkit-box-decoration-break: clone;
117
+ box-decoration-break: clone;
118
+ }
119
+
120
+ .pro-tip::before {
121
+ content: "💡 Pro-Tip: ";
122
+ font-variant-caps: all-small-caps;
123
+ font-size: inherit;
124
+ font-weight: 700;
125
+ font-style: normal;
126
+ line-height: 1;
127
+ vertical-align: baseline;
128
+ letter-spacing: 0.04em;
129
+ font-family: var(--font-heading);
130
+ display: inline;
131
+ }
132
+
133
+ .pro-tip p {
134
+ margin-bottom: 0.5rem;
135
+ line-height: 1.5;
136
+ }
137
+
138
+ .pro-tip p:first-child {
139
+ display: inline;
140
+ margin: 0;
141
+ }
142
+
143
+ .pro-tip p:last-child {
144
+ margin-bottom: 0;
145
+ }
146
+
147
+ .pro-tip p:first-child + p {
148
+ margin-top: 0.75rem;
149
+ }
150
+
151
+ /* Core callouts — the kit defaults' registry (note, tip, warning). Same
152
+ box as the Pro-Tip; books on a preset style their own callouts. */
153
+ .callout,
154
+ .note,
155
+ .tip,
156
+ .warning {
157
+ font-family: var(--font-body);
158
+ margin: 0.75rem 0;
159
+ padding: 0.875rem 1.25rem;
160
+ border-radius: var(--radius-callout);
161
+ page-break-before: avoid;
162
+ page-break-inside: avoid;
163
+ -webkit-box-decoration-break: clone;
164
+ box-decoration-break: clone;
165
+ }
166
+
167
+ .note,
168
+ .callout {
169
+ background-color: var(--color-note-bg);
170
+ border-left: 3px solid var(--color-note-accent);
171
+ }
172
+
173
+ .tip {
174
+ background-color: var(--color-tip-bg);
175
+ border-left: 3px solid var(--color-tip-accent);
176
+ }
177
+
178
+ .warning {
179
+ background-color: var(--color-warning-bg);
180
+ border-left: 3px solid var(--color-warning-accent);
181
+ }
182
+
183
+ .callout::before,
184
+ .note::before,
185
+ .tip::before,
186
+ .warning::before {
187
+ font-variant-caps: all-small-caps;
188
+ font-size: inherit;
189
+ font-weight: 700;
190
+ font-style: normal;
191
+ line-height: 1;
192
+ vertical-align: baseline;
193
+ letter-spacing: 0.04em;
194
+ font-family: var(--font-heading);
195
+ display: inline;
196
+ }
197
+
198
+ .note::before {
199
+ content: "Note: ";
200
+ }
201
+
202
+ .tip::before {
203
+ content: "Tip: ";
204
+ }
205
+
206
+ .warning::before {
207
+ content: "Warning: ";
208
+ }
209
+
210
+ /* A book's own callouts look like .note: filters/callout-classes.lua gives
211
+ any registry callout the theme doesn't style the .callout class and a
212
+ data-label. This draws that label in the web edition; the other formats
213
+ get it from add-div-titles.lua, and @media screen keeps it out of them. */
214
+ @media screen {
215
+ .callout::before {
216
+ content: attr(data-label) " ";
217
+ }
218
+ }
219
+
220
+ .callout p,
221
+ .note p,
222
+ .tip p,
223
+ .warning p {
224
+ margin-bottom: 0.5rem;
225
+ line-height: 1.5;
226
+ }
227
+
228
+ .callout p:first-child,
229
+ .note p:first-child,
230
+ .tip p:first-child,
231
+ .warning p:first-child {
232
+ display: inline;
233
+ margin: 0;
234
+ }
235
+
236
+ .callout p:last-child,
237
+ .note p:last-child,
238
+ .tip p:last-child,
239
+ .warning p:last-child {
240
+ margin-bottom: 0;
241
+ }
242
+
243
+ .callout p:first-child + p,
244
+ .note p:first-child + p,
245
+ .tip p:first-child + p,
246
+ .warning p:first-child + p {
247
+ margin-top: 0.75rem;
248
+ }
249
+
250
+ /* For Managers Callout */
251
+ .for-managers {
252
+ font-family: var(--font-body);
253
+ margin: 0.75rem 0;
254
+ padding: 0.875rem 1.25rem;
255
+ background-color: var(--color-manager-bg);
256
+ border-left: 3px solid var(--color-manager-accent);
257
+ border-radius: var(--radius-callout);
258
+ page-break-before: avoid;
259
+ page-break-inside: avoid;
260
+ /* When a callout is too tall to keep on one page (avoid can't help), break
261
+ it cleanly: each page fragment gets its own complete border/background
262
+ instead of an orphaned, square-cut open edge at the page boundary. */
263
+ -webkit-box-decoration-break: clone;
264
+ box-decoration-break: clone;
265
+ }
266
+
267
+ .for-managers::before {
268
+ content: "👔 For managers: ";
269
+ font-variant-caps: all-small-caps;
270
+ font-size: inherit;
271
+ font-weight: 700;
272
+ font-style: normal;
273
+ line-height: 1;
274
+ vertical-align: baseline;
275
+ letter-spacing: 0.04em;
276
+ font-family: var(--font-heading);
277
+ display: inline;
278
+ }
279
+
280
+ .for-managers p {
281
+ margin-bottom: 0.5rem;
282
+ line-height: 1.5;
283
+ }
284
+
285
+ .for-managers p:first-child {
286
+ display: inline;
287
+ margin: 0;
288
+ }
289
+
290
+ .for-managers p:last-child {
291
+ margin-bottom: 0;
292
+ }
293
+
294
+ .for-managers p:first-child + p {
295
+ margin-top: 0.75rem;
296
+ }
297
+
298
+ /* For Individual Contributors Callout */
299
+ .for-ics {
300
+ font-family: var(--font-body);
301
+ margin: 0.75rem 0;
302
+ padding: 0.875rem 1.25rem;
303
+ background-color: var(--color-ic-bg);
304
+ border-left: 3px solid var(--color-ic-accent);
305
+ border-radius: var(--radius-callout);
306
+ page-break-before: avoid;
307
+ page-break-inside: avoid;
308
+ /* When a callout is too tall to keep on one page (avoid can't help), break
309
+ it cleanly: each page fragment gets its own complete border/background
310
+ instead of an orphaned, square-cut open edge at the page boundary. */
311
+ -webkit-box-decoration-break: clone;
312
+ box-decoration-break: clone;
313
+ }
314
+
315
+ .for-ics::before {
316
+ content: "💻 For individual contributors: ";
317
+ font-variant-caps: all-small-caps;
318
+ font-size: inherit;
319
+ font-weight: 700;
320
+ font-style: normal;
321
+ line-height: 1;
322
+ vertical-align: baseline;
323
+ letter-spacing: 0.04em;
324
+ font-family: var(--font-heading);
325
+ display: inline;
326
+ }
327
+
328
+ .for-ics p {
329
+ margin-bottom: 0.5rem;
330
+ line-height: 1.5;
331
+ }
332
+
333
+ .for-ics p:first-child {
334
+ display: inline;
335
+ margin: 0;
336
+ }
337
+
338
+ .for-ics p:last-child {
339
+ margin-bottom: 0;
340
+ }
341
+
342
+ .for-ics p:first-child + p {
343
+ margin-top: 0.75rem;
344
+ }
345
+
346
+ /* Common Objection Callout */
347
+ .common-objection {
348
+ font-family: var(--font-body);
349
+ margin: 0.75rem 0;
350
+ padding: 0.875rem 1.25rem;
351
+ background-color: var(--color-objection-bg);
352
+ border-left: 3px solid var(--color-objection-accent);
353
+ border-radius: var(--radius-callout);
354
+ page-break-before: avoid;
355
+ page-break-inside: avoid;
356
+ /* When a callout is too tall to keep on one page (avoid can't help), break
357
+ it cleanly: each page fragment gets its own complete border/background
358
+ instead of an orphaned, square-cut open edge at the page boundary. */
359
+ -webkit-box-decoration-break: clone;
360
+ box-decoration-break: clone;
361
+ }
362
+
363
+ .common-objection::before {
364
+ content: "🤔 Common objection: ";
365
+ font-variant-caps: all-small-caps;
366
+ font-size: inherit;
367
+ font-weight: 700;
368
+ font-style: normal;
369
+ line-height: 1;
370
+ vertical-align: baseline;
371
+ letter-spacing: 0.04em;
372
+ font-family: var(--font-heading);
373
+ display: inline;
374
+ }
375
+
376
+ .common-objection p {
377
+ margin-bottom: 0.5rem;
378
+ line-height: 1.5;
379
+ }
380
+
381
+ .common-objection p:first-child {
382
+ display: inline;
383
+ margin: 0;
384
+ }
385
+
386
+ .common-objection p:nth-child(2) {
387
+ display: block;
388
+ margin-top: 0.75rem;
389
+ }
390
+
391
+ .common-objection p:last-child {
392
+ margin-bottom: 0;
393
+ }
394
+
395
+ /* Title Block Header */
396
+ .title {
397
+ text-align: center;
398
+ }
399
+
400
+ #title-block-header {
401
+ margin-top: 3rem;
402
+ }
403
+
404
+ /* Footnotes Section */
405
+ .footnotes {
406
+ font-size: 0.85em;
407
+ margin-top: var(--spacing-section);
408
+ padding-top: var(--spacing-callout);
409
+ border-top: 2px solid var(--color-emphasis);
410
+ page-break-inside: avoid;
411
+ }
412
+
413
+ .footnotes::before {
414
+ content: "Notes";
415
+ display: block;
416
+ margin-bottom: 0.75rem;
417
+ font-weight: 700;
418
+ font-family: var(--font-heading);
419
+ font-size: 1.1em;
420
+ letter-spacing: normal;
421
+ }
422
+
423
+ .footnotes ol {
424
+ font-family: var(--font-heading);
425
+ font-variant-numeric: lining-nums tabular-nums;
426
+ padding-left: 2em;
427
+ }
428
+
429
+ .footnotes ol li {
430
+ margin-bottom: 0.5rem;
431
+ padding-left: 0.25em;
432
+ }
433
+
434
+ .footnotes ol li p {
435
+ margin-bottom: 0.25rem;
436
+ line-height: 1.4;
437
+ }
438
+
439
+ /* Blockquotes — elegant left-border with refined typography */
440
+ blockquote {
441
+ border-left: 3px solid var(--color-muted);
442
+ padding-left: 1.25rem;
443
+ padding-top: 0.25rem;
444
+ padding-bottom: 0.25rem;
445
+ margin: 1.5rem 0 1.5rem 0.5rem;
446
+ font-style: italic;
447
+ font-size: 0.97em;
448
+ page-break-inside: avoid;
449
+ }
450
+
451
+ blockquote p {
452
+ margin-bottom: 0;
453
+ }
454
+
455
+ /* Images */
456
+ img {
457
+ max-width: 100%;
458
+ height: auto;
459
+ display: block;
460
+ margin-left: auto;
461
+ margin-right: auto;
462
+ page-break-inside: avoid;
463
+ }
464
+
465
+ /* Tables — booktabs academic style */
466
+ table {
467
+ width: 100%;
468
+ border-collapse: collapse;
469
+ font-size: 0.9em;
470
+ font-family: var(--font-heading);
471
+ page-break-inside: avoid;
472
+ margin: 1.5em 0;
473
+ border-top: 2px solid var(--color-emphasis);
474
+ border-bottom: 2px solid var(--color-emphasis);
475
+ }
476
+
477
+ table th,
478
+ table td {
479
+ padding: 0.5rem 0.75rem;
480
+ border: none;
481
+ border-bottom: 1px solid var(--color-border);
482
+ vertical-align: top;
483
+ text-align: left;
484
+ }
485
+
486
+ table th {
487
+ background-color: transparent;
488
+ font-weight: 600;
489
+ font-size: 0.9em;
490
+ letter-spacing: 0.02em;
491
+ border-bottom: 1px solid var(--color-emphasis);
492
+ }
493
+
494
+ table tbody tr:last-child td {
495
+ border-bottom: none;
496
+ }
497
+
498
+ /* Subtle zebra striping for long tables — helps track across rows */
499
+ table tbody tr:nth-child(even) {
500
+ background-color: #f8f8f8;
501
+ }
502
+
503
+ /* Figures and Captions */
504
+ figure {
505
+ margin: var(--spacing-callout) 0;
506
+ text-align: center;
507
+ }
508
+
509
+ figcaption {
510
+ font-size: 0.9em;
511
+ color: var(--color-muted);
512
+ margin-top: 0.5rem;
513
+ text-align: center;
514
+ font-style: italic;
515
+ }
516
+
517
+ /* Copyright Page */
518
+ #copyright-page {
519
+ display: flex;
520
+ align-items: flex-end;
521
+ font-size: 0.825em;
522
+ line-height: 1.5;
523
+ page-break-before: left;
524
+ page-break-after: always;
525
+ }
526
+
527
+ /* Dedication — refined centered treatment */
528
+ .dedication {
529
+ text-align: center;
530
+ font-style: italic;
531
+ margin-top: 3in;
532
+ font-size: 1.05em;
533
+ line-height: 1.65;
534
+ color: var(--color-emphasis);
535
+ }
536
+
537
+ /* Footnote Reference Styling */
538
+ .footnote-ref {
539
+ font-size: 0.85em;
540
+ vertical-align: baseline;
541
+ position: relative;
542
+ top: -0.4em;
543
+ color: #000;
544
+ }
545
+
546
+ }
@@ -0,0 +1,40 @@
1
+ /* ============================================
2
+ UTILITIES LAYER - Custom Utility Classes
3
+ ============================================ */
4
+ @layer utilities {
5
+ /* Book Typography Utilities */
6
+ .book-justified {
7
+ text-align: justify;
8
+ hyphens: auto;
9
+ -webkit-hyphens: auto;
10
+ /* hyphenate-limit-chars: min-word-length (6), min-before-break (3), min-after-break (2) */
11
+ hyphenate-limit-chars: 6 3 2;
12
+ }
13
+
14
+ .book-ragged {
15
+ text-align: left;
16
+ hyphens: manual;
17
+ }
18
+
19
+ .book-small-caps {
20
+ font-variant-caps: all-small-caps;
21
+ letter-spacing: 0.05em;
22
+ }
23
+
24
+ .book-no-indent {
25
+ text-indent: 0;
26
+ }
27
+
28
+ .book-indent {
29
+ text-indent: 1.5em;
30
+ }
31
+
32
+ /* OpenType feature utility classes */
33
+ .book-fractions {
34
+ font-variant-numeric: diagonal-fractions;
35
+ }
36
+
37
+ .book-ordinals {
38
+ font-feature-settings: "ordn";
39
+ }
40
+ }