@open-press/cli 0.5.0 → 0.7.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 (113) hide show
  1. package/dist/cli.js +114 -23
  2. package/package.json +1 -1
  3. package/template/core/CHANGELOG.md +97 -1
  4. package/template/core/README.md +9 -5
  5. package/template/core/engine/cli.mjs +2 -5
  6. package/template/core/engine/commands/_shared.mjs +4 -4
  7. package/template/core/engine/commands/deploy.mjs +1 -1
  8. package/template/core/engine/commands/inspect.mjs +3 -3
  9. package/template/core/engine/commands/replace.mjs +1 -1
  10. package/template/core/engine/commands/search.mjs +1 -1
  11. package/template/core/engine/commands/validate.mjs +2 -2
  12. package/template/core/engine/document-export.mjs +1 -1
  13. package/template/core/engine/{chrome-pdf.mjs → output/chrome-pdf.mjs} +1 -2
  14. package/template/core/engine/{deploy-sync.mjs → output/deploy-sync.mjs} +2 -2
  15. package/template/core/engine/{fonts.mjs → output/fonts.mjs} +1 -1
  16. package/template/core/engine/{public-assets.mjs → output/public-assets.mjs} +2 -2
  17. package/template/core/engine/{static-server.mjs → output/static-server.mjs} +2 -2
  18. package/template/core/engine/react/caption-numbering.mjs +73 -0
  19. package/template/core/engine/react/comment-marker.mjs +54 -10
  20. package/template/core/engine/react/document-entry.mjs +124 -64
  21. package/template/core/engine/react/document-export.mjs +252 -311
  22. package/template/core/engine/react/mdx-compile.mjs +123 -3
  23. package/template/core/engine/react/measurement-css.mjs +3 -3
  24. package/template/core/engine/react/pagination/allocator.mjs +122 -0
  25. package/template/core/engine/react/pagination/regions.mjs +81 -0
  26. package/template/core/engine/react/pagination.mjs +9 -121
  27. package/template/core/engine/react/pipeline/allocate.mjs +248 -0
  28. package/template/core/engine/react/pipeline/final-render.mjs +94 -0
  29. package/template/core/engine/react/pipeline/frame-measurement.mjs +271 -0
  30. package/template/core/engine/react/pipeline/press-tree.mjs +135 -0
  31. package/template/core/engine/react/project-asset-endpoint.mjs +2 -2
  32. package/template/core/engine/react/{chapter-css.mjs → section-css.mjs} +12 -9
  33. package/template/core/engine/react/sources/heading-numbering.mjs +132 -0
  34. package/template/core/engine/react/sources/mdx-resolver.mjs +441 -0
  35. package/template/core/engine/react/{workspace-discovery.mjs → style-discovery.mjs} +29 -40
  36. package/template/core/engine/{config.mjs → runtime/config.mjs} +15 -0
  37. package/template/core/engine/{file-utils.mjs → runtime/file-utils.mjs} +1 -1
  38. package/template/core/engine/{inspection.mjs → runtime/inspection.mjs} +3 -4
  39. package/template/core/engine/{source-text-tools.mjs → runtime/source-text-tools.mjs} +24 -7
  40. package/template/core/engine/runtime/source-workspace.mjs +186 -0
  41. package/template/core/engine/{validation.mjs → runtime/validation.mjs} +19 -17
  42. package/template/core/package.json +5 -2
  43. package/template/core/src/openpress/anchorMap.ts +27 -0
  44. package/template/core/src/openpress/core/Frame.tsx +80 -0
  45. package/template/core/src/openpress/core/FrameContext.tsx +19 -0
  46. package/template/core/src/openpress/core/MdxArea.tsx +35 -0
  47. package/template/core/src/openpress/core/Press.tsx +34 -0
  48. package/template/core/src/openpress/core/index.tsx +34 -15
  49. package/template/core/src/openpress/core/primitives.tsx +23 -0
  50. package/template/core/src/openpress/core/types.ts +131 -19
  51. package/template/core/src/openpress/core/useSource.ts +28 -0
  52. package/template/core/src/openpress/manuscript/index.tsx +196 -0
  53. package/template/core/src/openpress/mdx/index.ts +88 -0
  54. package/template/core/src/openpress/numbering/index.ts +294 -0
  55. package/template/core/src/openpress/publicPage.tsx +4 -186
  56. package/template/core/src/openpress/reactDocumentMetadata.ts +2 -16
  57. package/template/core/src/openpress/types.ts +0 -16
  58. package/template/core/src/openpress/workbench.tsx +2 -36
  59. package/template/core/src/styles/openpress/responsive.css +0 -14
  60. package/template/core/tsconfig.json +4 -1
  61. package/template/core/vite.config.ts +10 -3
  62. package/template/packs/academic-paper/document/chapters/01-introduction/content/01-introduction.mdx +21 -0
  63. package/template/packs/academic-paper/document/chapters/02-methods/content/01-methods.mdx +30 -0
  64. package/template/packs/academic-paper/document/chapters/03-results-and-discussion/content/01-results.mdx +29 -0
  65. package/template/packs/academic-paper/document/chapters/04-acknowledgment/content/01-acknowledgment.mdx +12 -0
  66. package/template/packs/academic-paper/document/chapters/05-references/content/01-references.mdx +27 -0
  67. package/template/packs/academic-paper/document/components/ChapterOpenerVisual/index.tsx +76 -0
  68. package/template/packs/academic-paper/document/components/Page.tsx +37 -0
  69. package/template/packs/academic-paper/document/components/TokenSwatchGrid/index.tsx +46 -0
  70. package/template/packs/academic-paper/document/components/TokenSwatchGrid/style.css +63 -0
  71. package/template/packs/academic-paper/document/components/TypeSpecimen/index.tsx +38 -0
  72. package/template/packs/academic-paper/document/components/TypeSpecimen/style.css +111 -0
  73. package/template/packs/academic-paper/document/design.md +279 -0
  74. package/template/packs/academic-paper/document/index.tsx +131 -0
  75. package/template/packs/academic-paper/document/media/README.md +13 -0
  76. package/template/packs/academic-paper/document/openpress.config.mjs +26 -0
  77. package/template/packs/academic-paper/document/theme/README.md +11 -0
  78. package/template/packs/academic-paper/document/theme/base/page-contract.css +505 -0
  79. package/template/packs/academic-paper/document/theme/base/print.css +93 -0
  80. package/template/packs/academic-paper/document/theme/base/typography.css +336 -0
  81. package/template/packs/academic-paper/document/theme/fonts.css +3 -0
  82. package/template/packs/academic-paper/document/theme/page-surfaces/back-cover.css +43 -0
  83. package/template/packs/academic-paper/document/theme/page-surfaces/chapter-opener.css +205 -0
  84. package/template/packs/academic-paper/document/theme/page-surfaces/cover.css +267 -0
  85. package/template/packs/academic-paper/document/theme/page-surfaces/toc.css +149 -0
  86. package/template/packs/academic-paper/document/theme/patterns/_chart-frame.css +49 -0
  87. package/template/packs/academic-paper/document/theme/patterns/figure-grid.css +68 -0
  88. package/template/packs/academic-paper/document/theme/patterns/table-utilities.css +66 -0
  89. package/template/packs/academic-paper/document/theme/shell/reader-controls.css +761 -0
  90. package/template/packs/academic-paper/document/theme/tokens.css +80 -0
  91. package/template/packs/academic-paper/openpress.config.mjs +5 -0
  92. package/template/packs/claude-document/document/components/Page.tsx +24 -14
  93. package/template/packs/claude-document/document/design.md +2 -2
  94. package/template/packs/claude-document/document/index.tsx +67 -62
  95. package/template/packs/claude-document/document/theme/page-surfaces/toc.css +19 -7
  96. package/template/packs/editorial-monograph/document/components/Page.tsx +24 -14
  97. package/template/packs/editorial-monograph/document/design.md +2 -2
  98. package/template/packs/editorial-monograph/document/index.tsx +71 -47
  99. package/template/packs/editorial-monograph/document/theme/page-surfaces/toc.css +19 -9
  100. package/template/core/engine/commands/migrate-to-react.mjs +0 -27
  101. package/template/core/engine/page-renderer.mjs +0 -217
  102. package/template/core/engine/react/migrate-to-react.mjs +0 -355
  103. package/template/core/engine/source-workspace.mjs +0 -76
  104. package/template/core/src/openpress/core/basePages.tsx +0 -87
  105. package/template/core/src/openpress/pagination.ts +0 -845
  106. package/template/packs/claude-document/document/chapters/01-document-shape/chapter.tsx +0 -30
  107. package/template/packs/claude-document/document/chapters/02-review-loop/chapter.tsx +0 -30
  108. /package/template/core/engine/{chrome-pdf.d.mts → output/chrome-pdf.d.mts} +0 -0
  109. /package/template/core/engine/{katex-assets.mjs → output/katex-assets.mjs} +0 -0
  110. /package/template/core/engine/{page-block.mjs → output/page-block.mjs} +0 -0
  111. /package/template/core/engine/{pdf-media.mjs → output/pdf-media.mjs} +0 -0
  112. /package/template/core/engine/{config.d.mts → runtime/config.d.mts} +0 -0
  113. /package/template/core/engine/{issue-report.mjs → runtime/issue-report.mjs} +0 -0
