@udx/md2html 1.3.1 → 1.4.2

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/index.js CHANGED
@@ -289,11 +289,13 @@ async function buildHtml(srcDir, outputFile) {
289
289
  }
290
290
 
291
291
  // Process all mathematical formulas in the content (before image processing)
292
- // This pattern matches: $formula$ for inline math
293
- const inlineMathPattern = /\$(.*?)\$/g;
292
+ // This pattern matches: $formula$ for inline math, but NOT across newlines or table cells
293
+ // The [^\n$|] ensures we don't match across lines, other dollar signs, or table cell separators
294
+ const inlineMathPattern = /\$([^\n$|]+?)\$/g;
294
295
  combinedMarkdown = combinedMarkdown.replace(inlineMathPattern, (match, formula) => {
295
- // Skip if it's likely a currency symbol
296
- if (/^\s*\d+(\.\d+)?\s*$/.test(formula)) {
296
+ // Skip if it's likely a currency value (numbers with optional commas, decimals, K/M suffixes)
297
+ // Also skip if it starts with a number (likely currency like $22,945)
298
+ if (/^\s*[\d,]+(\.\d+)?[KMB]?\s*$/.test(formula) || /^\d/.test(formula.trim())) {
297
299
  return match;
298
300
  }
299
301
  return `\\(${formula}\\)`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@udx/md2html",
3
- "version": "1.3.1",
3
+ "version": "1.4.2",
4
4
  "description": "Magazine-quality Markdown to HTML converter with professional styling",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -1,10 +1,11 @@
1
1
  /* Chapter Navigation Styles */
2
2
  :root {
3
- --chapter-nav-width: 220px;
3
+ --chapter-nav-width: 264px;
4
4
  --chapter-nav-text-color: #1a1a1a;
5
5
  --chapter-nav-text-faded: rgba(51, 51, 51, 0.65);
6
6
  --chapter-nav-active-color: #991b1b;
7
7
  --chapter-text-size: 0.85rem;
8
+ --content-gap: 80px;
8
9
  }
9
10
 
10
11
  /* Container for the floating navigation */
@@ -16,16 +17,16 @@
16
17
  /* Floating navigation styles - clean and minimal */
17
18
  .chapter-navigation {
18
19
  position: fixed;
19
- top: 50%;
20
- transform: translateY(-50%);
21
- left: 20px;
20
+ top: 0;
21
+ left: 0;
22
22
  width: var(--chapter-nav-width);
23
- max-height: 80vh;
23
+ height: 100vh;
24
24
  overflow-y: auto;
25
- background-color: transparent;
26
- padding: 10px 0;
25
+ background-color: #fff;
26
+ padding: 40px 20px 60px 20px;
27
27
  z-index: 100;
28
- scrollbar-width: none; /* Hide scrollbar for Firefox */
28
+ scrollbar-width: thin; /* Show thin scrollbar for Firefox */
29
+ scrollbar-color: rgba(0, 0, 0, 0.2) transparent;
29
30
  transition: transform 0.3s ease;
30
31
  border: 0 none transparent !important;
31
32
  box-shadow: none !important;
@@ -34,9 +35,18 @@
34
35
  -moz-box-shadow: none !important;
35
36
  }
36
37
 
37
- /* Hide scrollbar for Chrome, Safari and Opera */
38
+ /* Show thin scrollbar for Chrome, Safari and Opera */
38
39
  .chapter-navigation::-webkit-scrollbar {
39
- display: none;
40
+ width: 4px;
41
+ }
42
+
43
+ .chapter-navigation::-webkit-scrollbar-track {
44
+ background: transparent;
45
+ }
46
+
47
+ .chapter-navigation::-webkit-scrollbar-thumb {
48
+ background-color: rgba(0, 0, 0, 0.2);
49
+ border-radius: 2px;
40
50
  }
41
51
 
42
52
  .chapter-nav-list {
@@ -181,14 +191,24 @@
181
191
  }
182
192
 
183
193
  /* Add padding to the content to prevent floating nav from overlapping */
194
+ /* Content fills the space to the right of the sidebar, article centers within it */
184
195
  .chapter-content {
185
- padding-left: calc(var(--chapter-nav-width) + 40px);
196
+ /* Position content to start right after the sidebar */
197
+ margin-left: var(--chapter-nav-width);
198
+ margin-right: 0;
199
+ /* Override Tailwind container max-width so content fills available space */
200
+ max-width: none !important;
201
+ width: auto !important;
202
+ /* Remove horizontal padding - let the article's mx-auto handle centering */
203
+ padding-left: 0;
204
+ padding-right: 0;
186
205
  }
187
206
 
188
207
  /* Responsive adjustments */
189
208
  @media (max-width: 1024px) {
190
209
  .chapter-content {
191
- padding-left: calc(var(--chapter-nav-width) + 30px);
210
+ margin-left: var(--chapter-nav-width);
211
+ margin-right: 0;
192
212
  }
193
213
  }
194
214
 
@@ -202,12 +222,14 @@
202
222
  }
203
223
 
204
224
  .chapter-content {
205
- padding-left: 20px;
206
- padding-right: 20px;
225
+ margin-left: 20px;
226
+ margin-right: 20px;
227
+ padding-left: 0;
228
+ padding-right: 0;
207
229
  }
208
230
  }
209
231
 
210
- /* Hide nav when printing */
232
+ /* Hide nav when printing - let browser print dialog control all margins */
211
233
  @media print {
212
234
  .chapter-navigation,
213
235
  .mobile-chapter-nav {
@@ -215,6 +237,12 @@
215
237
  }
216
238
 
217
239
  .chapter-content {
218
- padding-left: 0;
240
+ /* Remove all margins and padding so browser print dialog controls page margins */
241
+ margin-left: 0 !important;
242
+ margin-right: 0 !important;
243
+ padding-left: 0 !important;
244
+ padding-right: 0 !important;
245
+ max-width: 100% !important;
246
+ width: 100% !important;
219
247
  }
220
248
  }
package/static/scripts.js CHANGED
@@ -44,90 +44,16 @@ document.addEventListener('DOMContentLoaded', (event) => {
44
44
  }
45
45
  });
