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.
- package/LICENSE +21 -0
- package/NOTICE.md +72 -0
- package/README.md +251 -2
- package/bin/book-kit.js +115 -0
- package/commands/_emoji_io.py +32 -0
- package/commands/audit-chapter-lengths.js +244 -0
- package/commands/check-epub-size.js +68 -0
- package/commands/check-pdf-page-count.js +162 -0
- package/commands/composite-kindle-emoji.py +85 -0
- package/commands/composite-print-emoji.py +98 -0
- package/commands/conventions.js +76 -0
- package/commands/convert-pdfx.sh +194 -0
- package/commands/download-icc-profile.sh +105 -0
- package/commands/fonts.py +212 -0
- package/commands/generate-reference-docx.py +344 -0
- package/commands/kindle-fonts.js +173 -0
- package/commands/links-to-footnotes.js +366 -0
- package/commands/markdownlint.js +25 -0
- package/commands/minify-css.js +43 -0
- package/commands/optimize-images.js +73 -0
- package/commands/parity.sh +150 -0
- package/commands/postprocess-epub.js +541 -0
- package/commands/prep-print-src.js +77 -0
- package/commands/prose.js +38 -0
- package/commands/release-files.js +89 -0
- package/commands/reorder-print-frontmatter.js +79 -0
- package/commands/strip-page-rules.js +1168 -0
- package/commands/strip-property-rules.js +93 -0
- package/commands/update-key-takeaways.js +314 -0
- package/commands/validate.js +283 -0
- package/configs/markdownlint-cli2.jsonc +98 -0
- package/configs/textlintrc.json +22 -0
- package/css/theme/01-tokens.css +83 -0
- package/css/theme/02-fonts.css +79 -0
- package/css/theme/03-prose.css +53 -0
- package/css/theme/04-base.css +226 -0
- package/css/theme/05-components.css +546 -0
- package/css/theme/06-utilities.css +40 -0
- package/css/theme/07-ereader.css +245 -0
- package/css/theme/08-epub.css +865 -0
- package/css/theme/09-back-matter.css +47 -0
- package/css/theme/10-dark.css +302 -0
- package/css/theme/11-print.css +1229 -0
- package/css/theme.css +38 -0
- package/defaults/book.config.yml +318 -0
- package/defaults/pandoc-base.yml +19 -0
- package/defaults/pandoc-docx.yml +6 -0
- package/defaults/pandoc-epub-fonts.yml +6 -0
- package/defaults/pandoc-epub.yml +15 -0
- package/defaults/pandoc-kindle.yml +6 -0
- package/emoji/1f382.png +0 -0
- package/emoji/1f389.png +0 -0
- package/emoji/1f440.png +0 -0
- package/emoji/1f44d.png +0 -0
- package/emoji/1f44f.png +0 -0
- package/emoji/1f454.png +0 -0
- package/emoji/1f4a1.png +0 -0
- package/emoji/1f4bb.png +0 -0
- package/emoji/1f602.png +0 -0
- package/emoji/1f603.png +0 -0
- package/emoji/1f604.png +0 -0
- package/emoji/1f60a.png +0 -0
- package/emoji/1f60f.png +0 -0
- package/emoji/1f64c.png +0 -0
- package/emoji/1f64f.png +0 -0
- package/emoji/1f914.png +0 -0
- package/emoji/1f923.png +0 -0
- package/emoji/2714.png +0 -0
- package/emoji/274c.png +0 -0
- package/filters/add-div-titles.lua +196 -0
- package/filters/arc-notice.lua +36 -0
- package/filters/body-emoji-images.lua +48 -0
- package/filters/callout-classes.lua +40 -0
- package/filters/lib/book_kit.lua +110 -0
- package/filters/revision.lua +17 -0
- package/filters/strip-comments.lua +40 -0
- package/filters/strip-emoji-kindle.lua +134 -0
- package/fonts/LICENSE-source-code-pro.md +93 -0
- package/fonts/LICENSE-source-sans.md +93 -0
- package/fonts/LICENSE-source-serif.md +93 -0
- package/fonts/recipe.json +41 -0
- package/just/book-kit.just +229 -0
- package/lib/acronyms.js +47 -0
- package/lib/callouts.js +17 -0
- package/lib/config.js +211 -0
- package/lib/is-main.js +21 -0
- package/lib/lint.js +148 -0
- package/lib/pandoc.js +148 -0
- package/lib/paragraphs.js +173 -0
- package/lib/revision.js +35 -0
- package/lib/structure.js +39 -0
- package/lib/textlint-github-formatter.js +58 -0
- package/lib/validate.js +202 -0
- package/package.json +98 -4
- package/presets/business-nonfiction/CONVENTIONS.md +35 -0
- package/presets/business-nonfiction/preset.yml +128 -0
- package/profiles/pdfx-def.ps +42 -0
- package/requirements.txt +14 -0
- package/rules/no-ai-like-patterns.js +209 -0
- package/rules/no-assumptive.js +76 -0
- package/rules/no-bare-acronyms.js +129 -0
- package/rules/no-cliches.js +544 -0
- package/rules/no-cultural-idioms.js +422 -0
- package/rules/no-vague-intensifiers.js +94 -0
- package/templates/template-epub.html +79 -0
- package/templates/template.html +73 -0
- package/toolchain.json +42 -0
- package/validators/acronym-expansion.js +94 -0
- package/validators/bold-keywords.js +56 -0
- package/validators/callout-balance.js +74 -0
- package/validators/callout-divs.js +66 -0
- package/validators/callout-labels.js +102 -0
- package/validators/chapter-lengths.js +14 -0
- package/validators/chapter.js +57 -0
- package/validators/cross-references.js +45 -0
- package/validators/doubled-words.js +76 -0
- package/validators/duplicate-headings.js +52 -0
- package/validators/em-dashes.js +73 -0
- package/validators/escaped-smallcaps.js +46 -0
- package/validators/footnotes.js +78 -0
- package/validators/heading-hierarchy.js +58 -0
- package/validators/hypothetical-hooks.js +103 -0
- package/validators/index-integrity.js +28 -0
- package/validators/index.js +73 -0
- package/validators/list-punctuation.js +123 -0
- package/validators/min-opener-length.js +87 -0
- package/validators/no-bare-url-link-text.js +38 -0
- package/validators/no-todo-markers.js +49 -0
- package/validators/no-transition-todos.js +34 -0
- package/validators/number-range-dashes.js +72 -0
- package/validators/paragraph-length.js +62 -0
- package/validators/quote-punctuation.js +85 -0
- package/validators/section-intro-final-lead.js +90 -0
- package/validators/section-intro-has-lead.js +41 -0
- package/validators/section-intro-no-tldr.js +37 -0
- package/validators/section-intros.js +33 -0
- package/validators/sentence-starters.js +132 -0
- package/validators/smallcaps.js +67 -0
- package/validators/tldr-length.js +58 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// book-kit's base markdownlint config. The build merges lint.markdownlint
|
|
2
|
+
// from book.config.yml (and its presets) into `config` (lib/lint.js); a book
|
|
3
|
+
// with its own .markdownlint-cli2.jsonc uses that instead.
|
|
4
|
+
{
|
|
5
|
+
"config": {
|
|
6
|
+
// Enable all default rules as baseline
|
|
7
|
+
"default": true,
|
|
8
|
+
|
|
9
|
+
// === Line and Formatting Rules ===
|
|
10
|
+
// Disable line length for prose-heavy content (books need flowing paragraphs)
|
|
11
|
+
"line-length": false,
|
|
12
|
+
// Allow chapters to start with H2 (H1 is reserved for book title)
|
|
13
|
+
"first-line-h1": false,
|
|
14
|
+
|
|
15
|
+
// === Heading Rules ===
|
|
16
|
+
// MD001: Heading levels should increment by one level at a time
|
|
17
|
+
"heading-increment": true,
|
|
18
|
+
// MD003: Heading style - use ATX style (hash marks)
|
|
19
|
+
"heading-style": { "style": "atx" },
|
|
20
|
+
// MD022: Headings should be surrounded by blank lines
|
|
21
|
+
"blanks-around-headings": true,
|
|
22
|
+
// MD024: Allow duplicate headings in different sections (common in books)
|
|
23
|
+
"no-duplicate-heading": { "siblings_only": true },
|
|
24
|
+
// MD025: Only one H1 per document (but we use H2 for chapters)
|
|
25
|
+
"single-h1": false,
|
|
26
|
+
// MD041: First line doesn't need to be H1 (chapters start with H2)
|
|
27
|
+
"first-line-heading": false,
|
|
28
|
+
|
|
29
|
+
// === List Rules ===
|
|
30
|
+
// MD004: Use dashes for unordered lists consistently
|
|
31
|
+
"ul-style": { "style": "dash" },
|
|
32
|
+
// MD005: Consistent list indentation
|
|
33
|
+
"list-indent": true,
|
|
34
|
+
// MD007: Unordered list indentation (2 spaces)
|
|
35
|
+
"ul-indent": { "indent": 2 },
|
|
36
|
+
// MD029: Ordered list item prefix (use ordered numbers)
|
|
37
|
+
"ol-prefix": { "style": "ordered" },
|
|
38
|
+
// MD030: Spaces after list markers
|
|
39
|
+
"list-marker-space": true,
|
|
40
|
+
// MD032: Lists should be surrounded by blank lines
|
|
41
|
+
"blanks-around-lists": true,
|
|
42
|
+
|
|
43
|
+
// === Link and Reference Rules ===
|
|
44
|
+
// Disable link fragment checking (custom anchor handling)
|
|
45
|
+
"link-fragments": false,
|
|
46
|
+
// MD034: Allow bare URLs when appropriate
|
|
47
|
+
"no-bare-urls": false,
|
|
48
|
+
|
|
49
|
+
// === HTML Rules ===
|
|
50
|
+
// Allow inline HTML for pandoc custom divs and spans
|
|
51
|
+
"no-inline-html": false,
|
|
52
|
+
|
|
53
|
+
// === Code Block Rules ===
|
|
54
|
+
// MD031: Code blocks should be surrounded by blank lines
|
|
55
|
+
"blanks-around-fences": true,
|
|
56
|
+
// MD040: Fenced code blocks should have a language specified
|
|
57
|
+
"fenced-code-language": false,
|
|
58
|
+
// MD046: Use fenced code blocks consistently
|
|
59
|
+
"code-block-style": { "style": "fenced" },
|
|
60
|
+
// MD048: Use backticks for code fences
|
|
61
|
+
"code-fence-style": { "style": "backtick" },
|
|
62
|
+
|
|
63
|
+
// === Whitespace Rules ===
|
|
64
|
+
// MD009: No trailing spaces (except for line breaks)
|
|
65
|
+
"no-trailing-spaces": { "br_spaces": 2 },
|
|
66
|
+
// MD010: No hard tabs
|
|
67
|
+
"no-hard-tabs": true,
|
|
68
|
+
// MD012: No multiple consecutive blank lines
|
|
69
|
+
"no-multiple-blanks": { "maximum": 1 },
|
|
70
|
+
// MD027: No multiple spaces after blockquote symbol
|
|
71
|
+
"no-multiple-space-blockquote": true,
|
|
72
|
+
// MD047: Files should end with a single newline
|
|
73
|
+
"single-trailing-newline": true,
|
|
74
|
+
|
|
75
|
+
// === Content Rules ===
|
|
76
|
+
// MD026: No trailing punctuation in headings (except ? for questions)
|
|
77
|
+
"no-trailing-punctuation": { "punctuation": ".,;:!" },
|
|
78
|
+
// MD036: No emphasis used as heading
|
|
79
|
+
"no-emphasis-as-heading": true,
|
|
80
|
+
// MD037: No spaces inside emphasis markers
|
|
81
|
+
"no-space-in-emphasis": true,
|
|
82
|
+
// MD038: No spaces inside code span elements
|
|
83
|
+
"no-space-in-code": true,
|
|
84
|
+
// MD039: No spaces inside link text
|
|
85
|
+
"no-space-in-links": true,
|
|
86
|
+
// MD045: Images should have alt text for accessibility
|
|
87
|
+
"no-alt-text": true,
|
|
88
|
+
// MD049: Use asterisks for emphasis consistently
|
|
89
|
+
"emphasis-style": { "style": "asterisk" },
|
|
90
|
+
// MD050: Use asterisks for strong consistently
|
|
91
|
+
"strong-style": { "style": "asterisk" }
|
|
92
|
+
},
|
|
93
|
+
// Ignore generated content (lib/lint.js adds drafts, structure.draft_suffix)
|
|
94
|
+
"ignores": [
|
|
95
|
+
"**/node_modules/**",
|
|
96
|
+
"**/dist/**"
|
|
97
|
+
]
|
|
98
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"filters": {
|
|
3
|
+
"comments": true
|
|
4
|
+
},
|
|
5
|
+
"rules": {
|
|
6
|
+
"no-start-duplicated-conjunction": {
|
|
7
|
+
"interval": 2
|
|
8
|
+
},
|
|
9
|
+
"common-misspellings": {
|
|
10
|
+
"ignore": [
|
|
11
|
+
"doesnt",
|
|
12
|
+
"isnt"
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
"diacritics": true,
|
|
16
|
+
"doubled-spaces": true,
|
|
17
|
+
"en-capitalization": false,
|
|
18
|
+
"@textlint-rule/no-unmatched-pair": true,
|
|
19
|
+
"@textlint-rule/no-duplicate-abbr": true,
|
|
20
|
+
"abbr-within-parentheses": true
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/* ============================================
|
|
2
|
+
THEME LAYER - Design Tokens & Variables
|
|
3
|
+
Using @theme for utility class generation
|
|
4
|
+
============================================ */
|
|
5
|
+
@theme {
|
|
6
|
+
/* ── Design Tokens ──────────────────────────────────────────────
|
|
7
|
+
These tokens generate Tailwind utility classes.
|
|
8
|
+
|
|
9
|
+
Safe to modify:
|
|
10
|
+
• Brand colors (--color-brand, etc.) — used in screen CSS only
|
|
11
|
+
• Spacing scale (--spacing-*) — layout breathing room
|
|
12
|
+
• Line-height, paragraph spacing — reading comfort
|
|
13
|
+
|
|
14
|
+
Format-dependent (change with care):
|
|
15
|
+
• Font families — must match @font-face declarations
|
|
16
|
+
• Callout colors — have corresponding dark-mode overrides
|
|
17
|
+
• Border radius — EPUB strips border-radius on some readers
|
|
18
|
+
────────────────────────────────────────────────────────────── */
|
|
19
|
+
|
|
20
|
+
/* Book Typography - Source font family (Adobe, SIL Open Font License)
|
|
21
|
+
Source Serif 4: transitional serif with optical sizes, ideal for book body text
|
|
22
|
+
Source Sans 3: matching sans-serif for headings and callouts
|
|
23
|
+
Source Code Pro: matching monospace for code blocks */
|
|
24
|
+
--font-body: "Source Serif 4", "Source Serif 4 NotEqual", serif;
|
|
25
|
+
--font-heading: "Source Sans 3", sans-serif;
|
|
26
|
+
--font-mono: "Source Code Pro", "Courier New", monospace;
|
|
27
|
+
--font-emoji:
|
|
28
|
+
"Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", sans-serif;
|
|
29
|
+
|
|
30
|
+
/* Book Brand Colors */
|
|
31
|
+
--color-brand: #0056b3;
|
|
32
|
+
--color-muted: #6c757d;
|
|
33
|
+
--color-surface: #f8f9fa; /* Available for backgrounds */
|
|
34
|
+
--color-border: #dee2e6;
|
|
35
|
+
--color-emphasis: #495057;
|
|
36
|
+
|
|
37
|
+
/* Callout: Summary (TL;DR) */
|
|
38
|
+
--color-summary-bg: #f8f9fa;
|
|
39
|
+
--color-summary-border: #0056b3;
|
|
40
|
+
|
|
41
|
+
/* Callout: Tip */
|
|
42
|
+
--color-tip-bg: #f8f6f0;
|
|
43
|
+
--color-tip-accent: #b8956a;
|
|
44
|
+
|
|
45
|
+
/* Callout: Manager Guidance */
|
|
46
|
+
--color-manager-bg: #f0f4fa;
|
|
47
|
+
--color-manager-accent: #6a95c2;
|
|
48
|
+
|
|
49
|
+
/* Callout: IC Guidance */
|
|
50
|
+
--color-ic-bg: #f0f8f1;
|
|
51
|
+
--color-ic-accent: #6aaa6e;
|
|
52
|
+
|
|
53
|
+
/* Callout: Objection */
|
|
54
|
+
--color-objection-bg: #faf0f3;
|
|
55
|
+
--color-objection-accent: #b07090;
|
|
56
|
+
|
|
57
|
+
/* Core callouts (the kit defaults' note, tip, warning). Tip reuses the
|
|
58
|
+
Pro-Tip palette. */
|
|
59
|
+
--color-note-bg: #f5f7fa;
|
|
60
|
+
--color-note-accent: #8a9bb0;
|
|
61
|
+
--color-warning-bg: #fdf6e9;
|
|
62
|
+
--color-warning-accent: #c98a2b;
|
|
63
|
+
|
|
64
|
+
/* Callout: Takeaways */
|
|
65
|
+
--color-takeaway-bg: #f5f6f7;
|
|
66
|
+
--color-takeaway-border: #c8d4d9;
|
|
67
|
+
|
|
68
|
+
/* Print Grayscale Palette — Values used by @media print hardcoded rules */
|
|
69
|
+
|
|
70
|
+
/* Spacing Scale for Book Layout */
|
|
71
|
+
--spacing-callout: 1rem;
|
|
72
|
+
--spacing-section: 2rem;
|
|
73
|
+
|
|
74
|
+
/* Border Radius Scale */
|
|
75
|
+
--radius-callout: 0.375rem;
|
|
76
|
+
|
|
77
|
+
/* Book Typography Scale — Optimized for long-form reading */
|
|
78
|
+
--book-line-height: 1.6;
|
|
79
|
+
--book-paragraph-spacing: 0.75em;
|
|
80
|
+
--book-heading-line-height: 1.2;
|
|
81
|
+
--book-letter-spacing: normal;
|
|
82
|
+
--book-word-spacing: 0.02em;
|
|
83
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/* ============================================
|
|
2
|
+
FONT FACE DECLARATIONS
|
|
3
|
+
Source font family — variable WOFF2 with full OpenType features.
|
|
4
|
+
Source Serif 4: smcp, c2sc, onum, lnum, kern, liga, opsz (optical sizes)
|
|
5
|
+
Source Sans 3: kern, liga, pnum
|
|
6
|
+
Source Code Pro: frac, dnom, numr
|
|
7
|
+
Single file per style covers all weights 200-900.
|
|
8
|
+
============================================ */
|
|
9
|
+
|
|
10
|
+
/* Source Serif 4 — Body text (variable, Latin subset, optical sizes 8-60) */
|
|
11
|
+
@font-face {
|
|
12
|
+
font-family: "Source Serif 4";
|
|
13
|
+
font-style: normal;
|
|
14
|
+
font-weight: 200 900;
|
|
15
|
+
font-display: swap;
|
|
16
|
+
src: url("../fonts/SourceSerif4-Variable-Latin.woff2") format("woff2");
|
|
17
|
+
}
|
|
18
|
+
@font-face {
|
|
19
|
+
font-family: "Source Serif 4";
|
|
20
|
+
font-style: italic;
|
|
21
|
+
font-weight: 200 900;
|
|
22
|
+
font-display: swap;
|
|
23
|
+
src: url("../fonts/SourceSerif4-Italic-Variable-Latin.woff2") format("woff2");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/* Source Serif 4 — ≠ only. The Latin subsets above lack U+2260, so a "≠"
|
|
27
|
+
in body text fell back to Georgia. Upstream Source Serif 4.005
|
|
28
|
+
(adobe-fonts/source-serif), subset to that one glyph. It's a separate
|
|
29
|
+
family, listed second in each serif stack: as an extra face of "Source
|
|
30
|
+
Serif 4", WeasyPrint embedded it under the main face's font name and drew
|
|
31
|
+
the wrong glyph in its place (a blank, or a "C"). */
|
|
32
|
+
@font-face {
|
|
33
|
+
font-family: "Source Serif 4 NotEqual";
|
|
34
|
+
font-style: normal;
|
|
35
|
+
font-weight: 200 900;
|
|
36
|
+
font-display: swap;
|
|
37
|
+
src: url("../fonts/SourceSerif4-NotEqual.woff2") format("woff2");
|
|
38
|
+
unicode-range: U+2260;
|
|
39
|
+
}
|
|
40
|
+
@font-face {
|
|
41
|
+
font-family: "Source Serif 4 NotEqual";
|
|
42
|
+
font-style: italic;
|
|
43
|
+
font-weight: 200 900;
|
|
44
|
+
font-display: swap;
|
|
45
|
+
src: url("../fonts/SourceSerif4-Italic-NotEqual.woff2") format("woff2");
|
|
46
|
+
unicode-range: U+2260;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* Source Sans 3 — Headings, callouts, UI elements (variable, Latin subset) */
|
|
50
|
+
@font-face {
|
|
51
|
+
font-family: "Source Sans 3";
|
|
52
|
+
font-style: normal;
|
|
53
|
+
font-weight: 200 900;
|
|
54
|
+
font-display: swap;
|
|
55
|
+
src: url("../fonts/SourceSans3-Variable-Latin.woff2") format("woff2");
|
|
56
|
+
}
|
|
57
|
+
@font-face {
|
|
58
|
+
font-family: "Source Sans 3";
|
|
59
|
+
font-style: italic;
|
|
60
|
+
font-weight: 200 900;
|
|
61
|
+
font-display: swap;
|
|
62
|
+
src: url("../fonts/SourceSans3-Italic-Variable-Latin.woff2") format("woff2");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* Source Code Pro — Code blocks, inline code (variable, Latin subset) */
|
|
66
|
+
@font-face {
|
|
67
|
+
font-family: "Source Code Pro";
|
|
68
|
+
font-style: normal;
|
|
69
|
+
font-weight: 200 900;
|
|
70
|
+
font-display: swap;
|
|
71
|
+
src: url("../fonts/SourceCodePro-Variable-Latin.woff2") format("woff2");
|
|
72
|
+
}
|
|
73
|
+
@font-face {
|
|
74
|
+
font-family: "Source Code Pro";
|
|
75
|
+
font-style: italic;
|
|
76
|
+
font-weight: 200 900;
|
|
77
|
+
font-display: swap;
|
|
78
|
+
src: url("../fonts/SourceCodePro-Italic-Variable-Latin.woff2") format("woff2");
|
|
79
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/* ============================================
|
|
2
|
+
TAILWIND TYPOGRAPHY - PROSE CONTAINER STYLES
|
|
3
|
+
Pandoc content should use class="prose" wrapper
|
|
4
|
+
for Typography descendant rules to activate.
|
|
5
|
+
============================================ */
|
|
6
|
+
|
|
7
|
+
/* Base prose configuration with book theme colors */
|
|
8
|
+
.prose {
|
|
9
|
+
@apply prose-neutral max-w-none;
|
|
10
|
+
--tw-prose-body: var(--color-emphasis);
|
|
11
|
+
--tw-prose-headings: var(--color-emphasis);
|
|
12
|
+
--tw-prose-lead: var(--color-muted);
|
|
13
|
+
--tw-prose-links: var(--color-brand);
|
|
14
|
+
--tw-prose-bold: var(--color-emphasis);
|
|
15
|
+
--tw-prose-counters: var(--color-muted);
|
|
16
|
+
--tw-prose-bullets: var(--color-border);
|
|
17
|
+
--tw-prose-hr: var(--color-border);
|
|
18
|
+
--tw-prose-quotes: var(--color-emphasis);
|
|
19
|
+
--tw-prose-quote-borders: var(--color-muted);
|
|
20
|
+
--tw-prose-captions: var(--color-muted);
|
|
21
|
+
--tw-prose-code: var(--color-emphasis);
|
|
22
|
+
--tw-prose-pre-code: #1f2937;
|
|
23
|
+
--tw-prose-pre-bg: #f8f8f8;
|
|
24
|
+
--tw-prose-th-borders: var(--color-border);
|
|
25
|
+
--tw-prose-td-borders: var(--color-border);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* Comfortable reading width on screen */
|
|
29
|
+
@media screen {
|
|
30
|
+
.prose {
|
|
31
|
+
max-width: 40rem;
|
|
32
|
+
margin-left: auto;
|
|
33
|
+
margin-right: auto;
|
|
34
|
+
padding-left: 1.5rem;
|
|
35
|
+
padding-right: 1.5rem;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/* Larger text on medium screens */
|
|
40
|
+
@media screen and (min-width: 768px) {
|
|
41
|
+
.prose {
|
|
42
|
+
@apply prose-lg;
|
|
43
|
+
max-width: 42rem;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* Extra large text on wide screens */
|
|
48
|
+
@media screen and (min-width: 1024px) {
|
|
49
|
+
.prose {
|
|
50
|
+
@apply prose-xl;
|
|
51
|
+
max-width: 44rem;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/* ============================================
|
|
2
|
+
BASE LAYER - Element Resets & Typography
|
|
3
|
+
============================================ */
|
|
4
|
+
@layer base {
|
|
5
|
+
body {
|
|
6
|
+
font-family: var(--font-body);
|
|
7
|
+
font-optical-sizing: auto;
|
|
8
|
+
text-align: left;
|
|
9
|
+
line-height: var(--book-line-height);
|
|
10
|
+
letter-spacing: var(--book-letter-spacing);
|
|
11
|
+
word-spacing: var(--book-word-spacing);
|
|
12
|
+
font-kerning: normal;
|
|
13
|
+
font-variant-ligatures: common-ligatures contextual;
|
|
14
|
+
font-variant-numeric: oldstyle-nums proportional-nums;
|
|
15
|
+
text-rendering: optimizeLegibility;
|
|
16
|
+
-webkit-font-smoothing: antialiased;
|
|
17
|
+
-moz-osx-font-smoothing: grayscale;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* Variable font weight for bold — 600 (semibold) gives better
|
|
21
|
+
color and texture than browser-default 700 with Source Serif 4. */
|
|
22
|
+
strong,
|
|
23
|
+
b {
|
|
24
|
+
font-weight: 600;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* Paragraph typography for book readability */
|
|
28
|
+
p {
|
|
29
|
+
margin-bottom: var(--book-paragraph-spacing);
|
|
30
|
+
/* hanging-punctuation: Safari-only, stripped for EPUB compatibility */
|
|
31
|
+
hanging-punctuation: first allow-end last;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* Heading Hierarchy — clear visual distinction at every level */
|
|
35
|
+
h1 {
|
|
36
|
+
font-family: var(--font-heading);
|
|
37
|
+
font-size: 2.25rem;
|
|
38
|
+
font-weight: 700;
|
|
39
|
+
line-height: var(--book-heading-line-height);
|
|
40
|
+
margin-top: 0;
|
|
41
|
+
margin-bottom: 1.25rem;
|
|
42
|
+
letter-spacing: normal;
|
|
43
|
+
page-break-after: avoid;
|
|
44
|
+
page-break-inside: avoid;
|
|
45
|
+
orphans: 3;
|
|
46
|
+
widows: 3;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
h2 {
|
|
50
|
+
font-family: var(--font-heading);
|
|
51
|
+
font-size: 1.75rem;
|
|
52
|
+
font-weight: 700;
|
|
53
|
+
line-height: var(--book-heading-line-height);
|
|
54
|
+
margin-top: 2.5rem;
|
|
55
|
+
margin-bottom: 0.75rem;
|
|
56
|
+
letter-spacing: normal;
|
|
57
|
+
page-break-after: avoid;
|
|
58
|
+
page-break-inside: avoid;
|
|
59
|
+
orphans: 3;
|
|
60
|
+
widows: 3;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
h3 {
|
|
64
|
+
font-family: var(--font-heading);
|
|
65
|
+
font-size: 1.35rem;
|
|
66
|
+
font-weight: 700;
|
|
67
|
+
line-height: var(--book-heading-line-height);
|
|
68
|
+
margin-top: 2rem;
|
|
69
|
+
margin-bottom: 0.5rem;
|
|
70
|
+
letter-spacing: normal;
|
|
71
|
+
page-break-after: avoid;
|
|
72
|
+
page-break-inside: avoid;
|
|
73
|
+
orphans: 3;
|
|
74
|
+
widows: 3;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
h4 {
|
|
78
|
+
font-family: var(--font-heading);
|
|
79
|
+
font-size: 1.15rem;
|
|
80
|
+
font-weight: 700;
|
|
81
|
+
line-height: var(--book-heading-line-height);
|
|
82
|
+
margin-top: 1.5rem;
|
|
83
|
+
margin-bottom: 0.35rem;
|
|
84
|
+
letter-spacing: normal;
|
|
85
|
+
orphans: 2;
|
|
86
|
+
widows: 2;
|
|
87
|
+
page-break-after: avoid;
|
|
88
|
+
page-break-inside: avoid;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
h5 {
|
|
92
|
+
font-family: var(--font-heading);
|
|
93
|
+
font-size: 1rem;
|
|
94
|
+
font-weight: 700;
|
|
95
|
+
line-height: var(--book-heading-line-height);
|
|
96
|
+
margin-top: 1.25rem;
|
|
97
|
+
margin-bottom: 0.25rem;
|
|
98
|
+
letter-spacing: 0.07em;
|
|
99
|
+
text-transform: uppercase;
|
|
100
|
+
orphans: 2;
|
|
101
|
+
widows: 2;
|
|
102
|
+
page-break-after: avoid;
|
|
103
|
+
page-break-inside: avoid;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
h6 {
|
|
107
|
+
font-family: var(--font-heading);
|
|
108
|
+
font-size: 0.95rem;
|
|
109
|
+
font-weight: 700;
|
|
110
|
+
line-height: var(--book-heading-line-height);
|
|
111
|
+
margin-top: 1rem;
|
|
112
|
+
margin-bottom: 0.25rem;
|
|
113
|
+
letter-spacing: normal;
|
|
114
|
+
font-style: italic;
|
|
115
|
+
orphans: 2;
|
|
116
|
+
widows: 2;
|
|
117
|
+
page-break-after: avoid;
|
|
118
|
+
page-break-inside: avoid;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/* Navigation and TOC */
|
|
122
|
+
nav {
|
|
123
|
+
page-break-after: avoid;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
#TOC {
|
|
127
|
+
page-break-inside: auto;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
#TOC li {
|
|
131
|
+
list-style: none;
|
|
132
|
+
margin-bottom: 0.4em;
|
|
133
|
+
line-height: 1.4;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
#TOC a {
|
|
137
|
+
color: inherit;
|
|
138
|
+
text-decoration: none;
|
|
139
|
+
margin-bottom: 0.2em;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/* Page numbers in TOC — CSS Paged Media, print/PDF only.
|
|
143
|
+
Scoped here so strip-page-rules.js naturally excludes it from EPUB
|
|
144
|
+
(target-counter is unsupported by Kindle and all e-readers). */
|
|
145
|
+
@media print {
|
|
146
|
+
#TOC a {
|
|
147
|
+
display: flex;
|
|
148
|
+
justify-content: space-between;
|
|
149
|
+
align-items: baseline;
|
|
150
|
+
padding-right: 0;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
#TOC a::after {
|
|
154
|
+
content: target-counter(attr(href), page);
|
|
155
|
+
flex-shrink: 0;
|
|
156
|
+
margin-left: auto;
|
|
157
|
+
font-weight: normal;
|
|
158
|
+
white-space: nowrap;
|
|
159
|
+
font-family: var(--font-heading);
|
|
160
|
+
font-variant-numeric: lining-nums tabular-nums;
|
|
161
|
+
text-align: right;
|
|
162
|
+
width: 2.5em;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
#TOC ul {
|
|
167
|
+
padding-left: 1.5rem;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
#TOC > ul {
|
|
171
|
+
padding-left: 0.75rem;
|
|
172
|
+
padding-right: 0.75rem;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/* Top-level TOC entries (section headings) get extra weight */
|
|
176
|
+
#TOC > ul > li {
|
|
177
|
+
margin-bottom: 0.6em;
|
|
178
|
+
font-weight: 500;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/* Nested TOC entries (chapter titles) */
|
|
182
|
+
#TOC > ul > li > ul > li {
|
|
183
|
+
font-weight: 400;
|
|
184
|
+
font-size: 0.95em;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/* Small caps strategy:
|
|
188
|
+
• Screen: OpenType smcp/c2sc glyphs at natural size (no compensation)
|
|
189
|
+
• Print: font-size: inherit — Source Serif 4 provides real smcp glyphs
|
|
190
|
+
• EPUB: font-size: 1.05em compensation — e-readers often synthesize
|
|
191
|
+
small caps by scaling down uppercase, which renders shorter than
|
|
192
|
+
true OpenType glyphs. 1.05em brings visual height closer to x-height. */
|
|
193
|
+
|
|
194
|
+
/* Small Caps for Acronyms
|
|
195
|
+
* IMPORTANT: Do NOT add font-size reduction here.
|
|
196
|
+
* all-small-caps renders at x-height (matching lowercase).
|
|
197
|
+
* Adding font-size < 1em would make small caps shorter than lowercase letters.
|
|
198
|
+
*/
|
|
199
|
+
span.smallcaps {
|
|
200
|
+
font-variant-caps: all-small-caps;
|
|
201
|
+
letter-spacing: 0.05em;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/* Title Block Elements */
|
|
205
|
+
p.author,
|
|
206
|
+
p.subtitle,
|
|
207
|
+
p.date {
|
|
208
|
+
font-family: var(--font-heading);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
h1.title,
|
|
212
|
+
p.author,
|
|
213
|
+
p.subtitle,
|
|
214
|
+
p.date,
|
|
215
|
+
div.rights {
|
|
216
|
+
text-align: center;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
p.subtitle {
|
|
220
|
+
font-size: 1.15rem;
|
|
221
|
+
font-weight: 300;
|
|
222
|
+
line-height: 1.5;
|
|
223
|
+
font-style: italic;
|
|
224
|
+
color: var(--color-muted);
|
|
225
|
+
}
|
|
226
|
+
}
|