@@ -0,0 +1,267 @@
1
+ /* page-surfaces / cover
2
+ * Cover and back-cover share most of their layout chrome (meta header, byline
3
+ * footer, central main column). Shared selectors live here so cover is the
4
+ * primary reference; back-cover.css only refines the parts that differ.
5
+ */
6
+
7
+ .reader-page--cover,
8
+ .reader-page--back-cover {
9
+ background: var(--openpress-color-document);
10
+ padding: clamp(28px, 5cqw, 48px) clamp(24px, 4.5cqw, 42px);
11
+ flex-direction: column;
12
+ justify-content: space-between;
13
+ gap: clamp(16px, 2.5cqw, 24px);
14
+ }
15
+
16
+ .reader-app.is-ready .reader-page--cover,
17
+ .reader-app.is-ready .reader-page--back-cover,
18
+ .reader-page--cover.is-active,
19
+ .reader-page--back-cover.is-active {
20
+ display: flex;
21
+ }
22
+
23
+ .cover-meta,
24
+ .back-cover-meta {
25
+ display: flex;
26
+ justify-content: space-between;
27
+ align-items: flex-start;
28
+ gap: var(--openpress-space-3);
29
+ padding-bottom: var(--openpress-space-2);
30
+ border-bottom: 1px solid var(--openpress-color-ink);
31
+ font-family: var(--openpress-font-body);
32
+ font-size: clamp(8pt, 1.25cqw, 9.5pt);
33
+ color: var(--openpress-color-muted);
34
+ letter-spacing: 0.12em;
35
+ flex-shrink: 0;
36
+ }
37
+
38
+ .mihua-logo,
39
+ .openpress-logo {
40
+ display: block;
41
+ width: clamp(112px, 18cqw, 154px);
42
+ height: auto;
43
+ flex-shrink: 0;
44
+ object-fit: contain;
45
+ }
46
+
47
+ .cover-meta-title {
48
+ margin-left: auto;
49
+ max-width: 48%;
50
+ padding-top: 0.35em;
51
+ text-align: right;
52
+ white-space: nowrap;
53
+ }
54
+
55
+ .cover-main,
56
+ .back-cover-main {
57
+ display: flex;
58
+ flex-direction: column;
59
+ flex: 1;
60
+ min-height: 0;
61
+ }
62
+
63
+ .cover-title {
64
+ margin: 0;
65
+ font-family: var(--openpress-font-serif);
66
+ font-size: clamp(36px, 8.5cqw, 64px);
67
+ font-weight: 300;
68
+ line-height: 1;
69
+ letter-spacing: 0.01em;
70
+ color: var(--openpress-color-ink);
71
+ }
72
+
73
+ .cover-tagline {
74
+ margin: var(--openpress-space-2) 0 0;
75
+ font-family: var(--openpress-font-serif);
76
+ font-size: clamp(14px, 2.4cqw, 20px);
77
+ font-weight: 300;
78
+ letter-spacing: 0.08em;
79
+ color: var(--openpress-color-muted);
80
+ }
81
+
82
+ .cover-rule,
83
+ .back-cover-rule {
84
+ height: 1px;
85
+ width: 40px;
86
+ background: var(--openpress-color-ink);
87
+ margin: var(--openpress-space-3) 0;
88
+ }
89
+
90
+ .cover-subtitle {
91
+ margin: 0;
92
+ font-family: var(--openpress-font-body);
93
+ font-size: clamp(10.5pt, 1.85cqw, 12.5pt);
94
+ font-weight: 400;
95
+ letter-spacing: 0.02em;
96
+ line-height: 1.55;
97
+ color: var(--openpress-color-ink);
98
+ }
99
+
100
+ .cover-summary {
101
+ margin: var(--openpress-space-2) 0 0;
102
+ font-family: var(--openpress-font-body);
103
+ font-size: clamp(9pt, 1.65cqw, 10pt);
104
+ line-height: 1.8;
105
+ color: var(--openpress-color-muted);
106
+ max-width: 90%;
107
+ }
108
+
109
+ .cover-visual,
110
+ .back-cover-visual {
111
+ margin: var(--openpress-space-3) 0 0;
112
+ flex-shrink: 0;
113
+ }
114
+
115
+ .cover-visual img,
116
+ .back-cover-visual img {
117
+ display: block;
118
+ width: 100%;
119
+ height: auto;
120
+ max-height: 22cqh;
121
+ object-fit: cover;
122
+ border: 0;
123
+ padding: 0;
124
+ background: transparent;
125
+ }
126
+
127
+ .cover-byline,
128
+ .back-cover-byline {
129
+ display: flex;
130
+ justify-content: space-between;
131
+ align-items: baseline;
132
+ padding-top: var(--openpress-space-2);
133
+ border-top: 1px solid var(--openpress-color-ink);
134
+ font-family: var(--openpress-font-body);
135
+ font-size: clamp(8pt, 1.25cqw, 9.5pt);
136
+ color: var(--openpress-color-muted);
137
+ letter-spacing: 0.12em;
138
+ flex-shrink: 0;
139
+ }
140
+
141
+ .cover-byline span:first-child,
142
+ .back-cover-byline span:first-child {
143
+ font-family: var(--openpress-font-serif);
144
+ font-weight: 400;
145
+ letter-spacing: 0.04em;
146
+ color: var(--openpress-color-ink);
147
+ }
148
+
149
+ /* ─ academic-paper title block ──────────────────────────────────────────── */
150
+ /* IEEE-style title page: large serif title, optional subtitle, 3-column */
151
+ /* author grid, abstract band, index terms band. Single-column body picks */
152
+ /* up after this surface. Two-column body arrives with the v0.8 paged.js */
153
+ /* migration. */
154
+
155
+ .paper-cover {
156
+ display: flex;
157
+ flex-direction: column;
158
+ gap: clamp(18px, 2.4cqw, 32px);
159
+ padding-block: clamp(24px, 3cqw, 40px) 0;
160
+ font-family: var(--openpress-font-serif);
161
+ color: var(--openpress-color-ink);
162
+ }
163
+
164
+ .paper-title {
165
+ font-family: var(--openpress-font-serif);
166
+ font-size: clamp(28px, 4.4cqw, 36px);
167
+ line-height: 1.2;
168
+ font-weight: 400;
169
+ text-align: center;
170
+ margin: 0;
171
+ letter-spacing: 0;
172
+ }
173
+
174
+ .paper-subtitle {
175
+ font-size: clamp(11px, 1.4cqw, 12px);
176
+ font-style: italic;
177
+ text-align: center;
178
+ color: var(--openpress-color-muted);
179
+ margin: 0;
180
+ }
181
+
182
+ .paper-authors {
183
+ list-style: none;
184
+ padding: 0;
185
+ margin: clamp(8px, 1.6cqw, 16px) 0 0;
186
+ display: grid;
187
+ grid-template-columns: repeat(3, 1fr);
188
+ gap: clamp(10px, 1.4cqw, 16px) clamp(8px, 1.2cqw, 14px);
189
+ }
190
+
191
+ .paper-author {
192
+ display: flex;
193
+ flex-direction: column;
194
+ align-items: center;
195
+ text-align: center;
196
+ font-size: clamp(10.5px, 1.3cqw, 11.5px);
197
+ line-height: 1.35;
198
+ gap: 0;
199
+ }
200
+
201
+ .paper-author-name {
202
+ font-weight: 500;
203
+ margin: 0 0 0.25em 0;
204
+ }
205
+
206
+ .paper-author-affiliation {
207
+ font-style: italic;
208
+ margin: 0;
209
+ color: var(--openpress-color-ink);
210
+ }
211
+
212
+ .paper-author-location,
213
+ .paper-author-contact {
214
+ margin: 0;
215
+ color: var(--openpress-color-ink);
216
+ }
217
+
218
+ .paper-abstract,
219
+ .paper-index-terms {
220
+ margin-top: clamp(8px, 1.6cqw, 14px);
221
+ font-size: clamp(10.5px, 1.3cqw, 11.5px);
222
+ line-height: 1.45;
223
+ }
224
+
225
+ .paper-abstract p,
226
+ .paper-index-terms p {
227
+ margin: 0;
228
+ text-indent: 1.2em;
229
+ font-style: italic;
230
+ }
231
+
232
+ .paper-abstract-label {
233
+ font-style: normal;
234
+ font-weight: 700;
235
+ }
236
+
237
+ /* Single-column flush body (v0.6). The v0.8 paged.js migration replaces */
238
+ /* this declaration with `column-count: 2; column-gap: 1rem;` and adds */
239
+ /* `column-span: all` for the title block + abstract above. */
240
+ .reader-page--content .page-body {
241
+ max-width: none;
242
+ }
243
+
244
+ /* ─ academic-paper back cover ───────────────────────────────────────────── */
245
+
246
+ .paper-back-cover {
247
+ display: flex;
248
+ flex-direction: column;
249
+ gap: clamp(10px, 1.6cqw, 16px);
250
+ font-family: var(--openpress-font-serif);
251
+ padding-inline: clamp(24px, 4cqw, 56px);
252
+ }
253
+
254
+ .paper-back-kicker {
255
+ font-family: var(--openpress-font-mono, monospace);
256
+ font-size: 11px;
257
+ letter-spacing: 0.08em;
258
+ text-transform: uppercase;
259
+ color: var(--openpress-color-muted);
260
+ margin: 0;
261
+ }
262
+
263
+ .paper-back-statement {
264
+ font-size: clamp(13px, 1.6cqw, 15px);
265
+ line-height: 1.5;
266
+ margin: 0;
267
+ }
@@ -0,0 +1,149 @@
1
+ /* page-surfaces / toc
2
+ * Table-of-contents page surface rendered by the manuscript <Toc> helper.
3
+ * Entries flow through the generated toc:<sourceId> chain and TocArea.
4
+ */
5
+
6
+ .reader-page--toc {
7
+ padding: 0;
8
+ }
9
+
10
+ .reader-page--toc .page-frame {
11
+ grid-template-rows: auto minmax(0, 1fr);
12
+ }
13
+
14
+ .reader-page--toc .toc-header {
15
+ display: block;
16
+ overflow: visible;
17
+ opacity: 1;
18
+ }
19
+
20
+ .reader-page--toc .openpress-toc-area {
21
+ height: 100%;
22
+ }
23
+
24
+ .reader-page--toc h2 {
25
+ margin-top: 0;
26
+ font-family: var(--openpress-font-serif);
27
+ font-weight: 300;
28
+ letter-spacing: 0.12em;
29
+ font-size: clamp(15pt, 3.6cqw, 18pt);
30
+ border-bottom: 0;
31
+ padding-bottom: 0;
32
+ }
33
+
34
+ .reader-page--toc h2.toc-heading--continuation {
35
+ display: none;
36
+ }
37
+
38
+ .toc-list {
39
+ display: flex;
40
+ flex-direction: column;
41
+ gap: 0.75mm;
42
+ margin: 10mm 0 0;
43
+ padding: 0;
44
+ list-style: none;
45
+ }
46
+
47
+ .toc-continuation .toc-list {
48
+ margin-top: 5mm;
49
+ }
50
+
51
+ .toc-list li {
52
+ border-bottom: 0;
53
+ }
54
+
55
+ .toc-list a {
56
+ display: grid;
57
+ grid-template-columns: 9mm minmax(0, 1fr) 12mm;
58
+ column-gap: 3mm;
59
+ align-items: baseline;
60
+ color: var(--openpress-color-ink);
61
+ text-decoration: none;
62
+ font-family: var(--openpress-font-serif);
63
+ padding: 1.6mm 0;
64
+ font-weight: 400;
65
+ line-height: 1.38;
66
+ }
67
+
68
+ .toc-list a:hover .toc-title {
69
+ color: var(--openpress-color-muted);
70
+ }
71
+
72
+ .toc-index {
73
+ display: inline-block;
74
+ color: var(--openpress-color-muted);
75
+ font-family: var(--openpress-font-mono);
76
+ font-variant-numeric: tabular-nums;
77
+ font-weight: 400;
78
+ letter-spacing: 0;
79
+ font-size: 9.5pt;
80
+ text-align: left;
81
+ }
82
+
83
+ .toc-level-2 a {
84
+ margin-top: 2.5mm;
85
+ padding: 3mm 0 2mm;
86
+ border-top: 1px solid rgba(169, 180, 194, 0.42);
87
+ }
88
+
89
+ .toc-level-2:first-child a {
90
+ margin-top: 0;
91
+ border-top: 0;
92
+ }
93
+
94
+ .toc-level-2 .toc-title {
95
+ color: var(--openpress-color-ink);
96
+ font-size: 12pt;
97
+ font-weight: 500;
98
+ }
99
+
100
+ .toc-level-2 .toc-title::after {
101
+ content: none;
102
+ }
103
+
104
+ .toc-level-2 .toc-page {
105
+ color: var(--openpress-color-ink);
106
+ font-size: 9.8pt;
107
+ }
108
+
109
+ .toc-level-3 a {
110
+ grid-template-columns: 9mm minmax(0, 1fr) 12mm;
111
+ padding: 1.28mm 0 1.28mm 7mm;
112
+ color: var(--openpress-color-muted);
113
+ font-size: 10pt;
114
+ }
115
+
116
+ .toc-level-3 .toc-index {
117
+ font-size: 9pt;
118
+ }
119
+
120
+ .toc-level-3 .toc-page {
121
+ font-size: 9.5pt;
122
+ }
123
+
124
+ .toc-title {
125
+ display: flex;
126
+ gap: 3mm;
127
+ align-items: baseline;
128
+ color: var(--openpress-color-ink);
129
+ font-family: var(--openpress-font-serif);
130
+ }
131
+
132
+ .toc-title::after {
133
+ content: "";
134
+ flex: 1;
135
+ min-width: 10mm;
136
+ border-bottom: 1px dotted rgba(72, 101, 129, 0.32);
137
+ transform: translateY(-0.22em);
138
+ }
139
+
140
+ .toc-page {
141
+ color: var(--openpress-color-muted);
142
+ font-family: var(--openpress-font-mono);
143
+ font-variant-numeric: tabular-nums;
144
+ font-weight: 400;
145
+ font-size: 9.8pt;
146
+ justify-self: end;
147
+ min-width: 10mm;
148
+ text-align: right;
149
+ }
@@ -0,0 +1,49 @@
1
+ /* _chart-frame.css
2
+ * 共用圖表外框。文件圖表只要在 figure 上掛 chart-frame,
3
+ * 元件自己的 class 只負責內部結構樣式。
4
+ */
5
+
6
+ .reader-page--content .page-body > figure.chart-frame,
7
+ :where(.chart-frame) {
8
+ width: 100%;
9
+ max-width: none;
10
+ margin: var(--openpress-space-3) 0 var(--openpress-space-4);
11
+ margin-left: 0;
12
+ margin-right: 0;
13
+ padding: var(--openpress-space-2);
14
+ border: 1px solid rgba(0, 0, 0, 0.07);
15
+ background: var(--openpress-color-document);
16
+ box-sizing: border-box;
17
+ break-inside: avoid;
18
+ }
19
+
20
+ :where(.chart-frame) figcaption {
21
+ margin-top: var(--openpress-space-2);
22
+ color: var(--openpress-color-muted);
23
+ font-size: clamp(10px, 1.05cqw, 11px);
24
+ line-height: 1.55;
25
+ letter-spacing: 0.04em;
26
+ text-align: center;
27
+ }
28
+
29
+ .reader-page--content .page-body > figure svg,
30
+ :where(.chart-frame) svg {
31
+ display: block;
32
+ max-width: 100%;
33
+ height: auto;
34
+ overflow: visible;
35
+ }
36
+
37
+ @media (max-width: 899px) {
38
+ .reader-page--content .page-body > figure.chart-frame,
39
+ :where(.chart-frame) {
40
+ max-height: 100%;
41
+ }
42
+
43
+ .reader-page--content .page-body > figure svg,
44
+ :where(.chart-frame) svg {
45
+ width: 100%;
46
+ max-height: 100%;
47
+ object-fit: contain;
48
+ }
49
+ }
@@ -0,0 +1,68 @@
1
+ /* figure-grid
2
+ * Reusable image grid pattern for inline Markdown/HTML figures.
3
+ */
4
+
5
+ table.figure-grid {
6
+ border: 0;
7
+ background: transparent;
8
+ table-layout: fixed;
9
+ }
10
+
11
+ div.figure-grid {
12
+ display: grid;
13
+ grid-template-columns: repeat(2, minmax(0, 1fr));
14
+ gap: 4mm;
15
+ margin: var(--openpress-space-4) 0 var(--openpress-space-2);
16
+ break-inside: avoid;
17
+ }
18
+
19
+ table.figure-grid td {
20
+ border: 0;
21
+ padding: 0 2mm 3mm;
22
+ vertical-align: top;
23
+ }
24
+
25
+ table.figure-grid figure,
26
+ div.figure-grid figure {
27
+ margin-top: 0;
28
+ margin-bottom: 0;
29
+ }
30
+
31
+ .figure-grid img {
32
+ width: auto;
33
+ height: auto;
34
+ max-width: 100%;
35
+ max-height: 62mm;
36
+ }
37
+
38
+ /* Three-column triptych: one lead figure plus two siblings, centered on the
39
+ * page. Use this when a section needs a coordinated trio of images at a fixed
40
+ * aspect ratio (e.g. founder profile, milestone photo set). */
41
+ div.figure-grid--triptych {
42
+ grid-template-columns: repeat(3, minmax(0, 1fr));
43
+ gap: 3mm;
44
+ width: min(92%, 156mm);
45
+ margin: var(--openpress-space-4) auto var(--openpress-space-2);
46
+ }
47
+
48
+ div.figure-grid--triptych figure {
49
+ display: flex;
50
+ flex-direction: column;
51
+ align-items: center;
52
+ margin: 0;
53
+ }
54
+
55
+ div.figure-grid--triptych img {
56
+ width: 100%;
57
+ max-height: none;
58
+ aspect-ratio: 3 / 2;
59
+ object-fit: cover;
60
+ }
61
+
62
+ div.figure-grid--triptych .figure-grid__lead img {
63
+ aspect-ratio: 4 / 3;
64
+ }
65
+
66
+ div.figure-grid--triptych figcaption {
67
+ text-align: left;
68
+ }
@@ -0,0 +1,66 @@
1
+ /* table-utilities
2
+ * Semantic table helpers used by content Markdown.
3
+ */
4
+
5
+ .cell-check,
6
+ .cell-partial,
7
+ .cell-dash {
8
+ display: inline-block;
9
+ font-feature-settings: "tnum";
10
+ line-height: 1;
11
+ }
12
+
13
+ .cell-check {
14
+ color: #24a148;
15
+ font-weight: 600;
16
+ }
17
+
18
+ .cell-partial {
19
+ color: #b58105;
20
+ font-weight: 500;
21
+ }
22
+
23
+ .cell-dash {
24
+ color: var(--openpress-color-text-placeholder);
25
+ letter-spacing: -0.04em;
26
+ }
27
+
28
+ .status-text {
29
+ display: inline;
30
+ font-size: inherit;
31
+ line-height: inherit;
32
+ white-space: nowrap;
33
+ }
34
+
35
+ .status-live {
36
+ color: #198038;
37
+ }
38
+
39
+ .status-building {
40
+ color: #0f62fe;
41
+ }
42
+
43
+ .status-planned {
44
+ color: #525252;
45
+ }
46
+
47
+ .status-ai-full {
48
+ color: #007d79;
49
+ }
50
+
51
+ .status-ai-partial {
52
+ color: #8a5a00;
53
+ }
54
+
55
+ td.numeric,
56
+ th.numeric {
57
+ text-align: right;
58
+ font-variant-numeric: tabular-nums;
59
+ white-space: nowrap;
60
+ }
61
+
62
+ td.savings-rate,
63
+ th.savings-rate {
64
+ color: var(--openpress-color-green);
65
+ font-weight: 600;
66
+ }