md2pdf2 0.2.0 → 0.2.1

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.
@@ -292,7 +292,7 @@ function getDevHTML(port) {
292
292
  <div class="toast" id="toast"><span class="toast-dot"></span><span id="toastMsg">Reloading...</span></div>
293
293
  <div class="sidebar">
294
294
  <div class="sidebar-header">
295
- <h1>Templates</h1>
295
+ <h1>md2pdf2</h1>
296
296
  <p id="currentTemplate"><span style="color: #22c55e;">●</span> Watching for changes</p>
297
297
  </div>
298
298
  <div class="template-list" id="templateList"></div>
@@ -1 +1 @@
1
- {"version":3,"file":"template-engine.d.ts","sourceRoot":"","sources":["../src/template-engine.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,QAAQ,CAAkD;gBAEtD,MAAM,EAAE,YAAY;IAUhC,OAAO,CAAC,eAAe;YAST,sBAAsB;IAW9B,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKvD,mBAAmB,IAAI,IAAI;IAiD3B,OAAO,CAAC,eAAe;IAIvB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAIpD,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;CAQlF"}
1
+ {"version":3,"file":"template-engine.d.ts","sourceRoot":"","sources":["../src/template-engine.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,QAAQ,CAAkD;gBAEtD,MAAM,EAAE,YAAY;IAUhC,OAAO,CAAC,eAAe;YAaT,sBAAsB;IAW9B,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKvD,mBAAmB,IAAI,IAAI;IAiD3B,OAAO,CAAC,eAAe;IAIvB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAIpD,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;CASlF"}
@@ -18,6 +18,11 @@ export class TemplateEngine {
18
18
  Handlebars.registerHelper('currentDate', () => {
19
19
  return new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' });
20
20
  });
21
+ Handlebars.registerHelper('slice', (str, start, end) => {
22
+ if (typeof str !== 'string')
23
+ return '';
24
+ return str.slice(start, end);
25
+ });
21
26
  }
22
27
  async loadPartialsFromConfig(partialsConfig) {
23
28
  for (const [name, path] of Object.entries(partialsConfig)) {
@@ -93,7 +98,8 @@ export class TemplateEngine {
93
98
  content,
94
99
  frontMatter,
95
100
  styles,
96
- partials: this.partials
101
+ partials: this.partials,
102
+ ...frontMatter
97
103
  });
98
104
  }
99
105
  }
@@ -1 +1 @@
1
- {"version":3,"file":"template-engine.js","sourceRoot":"","sources":["../src/template-engine.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAG3C,MAAM,OAAO,cAAc;IACjB,QAAQ,CAA8B;IACtC,QAAQ,GAA+C,EAAE,CAAC;IAElE,YAAY,MAAoB;QAC9B,4BAA4B;QAC5B,IAAI,CAAC,eAAe,EAAE,CAAC;QAEvB,wCAAwC;QACxC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACpB,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAEO,eAAe;QACrB,UAAU,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC,IAAY,EAAE,EAAE;YACvD,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QACH,UAAU,CAAC,cAAc,CAAC,aAAa,EAAE,GAAG,EAAE;YAC5C,OAAO,IAAI,IAAI,EAAE,CAAC,kBAAkB,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC;QACpG,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,sBAAsB,CAAC,cAAsC;QACzE,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;YAC1D,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;gBAC1C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACpD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,oCAAoC,IAAI,UAAU,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC;YACnF,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,YAAoB;QACrC,MAAM,eAAe,GAAG,MAAM,aAAa,CAAC,YAAY,CAAC,CAAC;QAC1D,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC;IACxD,CAAC;IAED,mBAAmB;QACjB,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA4CpB,CAAC;QACL,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC;IACxD,CAAC;IAEO,eAAe,CAAC,OAAe;QACrC,OAAO,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,eAAe,CAAC,IAAY,EAAE,OAAe;QAC3C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,CAAC,OAAe,EAAE,WAAgC,EAAE,MAAc;QACtE,OAAO,IAAI,CAAC,QAAQ,CAAC;YACnB,OAAO;YACP,WAAW;YACX,MAAM;YACN,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC,CAAC;IACL,CAAC;CACF"}
1
+ {"version":3,"file":"template-engine.js","sourceRoot":"","sources":["../src/template-engine.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAG3C,MAAM,OAAO,cAAc;IACjB,QAAQ,CAA8B;IACtC,QAAQ,GAA+C,EAAE,CAAC;IAElE,YAAY,MAAoB;QAC9B,4BAA4B;QAC5B,IAAI,CAAC,eAAe,EAAE,CAAC;QAEvB,wCAAwC;QACxC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACpB,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAEO,eAAe;QACrB,UAAU,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC,IAAY,EAAE,EAAE;YACvD,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QACH,UAAU,CAAC,cAAc,CAAC,aAAa,EAAE,GAAG,EAAE;YAC5C,OAAO,IAAI,IAAI,EAAE,CAAC,kBAAkB,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC;QACpG,CAAC,CAAC,CAAC;QACH,UAAU,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,GAAW,EAAE,KAAa,EAAE,GAAY,EAAE,EAAE;YAC9E,IAAI,OAAO,GAAG,KAAK,QAAQ;gBAAE,OAAO,EAAE,CAAC;YACvC,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,sBAAsB,CAAC,cAAsC;QACzE,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;YAC1D,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;gBAC1C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACpD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,oCAAoC,IAAI,UAAU,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC;YACnF,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,YAAoB;QACrC,MAAM,eAAe,GAAG,MAAM,aAAa,CAAC,YAAY,CAAC,CAAC;QAC1D,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC;IACxD,CAAC;IAED,mBAAmB;QACjB,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA4CpB,CAAC;QACL,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC;IACxD,CAAC;IAEO,eAAe,CAAC,OAAe;QACrC,OAAO,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,eAAe,CAAC,IAAY,EAAE,OAAe;QAC3C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,CAAC,OAAe,EAAE,WAAgC,EAAE,MAAc;QACtE,OAAO,IAAI,CAAC,QAAQ,CAAC;YACnB,OAAO;YACP,WAAW;YACX,MAAM;YACN,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,GAAG,WAAW;SACf,CAAC,CAAC;IACL,CAAC;CACF"}
package/package.json CHANGED
@@ -1,12 +1,20 @@
1
1
  {
2
2
  "name": "md2pdf2",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Convert Markdown to PDF using customizable templates",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",
7
7
  "bin": {
8
8
  "md2pdf2": "dist/cli.js"
9
9
  },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "tsc --watch",
13
+ "start": "node dist/cli.js",
14
+ "test": "node dist/cli.js convert examples/demo.md -o demo.pdf",
15
+ "lint": "eslint src --ext .ts",
16
+ "prepublishOnly": "npm run build"
17
+ },
10
18
  "keywords": [
11
19
  "markdown",
12
20
  "pdf",
@@ -45,12 +53,5 @@
45
53
  "files": [
46
54
  "dist",
47
55
  "templates"
48
- ],
49
- "scripts": {
50
- "build": "tsc",
51
- "dev": "tsc --watch",
52
- "start": "node dist/cli.js",
53
- "test": "node dist/cli.js convert examples/demo.md -o demo.pdf",
54
- "lint": "eslint src --ext .ts"
55
- }
56
- }
56
+ ]
57
+ }
@@ -2,118 +2,215 @@
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>{{#if frontMatter.title}}{{frontMatter.title}}{{else}}Newsletter{{/if}}</title>
5
+ <title>{{title}}</title>
7
6
  <style>
7
+ * { box-sizing: border-box; margin: 0; padding: 0; }
8
+
8
9
  body {
9
- font-family: system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
10
- line-height: 1.65;
11
- color: #1a1a1a;
12
- max-width: 600px;
13
- margin: 0 auto;
14
- padding: 0;
15
- background: #f9f9f9;
16
- }
17
- .container {
18
- background: #ffffff;
19
- padding: 40px 50px;
20
- margin: 20px 0;
21
- border-radius: 8px;
22
- }
23
- .header {
24
- text-align: center;
25
- padding-bottom: 30px;
26
- border-bottom: 1px solid #eee;
27
- margin-bottom: 30px;
28
- }
29
- .header h1 {
30
- font-size: 1.75rem;
31
- margin: 0 0 8px 0;
32
- color: #111;
33
- }
34
- .header .date {
35
- font-size: 0.85rem;
36
- color: #888;
37
- }
38
- .content h2 {
39
- font-size: 1.35rem;
40
- margin-top: 2rem;
41
- margin-bottom: 0.75rem;
42
- color: #111;
43
- }
44
- .content h3 {
45
- font-size: 1.1rem;
46
- margin-top: 1.5rem;
47
- margin-bottom: 0.5rem;
48
- }
49
- .content p {
50
- margin-bottom: 1rem;
10
+ font-family: Georgia, 'Times New Roman', serif;
11
+ font-size: 11pt;
12
+ line-height: 1.8;
51
13
  color: #333;
52
- }
53
- .content a {
54
- color: #0066cc;
55
- text-decoration: underline;
56
- }
57
- .content code {
58
- background: #f0f0f0;
59
- padding: 0.15em 0.4em;
60
- border-radius: 3px;
61
- font-size: 0.9em;
62
- font-family: 'SF Mono', Monaco, monospace;
63
- }
64
- .content pre {
65
- background: #f5f5f5;
66
- padding: 1rem;
67
- border-radius: 6px;
68
- overflow-x: auto;
69
- font-size: 0.85rem;
70
- line-height: 1.5;
71
- }
72
- .content pre code { background: none; padding: 0; }
73
- .content blockquote {
74
- border-left: 3px solid #0066cc;
75
- margin: 1.25rem 0;
76
- padding: 0.25rem 0 0.25rem 1rem;
77
- color: #555;
14
+ background: #f0ebe3;
15
+ }
16
+
17
+ /* ── WRAPPER ── */
18
+ .wrapper {
19
+ max-width: 680px;
20
+ margin: 32px auto;
21
+ background: #fff;
22
+ border: 1px solid #ddd;
23
+ box-shadow: 0 2px 20px rgba(0,0,0,0.08);
24
+ }
25
+
26
+ /* ── MASTHEAD ── */
27
+ .masthead {
28
+ background: #1a1a1a;
29
+ color: white;
30
+ padding: 48px 56px 36px;
31
+ text-align: center;
32
+ position: relative;
33
+ overflow: hidden;
34
+ }
35
+
36
+ .masthead::before {
37
+ content: '';
38
+ position: absolute;
39
+ top: 0; left: 0; right: 0;
40
+ height: 4px;
41
+ background: linear-gradient(90deg, #d4a437, #e8c46a, #d4a437);
42
+ }
43
+
44
+ .masthead-label {
45
+ font-family: -apple-system, 'Helvetica Neue', sans-serif;
46
+ font-size: 8pt;
47
+ letter-spacing: 4px;
48
+ text-transform: uppercase;
49
+ color: #d4a437;
50
+ margin-bottom: 14px;
51
+ }
52
+
53
+ .masthead h1 {
54
+ font-size: 30pt;
55
+ font-weight: 700;
56
+ letter-spacing: -0.5px;
57
+ line-height: 1.1;
58
+ margin-bottom: 10px;
59
+ color: white;
60
+ }
61
+
62
+ .masthead-meta {
63
+ font-family: -apple-system, 'Helvetica Neue', sans-serif;
64
+ font-size: 9pt;
65
+ color: rgba(255,255,255,0.5);
66
+ letter-spacing: 0.5px;
67
+ }
68
+
69
+ /* ── BODY ── */
70
+ .body {
71
+ padding: 48px 56px;
72
+ }
73
+
74
+ h1 { display: none; } /* Used in masthead */
75
+
76
+ h2 {
77
+ font-size: 17pt;
78
+ font-weight: 700;
79
+ color: #1a1a1a;
80
+ margin-top: 2em;
81
+ margin-bottom: 0.5em;
82
+ line-height: 1.2;
83
+ position: relative;
84
+ padding-bottom: 10px;
85
+ }
86
+ h2::after {
87
+ content: '';
88
+ position: absolute;
89
+ bottom: 0; left: 0;
90
+ width: 40px; height: 3px;
91
+ background: #d4a437;
92
+ }
93
+
94
+ h3 {
95
+ font-size: 13pt;
96
+ color: #222;
97
+ margin-top: 1.5em;
98
+ margin-bottom: 0.4em;
99
+ }
100
+
101
+ p { margin-bottom: 1em; }
102
+
103
+ p:first-of-type::first-letter {
104
+ font-size: 3em;
105
+ font-weight: 700;
106
+ float: left;
107
+ line-height: 0.75;
108
+ padding-right: 8px;
109
+ padding-top: 4px;
110
+ color: #d4a437;
111
+ }
112
+
113
+ blockquote {
114
+ border-left: 3px solid #d4a437;
115
+ margin: 1.8em 0;
116
+ padding: 16px 24px;
117
+ background: #fdf8f0;
78
118
  font-style: italic;
119
+ font-size: 12pt;
120
+ color: #555;
79
121
  }
80
- .content ul, .content ol {
81
- padding-left: 1.5rem;
82
- margin-bottom: 1rem;
83
- }
84
- .content li { margin-bottom: 0.5rem; }
85
- .highlight {
86
- background: #fff3cd;
87
- padding: 15px 20px;
88
- border-radius: 6px;
89
- margin: 1.25rem 0;
122
+
123
+ a { color: #b8860b; }
124
+
125
+ ul, ol { margin: 0.8em 0 0.8em 1.6em; }
126
+ li { margin-bottom: 0.4em; }
127
+
128
+ hr {
129
+ border: none;
130
+ text-align: center;
131
+ margin: 2em 0;
132
+ color: #ccc;
133
+ }
134
+ hr::before {
135
+ content: '— ◆ —';
136
+ letter-spacing: 6px;
137
+ color: #ccc;
138
+ font-size: 9pt;
139
+ }
140
+
141
+ table {
142
+ width: 100%;
143
+ border-collapse: collapse;
144
+ margin: 1.5em 0;
145
+ font-size: 10pt;
146
+ }
147
+ th {
148
+ background: #1a1a1a;
149
+ color: white;
150
+ padding: 8px 14px;
151
+ text-align: left;
152
+ font-family: -apple-system, sans-serif;
153
+ font-size: 9pt;
154
+ letter-spacing: 0.5px;
155
+ }
156
+ td {
157
+ padding: 8px 14px;
158
+ border-bottom: 1px solid #eee;
90
159
  }
160
+ tr:nth-child(even) td { background: #fdf8f0; }
161
+
162
+ code {
163
+ font-family: 'SF Mono', monospace;
164
+ font-size: 9pt;
165
+ background: #f5f0e8;
166
+ padding: 1px 5px;
167
+ border-radius: 2px;
168
+ }
169
+
170
+ /* ── FOOTER ── */
91
171
  .footer {
172
+ background: #1a1a1a;
173
+ color: rgba(255,255,255,0.5);
92
174
  text-align: center;
93
- padding-top: 30px;
94
- margin-top: 40px;
95
- border-top: 1px solid #eee;
96
- font-size: 0.85rem;
97
- color: #888;
98
- }
175
+ padding: 28px 56px;
176
+ font-family: -apple-system, 'Helvetica Neue', sans-serif;
177
+ font-size: 8.5pt;
178
+ letter-spacing: 0.3px;
179
+ }
180
+
181
+ .footer a { color: #d4a437; }
182
+
183
+ /* ── PRINT ── */
99
184
  @media print {
100
- body { background: #fff; }
101
- .container { box-shadow: none; margin: 0; }
185
+ body { background: white; }
186
+ .wrapper { box-shadow: none; border: none; margin: 0; }
187
+ .masthead { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
188
+ .footer { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
102
189
  }
103
190
  </style>
104
191
  </head>
105
192
  <body>
106
- <div class="container">
107
- <div class="header">
108
- <h1>{{#if frontMatter.title}}{{frontMatter.title}}{{else}}Newsletter{{/if}}</h1>
109
- <div class="date">{{#if frontMatter.date}}{{frontMatter.date}}{{else}}{{currentDate}}{{/if}}</div>
193
+ <div class="wrapper">
194
+
195
+ <div class="masthead">
196
+ <div class="masthead-label">Newsletter</div>
197
+ <h1>{{#if title}}{{title}}{{else}}The Weekly Brief{{/if}}</h1>
198
+ <div class="masthead-meta">
199
+ {{#if author}}By {{author}} · {{/if}}{{#if date}}{{date}}{{/if}}
200
+ </div>
110
201
  </div>
111
- <div class="content">
202
+
203
+ <div class="body">
112
204
  {{{content}}}
113
205
  </div>
206
+
114
207
  <div class="footer">
115
- Generated with md2pdf2
208
+ {{#if footer_text}}{{footer_text}}{{else}}
209
+ You're receiving this because you subscribed. ·
210
+ <a href="#">Unsubscribe</a>
211
+ {{/if}}
116
212
  </div>
213
+
117
214
  </div>
118
215
  </body>
119
216
  </html>
@@ -0,0 +1,261 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>{{title}}</title>
7
+ <style>
8
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Playfair+Display:wght@700&display=swap');
9
+
10
+ * { box-sizing: border-box; margin: 0; padding: 0; }
11
+
12
+ body {
13
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
14
+ font-size: 11pt;
15
+ line-height: 1.7;
16
+ color: #1a1a2e;
17
+ background: #fff;
18
+ }
19
+
20
+ /* ── COVER PAGE ── */
21
+ .cover {
22
+ min-height: 100vh;
23
+ display: flex;
24
+ flex-direction: column;
25
+ justify-content: space-between;
26
+ background: linear-gradient(135deg, #0f3460 0%, #16213e 60%, #1a1a2e 100%);
27
+ color: white;
28
+ padding: 80px 72px;
29
+ page-break-after: always;
30
+ position: relative;
31
+ overflow: hidden;
32
+ }
33
+
34
+ .cover::before {
35
+ content: '';
36
+ position: absolute;
37
+ top: -100px; right: -100px;
38
+ width: 500px; height: 500px;
39
+ background: radial-gradient(circle, rgba(233,69,96,0.25) 0%, transparent 70%);
40
+ border-radius: 50%;
41
+ }
42
+
43
+ .cover::after {
44
+ content: '';
45
+ position: absolute;
46
+ bottom: -80px; left: -80px;
47
+ width: 400px; height: 400px;
48
+ background: radial-gradient(circle, rgba(22,158,255,0.2) 0%, transparent 70%);
49
+ border-radius: 50%;
50
+ }
51
+
52
+ .cover-logo {
53
+ font-size: 13pt;
54
+ font-weight: 600;
55
+ letter-spacing: 3px;
56
+ text-transform: uppercase;
57
+ opacity: 0.7;
58
+ z-index: 1;
59
+ }
60
+
61
+ .cover-main { z-index: 1; }
62
+
63
+ .cover-tag {
64
+ display: inline-block;
65
+ background: rgba(233,69,96,0.9);
66
+ color: white;
67
+ font-size: 8pt;
68
+ font-weight: 600;
69
+ letter-spacing: 2px;
70
+ text-transform: uppercase;
71
+ padding: 6px 14px;
72
+ border-radius: 2px;
73
+ margin-bottom: 28px;
74
+ }
75
+
76
+ .cover h1 {
77
+ font-family: 'Playfair Display', Georgia, serif;
78
+ font-size: 42pt;
79
+ font-weight: 700;
80
+ line-height: 1.1;
81
+ margin-bottom: 20px;
82
+ letter-spacing: -0.5px;
83
+ }
84
+
85
+ .cover-subtitle {
86
+ font-size: 14pt;
87
+ font-weight: 300;
88
+ opacity: 0.75;
89
+ max-width: 480px;
90
+ }
91
+
92
+ .cover-footer {
93
+ z-index: 1;
94
+ display: flex;
95
+ justify-content: space-between;
96
+ align-items: flex-end;
97
+ border-top: 1px solid rgba(255,255,255,0.15);
98
+ padding-top: 24px;
99
+ }
100
+
101
+ .cover-meta { font-size: 10pt; opacity: 0.65; }
102
+ .cover-meta strong { display: block; opacity: 1; font-weight: 500; }
103
+
104
+ /* ── CONTENT ── */
105
+ .content {
106
+ max-width: 720px;
107
+ margin: 0 auto;
108
+ padding: 60px 72px;
109
+ }
110
+
111
+ h1, h2, h3, h4, h5, h6 {
112
+ font-weight: 600;
113
+ line-height: 1.25;
114
+ margin-top: 2em;
115
+ margin-bottom: 0.6em;
116
+ color: #0f3460;
117
+ }
118
+
119
+ h1 { font-size: 22pt; border-bottom: 3px solid #e94560; padding-bottom: 10px; }
120
+ h2 { font-size: 16pt; border-bottom: 1px solid #e0e0e0; padding-bottom: 8px; }
121
+ h3 { font-size: 13pt; color: #16213e; }
122
+ h4 { font-size: 11pt; color: #16213e; font-weight: 600; }
123
+
124
+ p { margin-bottom: 1em; }
125
+
126
+ a { color: #e94560; text-decoration: none; }
127
+
128
+ strong { font-weight: 600; color: #0f3460; }
129
+ em { font-style: italic; color: #444; }
130
+
131
+ /* Tables */
132
+ table {
133
+ width: 100%;
134
+ border-collapse: collapse;
135
+ margin: 1.5em 0;
136
+ font-size: 10pt;
137
+ }
138
+ thead {
139
+ background: #0f3460;
140
+ color: white;
141
+ }
142
+ thead th {
143
+ padding: 10px 14px;
144
+ text-align: left;
145
+ font-weight: 500;
146
+ letter-spacing: 0.5px;
147
+ }
148
+ tbody tr:nth-child(even) { background: #f8f9fc; }
149
+ tbody tr:hover { background: #eef1f8; }
150
+ tbody td {
151
+ padding: 9px 14px;
152
+ border-bottom: 1px solid #e5e9f0;
153
+ }
154
+
155
+ /* Code */
156
+ code {
157
+ background: #f0f3f9;
158
+ color: #c7254e;
159
+ font-family: 'SF Mono', 'Fira Code', monospace;
160
+ font-size: 9pt;
161
+ padding: 2px 6px;
162
+ border-radius: 3px;
163
+ }
164
+ pre {
165
+ background: #1a1a2e;
166
+ color: #e2e8f0;
167
+ padding: 20px 24px;
168
+ border-radius: 6px;
169
+ overflow-x: auto;
170
+ margin: 1.5em 0;
171
+ border-left: 4px solid #e94560;
172
+ }
173
+ pre code {
174
+ background: none;
175
+ color: inherit;
176
+ padding: 0;
177
+ font-size: 9pt;
178
+ line-height: 1.6;
179
+ }
180
+
181
+ /* Blockquotes */
182
+ blockquote {
183
+ border-left: 4px solid #e94560;
184
+ margin: 1.5em 0;
185
+ padding: 12px 20px;
186
+ background: #fef5f7;
187
+ color: #555;
188
+ font-style: italic;
189
+ border-radius: 0 4px 4px 0;
190
+ }
191
+
192
+ /* Lists */
193
+ ul, ol {
194
+ margin: 0.8em 0 0.8em 1.5em;
195
+ }
196
+ li { margin-bottom: 0.3em; }
197
+ li::marker { color: #e94560; }
198
+
199
+ /* Callout / Info box using blockquote with > **Note** */
200
+ blockquote strong:first-child {
201
+ display: block;
202
+ color: #0f3460;
203
+ font-style: normal;
204
+ margin-bottom: 4px;
205
+ }
206
+
207
+ /* Horizontal Rule */
208
+ hr {
209
+ border: none;
210
+ border-top: 2px solid #e5e9f0;
211
+ margin: 2em 0;
212
+ }
213
+
214
+ /* Page numbers */
215
+ @page { margin: 0; }
216
+ .page-number {
217
+ position: fixed;
218
+ bottom: 24px;
219
+ right: 48px;
220
+ font-size: 9pt;
221
+ color: #999;
222
+ }
223
+
224
+ /* Print */
225
+ @media print {
226
+ body { font-size: 10.5pt; }
227
+ .cover { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
228
+ pre, blockquote, table { page-break-inside: avoid; }
229
+ h2, h3 { page-break-after: avoid; }
230
+ }
231
+ </style>
232
+ </head>
233
+ <body>
234
+
235
+ <!-- Cover Page -->
236
+ <div class="cover">
237
+ <div class="cover-logo">{{#if author}}{{author}}{{else}}Professional Report{{/if}}</div>
238
+ <div class="cover-main">
239
+ <div class="cover-tag">Report</div>
240
+ <h1>{{#if title}}{{title}}{{else}}Document Title{{/if}}</h1>
241
+ {{#if subtitle}}<p class="cover-subtitle">{{subtitle}}</p>{{/if}}
242
+ </div>
243
+ <div class="cover-footer">
244
+ <div class="cover-meta">
245
+ <strong>Prepared by</strong>
246
+ {{#if author}}{{author}}{{else}}—{{/if}}
247
+ </div>
248
+ <div class="cover-meta" style="text-align:right">
249
+ <strong>Date</strong>
250
+ {{#if date}}{{date}}{{else}}—{{/if}}
251
+ </div>
252
+ </div>
253
+ </div>
254
+
255
+ <!-- Content -->
256
+ <div class="content">
257
+ {{{content}}}
258
+ </div>
259
+
260
+ </body>
261
+ </html>
@@ -2,133 +2,210 @@
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>{{#if frontMatter.name}}{{frontMatter.name}} - Resume{{else}}Resume{{/if}}</title>
5
+ <title>{{title}}</title>
7
6
  <style>
8
7
  * { box-sizing: border-box; margin: 0; padding: 0; }
8
+
9
9
  body {
10
- font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
10
+ font-family: -apple-system, 'Helvetica Neue', Arial, sans-serif;
11
+ font-size: 10pt;
11
12
  line-height: 1.5;
12
- color: #2c3e50;
13
- max-width: 800px;
14
- margin: 0 auto;
15
- padding: 0;
13
+ color: #2d2d2d;
14
+ background: #fff;
15
+ }
16
+
17
+ /* ── HEADER ── */
18
+ .resume-header {
19
+ background: #1b262c;
20
+ color: white;
21
+ padding: 40px 56px;
22
+ display: flex;
23
+ align-items: center;
24
+ gap: 32px;
25
+ }
26
+
27
+ .header-avatar {
28
+ width: 80px; height: 80px;
29
+ border-radius: 50%;
30
+ background: linear-gradient(135deg, #00b4d8, #0077b6);
31
+ display: flex; align-items: center; justify-content: center;
32
+ font-size: 28pt; font-weight: 700; color: white;
33
+ flex-shrink: 0;
34
+ }
35
+
36
+ .header-info h1 {
37
+ font-size: 22pt;
38
+ font-weight: 700;
39
+ letter-spacing: -0.5px;
40
+ color: white;
41
+ margin: 0 0 4px;
42
+ }
43
+
44
+ .header-role {
16
45
  font-size: 11pt;
46
+ color: #00b4d8;
47
+ font-weight: 500;
48
+ margin-bottom: 10px;
17
49
  }
18
- .header {
19
- text-align: center;
20
- padding: 30px 0;
21
- border-bottom: 2px solid #3498db;
22
- }
23
- .header h1 {
24
- font-size: 28pt;
25
- font-weight: 300;
50
+
51
+ .header-contact {
52
+ display: flex;
53
+ flex-wrap: wrap;
54
+ gap: 8px 20px;
55
+ font-size: 9pt;
56
+ color: rgba(255,255,255,0.65);
57
+ }
58
+
59
+ /* ── BODY LAYOUT ── */
60
+ .resume-body {
61
+ display: grid;
62
+ grid-template-columns: 220px 1fr;
63
+ min-height: calc(100vh - 160px);
64
+ }
65
+
66
+ /* ── SIDEBAR ── */
67
+ .sidebar {
68
+ background: #f4f8fb;
69
+ padding: 36px 28px;
70
+ border-right: 1px solid #e0e8ee;
71
+ }
72
+
73
+ .sidebar-section { margin-bottom: 28px; }
74
+
75
+ .sidebar-label {
76
+ font-size: 7.5pt;
77
+ font-weight: 700;
26
78
  letter-spacing: 2px;
27
- margin-bottom: 8px;
28
- color: #2c3e50;
29
- }
30
- .header .contact {
31
- font-size: 10pt;
32
- color: #7f8c8d;
33
- }
34
- .header .contact a {
35
- color: #3498db;
36
- text-decoration: none;
37
- margin: 0 10px;
38
- }
39
- .section {
40
- padding: 20px 0;
41
- border-bottom: 1px solid #eee;
42
- }
43
- .section:last-child { border-bottom: none; }
44
- .section-title {
45
- font-size: 12pt;
46
- font-weight: 600;
47
- color: #3498db;
48
79
  text-transform: uppercase;
49
- letter-spacing: 1px;
50
- margin-bottom: 15px;
51
- }
52
- .section h2 {
53
- font-size: 11pt;
54
- margin-bottom: 4px;
55
- color: #2c3e50;
56
- }
57
- .section h3 {
58
- font-size: 10pt;
59
- font-weight: normal;
60
- color: #7f8c8d;
61
- margin-bottom: 8px;
80
+ color: #0077b6;
81
+ margin-bottom: 10px;
82
+ padding-bottom: 4px;
83
+ border-bottom: 2px solid #00b4d8;
62
84
  }
63
- .section p {
85
+
86
+ .skill-bar {
64
87
  margin-bottom: 8px;
65
- font-size: 10pt;
66
88
  }
67
- .section ul {
68
- padding-left: 20px;
69
- margin-bottom: 15px;
70
- }
71
- .section li {
72
- font-size: 10pt;
73
- margin-bottom: 4px;
74
- }
75
- .skills-grid {
76
- display: flex;
77
- flex-wrap: wrap;
78
- gap: 8px;
79
- }
80
- .skill-tag {
81
- background: #ecf0f1;
82
- padding: 4px 12px;
83
- border-radius: 3px;
89
+ .skill-bar span {
84
90
  font-size: 9pt;
85
- color: #2c3e50;
86
- }
87
- .entry {
88
- margin-bottom: 20px;
89
- }
90
- .entry-header {
91
- display: flex;
92
- justify-content: space-between;
93
- align-items: baseline;
94
- margin-bottom: 5px;
95
- }
96
- .entry-title {
91
+ display: block;
92
+ margin-bottom: 3px;
93
+ color: #333;
94
+ }
95
+ .skill-track {
96
+ height: 4px;
97
+ background: #dde8f0;
98
+ border-radius: 2px;
99
+ overflow: hidden;
100
+ }
101
+ .skill-fill {
102
+ height: 100%;
103
+ background: linear-gradient(90deg, #0077b6, #00b4d8);
104
+ border-radius: 2px;
105
+ }
106
+
107
+ /* ── MAIN CONTENT ── */
108
+ .main {
109
+ padding: 36px 48px;
110
+ }
111
+
112
+ h1 { display: none; } /* Hidden — shown in header */
113
+ h2 {
114
+ font-size: 11pt;
115
+ font-weight: 700;
116
+ letter-spacing: 1.5px;
117
+ text-transform: uppercase;
118
+ color: #0077b6;
119
+ border-bottom: 2px solid #e0e8ee;
120
+ padding-bottom: 6px;
121
+ margin-bottom: 16px;
122
+ margin-top: 28px;
123
+ }
124
+ h2:first-child { margin-top: 0; }
125
+ h3 {
97
126
  font-size: 11pt;
98
127
  font-weight: 600;
128
+ color: #1b262c;
129
+ margin-bottom: 2px;
99
130
  }
100
- .entry-date {
101
- font-size: 9pt;
102
- color: #7f8c8d;
131
+ h4 {
132
+ font-size: 9.5pt;
133
+ font-weight: 400;
134
+ color: #0077b6;
135
+ margin-bottom: 4px;
103
136
  }
104
- .entry-company {
105
- font-size: 10pt;
106
- color: #7f8c8d;
107
- margin-bottom: 8px;
137
+ p { margin-bottom: 0.7em; font-size: 9.5pt; color: #444; }
138
+
139
+ ul {
140
+ margin: 0.3em 0 0.8em 1.2em;
141
+ list-style: none;
142
+ padding: 0;
108
143
  }
109
- a { color: #3498db; text-decoration: none; }
110
- code {
111
- background: #f8f9fa;
112
- padding: 0.15em 0.4em;
113
- border-radius: 3px;
114
- font-size: 0.9em;
144
+ li {
145
+ margin-bottom: 4px;
146
+ font-size: 9.5pt;
147
+ color: #444;
148
+ padding-left: 1em;
149
+ position: relative;
150
+ }
151
+ li::before {
152
+ content: '▸';
153
+ position: absolute;
154
+ left: 0;
155
+ color: #00b4d8;
156
+ font-size: 8pt;
157
+ }
158
+
159
+ .job-meta {
160
+ display: flex;
161
+ justify-content: space-between;
162
+ font-size: 8.5pt;
163
+ color: #888;
164
+ margin-bottom: 6px;
115
165
  }
166
+
167
+ /* ── PRINT ── */
116
168
  @media print {
117
- body { padding: 0.5in; }
118
- .section { page-break-inside: avoid; }
169
+ body { font-size: 9.5pt; }
170
+ .resume-header, .sidebar {
171
+ -webkit-print-color-adjust: exact;
172
+ print-color-adjust: exact;
173
+ }
119
174
  }
120
175
  </style>
121
176
  </head>
122
177
  <body>
123
- <div class="header">
124
- <h1>{{#if frontMatter.name}}{{frontMatter.name}}{{else}}Your Name{{/if}}</h1>
125
- <div class="contact">
126
- {{#if frontMatter.email}}<a href="mailto:{{frontMatter.email}}">{{frontMatter.email}}</a>{{/if}}
127
- {{#if frontMatter.phone}}<a href="tel:{{frontMatter.phone}}">{{frontMatter.phone}}</a>{{/if}}
128
- {{#if frontMatter.linkedin}}<a href="{{frontMatter.linkedin}}">LinkedIn</a>{{/if}}
129
- {{#if frontMatter.github}}<a href="{{frontMatter.github}}">GitHub</a>{{/if}}
178
+
179
+ <div class="resume-header">
180
+ <div class="header-avatar">
181
+ {{#if initials}}{{initials}}{{else}}{{#if title}}{{slice title 0 1}}{{else}}?{{/if}}{{/if}}
182
+ </div>
183
+ <div class="header-info">
184
+ <h1>{{#if title}}{{title}}{{else}}Full Name{{/if}}</h1>
185
+ <div class="header-role">{{#if role}}{{role}}{{else}}Professional Title{{/if}}</div>
186
+ <div class="header-contact">
187
+ {{#if email}}<span>✉ {{email}}</span>{{/if}}
188
+ {{#if phone}}<span>✆ {{phone}}</span>{{/if}}
189
+ {{#if location}}<span>⌖ {{location}}</span>{{/if}}
190
+ {{#if website}}<span>⬡ {{website}}</span>{{/if}}
191
+ </div>
192
+ </div>
193
+ </div>
194
+
195
+ <div class="resume-body">
196
+ <div class="sidebar">
197
+ <!-- Sidebar rendered by separate partial or manually -->
198
+ {{#if skills_sidebar}}
199
+ <div class="sidebar-section">
200
+ <div class="sidebar-label">Skills</div>
201
+ {{{skills_sidebar}}}
202
+ </div>
203
+ {{/if}}
204
+ </div>
205
+ <div class="main">
206
+ {{{content}}}
130
207
  </div>
131
208
  </div>
132
- <main>{{{content}}}</main>
209
+
133
210
  </body>
134
211
  </html>