46
46
 
47
- // Smart table sizing - auto-fit columns based on content
47
+ // Table enhancement - add responsive wrapper and basic styling
48
+ // Note: We do NOT set inline styles for table-layout or width to avoid conflicts with CSS
48
49
  document.querySelectorAll('table').forEach(table => {
49
- // Use auto layout for smart column sizing
50
- table.style.tableLayout = 'auto';
51
- table.style.width = 'auto';
52
- table.style.maxWidth = '100%';
53
- table.classList.add('auto-size');
54
-
55
50
  // Add responsive wrapper if not already wrapped
56
51
  if (table.parentElement.tagName !== 'DIV' || !table.parentElement.classList.contains('table-responsive')) {
57
52
  const wrapper = document.createElement('div');
58
- wrapper.className = 'table-responsive overflow-x-auto my-8';
59
- wrapper.style.maxWidth = '100%';
53
+ wrapper.className = 'table-responsive';
60
54
  table.parentNode.insertBefore(wrapper, table);
61
55
  wrapper.appendChild(table);
62
56
  }
63
-
64
- // Analyze columns and apply smart sizing
65
- const rows = table.querySelectorAll('tr');
66
- if (rows.length > 0) {
67
- const headerCells = table.querySelectorAll('th');
68
- const numCols = headerCells.length || (rows[0] ? rows[0].querySelectorAll('td').length : 0);
69
-
70
- // Analyze each column's content
71
- for (let colIdx = 0; colIdx < numCols; colIdx++) {
72
- let isNumeric = true;
73
- let isCurrency = true;
74
- let isCompact = true;
75
- let maxLength = 0;
76
-
77
- rows.forEach(row => {
78
- const cells = row.querySelectorAll('th, td');
79
- if (cells[colIdx]) {
80
- const text = cells[colIdx].textContent.trim();
81
- maxLength = Math.max(maxLength, text.length);
82
-
83
- // Check if numeric (including decimals and commas)
84
- if (!/^[\d,.\-\s]+$/.test(text) && text !== '') {
85
- isNumeric = false;
86
- }
87
-
88
- // Check if currency (starts with $ or ends with .00)
89
- if (!/^\$?[\d,]+\.?\d*$/.test(text) && text !== '') {
90
- isCurrency = false;
91
- }
92
-
93
- // Compact if short content (less than 15 chars)
94
- if (text.length > 15) {
95
- isCompact = false;
96
- }
97
- }
98
- });
99
-
100
- // Apply column classes based on analysis
101
- rows.forEach(row => {
102
- const cells = row.querySelectorAll('th, td');
103
- if (cells[colIdx]) {
104
- if (isCurrency && maxLength <= 15) {
105
- cells[colIdx].classList.add('col-currency');
106
- } else if (isNumeric && maxLength <= 10) {
107
- cells[colIdx].classList.add('col-numeric');
108
- } else if (isCompact && maxLength <= 10) {
109
- cells[colIdx].classList.add('col-compact');
110
- } else {
111
- cells[colIdx].classList.add('col-text');
112
- }
113
- }
114
- });
115
- }
116
- }
117
-
118
- // Add proper classes and styles to table headers
119
- table.querySelectorAll('th').forEach(th => {
120
- th.classList.add('bg-gray-50');
121
- th.classList.add('font-semibold');
122
- th.style.padding = '0.5rem 0.75rem';
123
- th.style.borderBottom = '2px solid #e5e7eb';
124
- });
125
-
126
- // Add proper classes and styles to table cells
127
- table.querySelectorAll('td').forEach(td => {
128
- td.style.padding = '0.5rem 0.75rem';
129
- td.style.borderBottom = '1px solid #e5e7eb';
130
- });
131
57
  });
132
58
 
133
59
  // Remove any blue highlights
@@ -137,30 +63,6 @@ document.addEventListener('DOMContentLoaded', (event) => {
137
63
  el.style.boxShadow = 'none';
138
64
  });
139
65
 
140
- // Format tabular data with scaling operations
141
- document.querySelectorAll('p').forEach(p => {
142
- const text = p.textContent.trim();
143
- if (text.includes('IT/SRE for every') || text.includes('DevOps Engineer for every')) {
144
- // Find the paragraph containing the scaling information
145
- const container = document.createElement('div');
146
- container.className = 'scaling-table';
147
-
148
- // Parse the content and create a grid layout
149
- const content = p.textContent.trim();
150
- const parts = content.split(',').map(part => part.trim());
151
-
152
- parts.forEach(part => {
153
- const itemDiv = document.createElement('div');
154
- itemDiv.textContent = part;
155
- itemDiv.className = 'scaling-item';
156
- container.appendChild(itemDiv);
157
- });
158
-
159
- // Replace the paragraph with the grid container
160
- p.parentNode.replaceChild(container, p);
161
- }
162
- });
163
-
164
66
  // Process quote attributions with em dash
165
67
  document.querySelectorAll('blockquote + p').forEach(p => {
166
68
  const text = p.textContent || '';
@@ -227,10 +129,11 @@ document.addEventListener('DOMContentLoaded', (event) => {
227
129
 
228
130
  window.updateActiveChapter = () => {
229
131
  try {
230
- // Only target H2 headings
231
- const headings = Array.from(document.querySelectorAll('h2'));
132
+ // Target H2 and H3 headings for navigation
133
+ const allHeadings = Array.from(document.querySelectorAll('h2, h3'));
134
+ const h2Headings = Array.from(document.querySelectorAll('h2'));
232
135
 
233
- if (!headings.length || !chapterNavItems.length) return;
136
+ if (!allHeadings.length || !chapterNavItems.length) return;
234
137
 
235
138
  // Calculate which heading is most visible in the viewport
236
139
  const viewportHeight = window.innerHeight;
@@ -239,7 +142,7 @@ document.addEventListener('DOMContentLoaded', (event) => {
239
142
  let bestVisibleHeading = null;
240
143
  let bestVisibleScore = -1;
241
144
 
242
- headings.forEach(heading => {
145
+ allHeadings.forEach(heading => {
243
146
  if (!heading) return;
244
147
 
245
148
  const rect = heading.getBoundingClientRect();
@@ -261,10 +164,29 @@ document.addEventListener('DOMContentLoaded', (event) => {
261
164
  }
262
165
  });
263
166
 
167
+ // Find the parent H2 for the current heading (if it's an H3)
168
+ const findParentH2 = (heading) => {
169
+ if (!heading || heading.tagName === 'H2') return heading;
170
+
171
+ // Walk backwards through all headings to find the parent H2
172
+ const headingIndex = allHeadings.indexOf(heading);
173
+ for (let i = headingIndex - 1; i >= 0; i--) {
174
+ if (allHeadings[i].tagName === 'H2') {
175
+ return allHeadings[i];
176
+ }
177
+ }
178
+ return null;
179
+ };
180
+
264
181
  if (bestVisibleHeading) {
265
182
  const headingId = bestVisibleHeading.getAttribute('id');
266
183
  const headingText = bestVisibleHeading.textContent.trim();
267
184
 
185
+ // Get parent H2 if current heading is H3
186
+ const parentH2 = findParentH2(bestVisibleHeading);
187
+ const parentH2Text = parentH2 ? parentH2.textContent.trim() : null;
188
+ const parentH2Id = parentH2 ? parentH2.getAttribute('id') : null;
189
+
268
190
  chapterNavItems.forEach(item => {
269
191
  if (!item) return;
270
192
 
@@ -272,22 +194,30 @@ document.addEventListener('DOMContentLoaded', (event) => {
272
194
  if (!navLink) return;
273
195
 
274
196
  const itemText = navLink.textContent.trim();
275
- const isActive = itemText === headingText || item.getAttribute('data-chapter-id') === headingId;
197
+ const itemId = item.getAttribute('data-chapter-id');
198
+
199
+ // Check if this nav item matches the current heading OR its parent H2
200
+ const isCurrentHeading = itemText === headingText || itemId === headingId;
201
+ const isParentSection = parentH2 && (itemText === parentH2Text || itemId === parentH2Id);
202
+ const isActive = isCurrentHeading || isParentSection;
276
203
 
277
204
  if (isActive) {
278
205
  item.classList.add('active');
279
206
 
280
- const navContainer = document.querySelector('.chapter-navigation');
281
- if (navContainer) {
282
- const itemOffset = item.offsetTop;
283
- const navHeight = navContainer.offsetHeight;
284
- const itemHeight = item.offsetHeight;
207
+ // Only scroll to and update text for the most specific (current) heading
208
+ if (isCurrentHeading) {
209
+ const navContainer = document.querySelector('.chapter-navigation');
210
+ if (navContainer) {
211
+ const itemOffset = item.offsetTop;
212
+ const navHeight = navContainer.offsetHeight;
213
+ const itemHeight = item.offsetHeight;
214
+
215
+ navContainer.scrollTop = itemOffset - (navHeight / 2) + (itemHeight / 2);
216
+ }
285
217
 
286
- navContainer.scrollTop = itemOffset - (navHeight / 2) + (itemHeight / 2);
287
- }
288
-
289
- if (currentChapterText) {
290
- currentChapterText.textContent = itemText;
218
+ if (currentChapterText) {
219
+ currentChapterText.textContent = itemText;
220
+ }
291
221
  }
292
222
  } else {
293
223
  item.classList.remove('active');
@@ -302,7 +232,10 @@ document.addEventListener('DOMContentLoaded', (event) => {
302
232
  if (!link) return;
303
233
 
304
234
  const itemText = link.textContent.trim();
305
- const isActive = itemText === headingText || item.getAttribute('data-chapter-id') === headingId;
235
+ const itemId = item.getAttribute('data-chapter-id');
236
+ const isCurrentHeading = itemText === headingText || itemId === headingId;
237
+ const isParentSection = parentH2 && (itemText === parentH2Text || itemId === parentH2Id);
238
+ const isActive = isCurrentHeading || isParentSection;
306
239
 
307
240
  if (isActive) {
308
241
  item.classList.add('active');
@@ -310,8 +243,8 @@ document.addEventListener('DOMContentLoaded', (event) => {
310
243
  item.classList.remove('active');
311
244
  }
312
245
  });
313
- } else if (headings.length > 0) {
314
- const firstHeading = headings[0];
246
+ } else if (h2Headings.length > 0) {
247
+ const firstHeading = h2Headings[0];
315
248
  const firstHeadingText = firstHeading.textContent.trim();
316
249
 
317
250
  chapterNavItems.forEach(item => {
package/static/styles.css CHANGED
@@ -1,4 +1,10 @@
1
1
  @media print {
2
+ /* Remove all margins so browser print dialog controls page margins */
3
+ html, body {
4
+ margin: 0 !important;
5
+ padding: 0 !important;
6
+ }
7
+
2
8
  pre, pre code {
3
9
  white-space: pre-wrap !important;
4
10
  overflow-x: hidden !important;
@@ -27,11 +33,15 @@
27
33
  .content-container {
28
34
  max-width: 100% !important;
29
35
  width: 100% !important;
36
+ margin: 0 !important;
37
+ padding: 0 !important;
30
38
  }
31
39
 
32
- article {
40
+ article, main, section {
33
41
  width: 100% !important;
34
42
  max-width: 100% !important;
43
+ margin: 0 !important;
44
+ padding: 0 !important;
35
45
  }
36
46
  }
37
47
 
@@ -47,10 +57,10 @@ body {
47
57
 
48
58
  .content-container {
49
59
  width: 100%;
50
- max-width: 768px;
60
+ max-width: 800px;
51
61
  margin: 0 auto;
52
62
  padding: 2rem;
53
- font-size: 18px !important;
63
+ font-size: 20px !important;
54
64
  /* Magazine-style container */
55
65
  }
56
66
 
@@ -63,7 +73,7 @@ html:not(:has(details[open])) {
63
73
  .prose p {
64
74
  margin-top: 0 !important;
65
75
  margin-bottom: 0 !important;
66
- font-size: 18px !important;
76
+ font-size: 20px !important;
67
77
  line-height: 1.6 !important;
68
78
  }
69
79
 
@@ -88,7 +98,7 @@ html:not(:has(details[open])) {
88
98
  }
89
99
 
90
100
  .prose li {
91
- font-size: 18px !important;
101
+ font-size: 20px !important;
92
102
  margin-bottom: 0.5em !important;
93
103
  line-height: 1.6 !important;
94
104
  position: relative !important;
@@ -182,42 +192,41 @@ blockquote + p {
182
192
  margin-top: 2em;
183
193
  }
184
194
 
185
- /* Enhanced table styling with true full width enforcement */
195
+ /* Enhanced table styling - use auto layout for natural column sizing */
186
196
  .prose table,
187
197
  table.w-full,
188
198
  article table,
189
199
  div table,
190
200
  .table-responsive table {
191
- width: 100% !important;
192
- min-width: 100% !important;
193
- max-width: 100% !important;
194
- margin: 2em 0 !important;
195
- border-collapse: collapse !important;
196
- table-layout: fixed !important;
197
- display: table !important;
201
+ width: 100%;
202
+ margin: 2em 0;
203
+ border-collapse: collapse;
204
+ table-layout: auto;
205
+ display: table;
198
206
  }
199
207
 
200
208
  /* Table wrapper to handle overflow properly */
201
209
  .table-responsive,
202
210
  div.overflow-x-auto {
203
- width: 100% !important;
204
- min-width: 100% !important;
205
- max-width: 100% !important;
206
- overflow-x: auto !important;
207
- margin: 2em 0 !important;
208
- display: block !important;
211
+ width: 100%;
212
+ max-width: 100%;
213
+ overflow-x: auto;
214
+ margin: 2em 0;
215
+ display: block;
209
216
  }
210
217
 
211
218
  .prose table th, .prose table td {
212
- padding: 0.75em 1em !important;
213
- border: 1px solid rgba(0, 0, 0, 0.1) !important;
214
- text-align: left !important;
215
- vertical-align: top !important;
219
+ padding: 0.75em 1em;
220
+ border: 1px solid rgba(0, 0, 0, 0.1);
221
+ text-align: left;
222
+ vertical-align: top;
223
+ word-wrap: break-word;
224
+ overflow-wrap: break-word;
216
225
  }
217
226
 
218
227
  .prose table th {
219
- font-weight: 600 !important;
220
- background-color: rgba(0, 0, 0, 0.05) !important;
228
+ font-weight: 600;
229
+ background-color: rgba(0, 0, 0, 0.05);
221
230
  }
222
231
 
223
232
  /* Grid-based tables for special formatting needs */
@@ -709,48 +718,30 @@ main > svg,
709
718
  }
710
719
 
711
720
  /* ============================================
712
- SMART TABLE SIZING
721
+ TABLE STYLING
713
722
  ============================================ */
714
723
 
715
- /* Auto-sized tables - columns fit content */
716
- table.auto-size {
724
+ /* Tables use auto layout to fit content naturally */
725
+ table {
717
726
  table-layout: auto;
718
- width: auto;
719
- max-width: 100%;
720
- }
721
-
722
- /* Compact columns for short content (numbers, codes) */
723
- table .col-compact {
724
- width: 1%;
725
- white-space: nowrap;
726
- }
727
-
728
- /* Numeric columns - right aligned, compact */
729
- table .col-numeric {
730
- width: 1%;
731
- white-space: nowrap;
732
- text-align: right;
733
- font-variant-numeric: tabular-nums;
734
- }
735
-
736
- /* Currency columns */
737
- table .col-currency {
738
- width: 1%;
739
- white-space: nowrap;
740
- text-align: right;
741
- font-variant-numeric: tabular-nums;
727
+ width: 100%;
728
+ border-collapse: collapse;
742
729
  }
743
730
 
744
- /* Description/text columns - expand to fill */
745
- table .col-text {
746
- width: auto;
731
+ /* Ensure table cells don't overlap */
732
+ table th,
733
+ table td {
734
+ padding: 0.75em 1em;
735
+ border: 1px solid rgba(0, 0, 0, 0.1);
736
+ text-align: left;
737
+ vertical-align: top;
738
+ word-wrap: break-word;
739
+ overflow-wrap: break-word;
747
740
  }
748
741
 
749
- /* Shrink-to-fit table wrapper */
750
- .table-auto-wrapper {
751
- display: inline-block;
752
- max-width: 100%;
753
- overflow-x: auto;
742
+ table th {
743
+ font-weight: 600;
744
+ background-color: rgba(0, 0, 0, 0.05);
754
745
  }
755
746
 
756
747
  /* Print table sizing */
@@ -3,8 +3,8 @@
3
3
 
4
4
  body {
5
5
  font-family: "Times New Roman", Times, Georgia, serif;
6
- font-size: 12pt;
7
- line-height: 1.5;
6
+ font-size: 11pt;
7
+ line-height: 1.4;
8
8
  }
9
9
 
10
10
  .content-container {
@@ -12,55 +12,62 @@ body {
12
12
  padding: 1in;
13
13
  }
14
14
 
15
+ @media print {
16
+ .content-container {
17
+ padding: 1.25in !important;
18
+ max-width: 6in !important;
19
+ }
20
+ }
21
+
15
22
  /* Formal heading styles */
16
23
  .prose h1, h1 {
17
- font-size: 18pt !important;
24
+ font-size: 16pt !important;
18
25
  font-weight: bold !important;
19
26
  text-align: center !important;
20
- margin-bottom: 24pt !important;
27
+ margin-bottom: 20pt !important;
21
28
  font-family: "Times New Roman", Times, Georgia, serif !important;
22
29
  }
23
30
 
24
31
  .prose h2, h2 {
25
- font-size: 14pt !important;
32
+ font-size: 13pt !important;
26
33
  font-weight: bold !important;
27
- margin-top: 18pt !important;
28
- margin-bottom: 12pt !important;
34
+ margin-top: 16pt !important;
35
+ margin-bottom: 10pt !important;
29
36
  font-family: "Times New Roman", Times, Georgia, serif !important;
30
37
  }
31
38
 
32
39
  .prose h3, h3 {
33
- font-size: 12pt !important;
40
+ font-size: 11pt !important;
34
41
  font-weight: bold !important;
35
- margin-top: 12pt !important;
42
+ margin-top: 10pt !important;
36
43
  margin-bottom: 6pt !important;
37
44
  font-family: "Times New Roman", Times, Georgia, serif !important;
38
45
  }
39
46
 
40
47
  .prose h4, h4, .prose h5, h5, .prose h6, h6 {
41
- font-size: 12pt !important;
48
+ font-size: 11pt !important;
42
49
  font-weight: bold !important;
43
50
  font-style: italic !important;
44
- margin-top: 12pt !important;
45
- margin-bottom: 6pt !important;
51
+ margin-top: 10pt !important;
52
+ margin-bottom: 5pt !important;
46
53
  font-family: "Times New Roman", Times, Georgia, serif !important;
47
54
  }
48
55
 
49
56
  .prose p, p {
50
- font-size: 12pt !important;
57
+ font-size: 11pt !important;
51
58
  text-align: justify !important;
52
- margin-bottom: 12pt !important;
59
+ margin-bottom: 10pt !important;
53
60
  font-family: "Times New Roman", Times, Georgia, serif !important;
54
61
  }
55
62
 
56
63
  .prose li {
57
- font-size: 12pt !important;
64
+ font-size: 11pt !important;
58
65
  font-family: "Times New Roman", Times, Georgia, serif !important;
59
66
  }
60
67
 
61
68
  /* Table styling for government documents */
62
69
  .prose table {
63
- font-size: 10pt !important;
70
+ font-size: 9pt !important;
64
71
  border-collapse: collapse !important;
65
72
  }
66
73
 
@@ -121,7 +128,9 @@ figure img {
121
128
  /* Print-optimized styling */
122
129
  @media print {
123
130
  body {
124
- font-size: 12pt !important;
131
+ font-size: 11pt !important;
132
+ margin: 0 !important;
133
+ padding: 0 !important;
125
134
  }
126
135
 
127
136
  .chapter-navigation, .mobile-chapter-nav {
@@ -130,5 +139,11 @@ figure img {
130
139
 
131
140
  .chapter-content {
132
141
  padding-left: 0 !important;
142
+ margin: 0 !important;
143
+ }
144
+
145
+ /* Ensure no content bleeds to edges */
146
+ * {
147
+ box-sizing: border-box !important;
133
148
  }
134
149
  }