orz-paged 0.1.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 (39) hide show
  1. package/README.md +146 -0
  2. package/assets/app.js +413 -0
  3. package/assets/templates/article-page.md +71 -0
  4. package/assets/templates/article-section.md +83 -0
  5. package/assets/templates/cover-letter.md +53 -0
  6. package/assets/templates/cv-elegant.md +93 -0
  7. package/assets/templates/cv-modern.md +86 -0
  8. package/assets/templates/cv.md +45 -0
  9. package/assets/templates/exam-page.md +76 -0
  10. package/assets/templates/exam-section.md +59 -0
  11. package/assets/templates/letter.md +47 -0
  12. package/assets/templates/note.md +28 -0
  13. package/assets/templates/report-page.md +72 -0
  14. package/assets/templates/report-section.md +80 -0
  15. package/assets/themes/base.css +538 -0
  16. package/assets/themes/beige-decent-1.css +103 -0
  17. package/assets/themes/beige-decent-2.css +92 -0
  18. package/assets/themes/light-academic-1.css +114 -0
  19. package/assets/themes/light-academic-2.css +99 -0
  20. package/assets/themes/light-neat-1.css +90 -0
  21. package/assets/themes/light-neat-2.css +101 -0
  22. package/assets/themes/light-neat-3.css +91 -0
  23. package/dist/browser-entry.js +302 -0
  24. package/dist/cli.js +167 -0
  25. package/dist/doc/dynamic.js +57 -0
  26. package/dist/doc/elements.js +813 -0
  27. package/dist/doc/fonts.js +83 -0
  28. package/dist/doc/nyml.js +140 -0
  29. package/dist/doc/page-css.js +230 -0
  30. package/dist/doc/settings.js +390 -0
  31. package/dist/doc/templates.js +147 -0
  32. package/dist/doc/theme-fonts.js +10 -0
  33. package/dist/orz-paged.browser.js +1524 -0
  34. package/dist/paged.js +31 -0
  35. package/dist/render-paged.js +123 -0
  36. package/dist/template.js +242 -0
  37. package/dist/types.js +11 -0
  38. package/orz-paged-skills/SKILL.md +547 -0
  39. package/package.json +51 -0
@@ -0,0 +1,80 @@
1
+ {{nyml
2
+ kind: document
3
+ template: report-section
4
+ header_center: Report Title
5
+ page_number_position: footer-right
6
+ page_number_style: page-n-of-N
7
+ }}
8
+
9
+ {{nyml
10
+ kind: report-title
11
+ title: Report Title
12
+ subtitle: A Short, Descriptive Subtitle
13
+ author: Author Name, Team or Department
14
+ date: Month Year
15
+ placement: section
16
+ }}
17
+
18
+ {{nyml
19
+ kind: toc
20
+ title: Contents
21
+ max_level: 2
22
+ }}
23
+
24
+ ## Executive Summary
25
+
26
+ Summarize the report in a few sentences for a reader who will not go further.
27
+ State the purpose of the work, the most important finding, and the single action
28
+ you are recommending. Keep this to a short paragraph that a busy decision-maker
29
+ can absorb at a glance.
30
+
31
+ This section should make sense on its own. Lead with the conclusion, then let the
32
+ rest of the report supply the supporting detail.
33
+
34
+ ## Background
35
+
36
+ Explain the context that prompted this report. Describe the situation, the problem
37
+ or opportunity, and why it matters now. Note any relevant history, prior decisions,
38
+ or constraints that shape the analysis.
39
+
40
+ State the scope clearly: what this report covers and, where useful, what it
41
+ deliberately leaves out. Briefly describe how the information was gathered (for
42
+ example, interviews, system metrics, or a review of existing documents).
43
+
44
+ ## Findings
45
+
46
+ The analysis surfaced the following key results. Each finding is stated with its
47
+ observed impact and current status.
48
+
49
+ | # | Finding | Impact | Status |
50
+ |---|---------|--------|--------|
51
+ | 1 | Describe the first observation here. | High | Confirmed |
52
+ | 2 | Describe the second observation here. | Medium | Confirmed |
53
+ | 3 | Describe the third observation here. | Low | Needs review |
54
+
55
+ Add a sentence or two of interpretation after the table. Point out any patterns
56
+ that connect the findings, and flag anything that contradicts an initial
57
+ assumption.
58
+
59
+ ## Recommendations
60
+
61
+ Based on the findings above, we recommend the following actions, listed in
62
+ priority order:
63
+
64
+ 1. **Recommendation one.** State the action and the outcome it is meant to
65
+ achieve. Name the owner if one is known.
66
+ 2. **Recommendation two.** Describe the change and the effort it requires.
67
+ 3. **Recommendation three.** Note any dependency on an earlier recommendation.
68
+
69
+ Each recommendation should trace back to at least one finding so the reasoning is
70
+ easy to follow.
71
+
72
+ ## Next Steps
73
+
74
+ Outline how to move from recommendations to action over the coming weeks.
75
+
76
+ - **This week:** Confirm priorities and assign an owner to each recommendation.
77
+ - **This month:** Begin the highest-priority work and define success measures.
78
+ - **Next quarter:** Review progress against the measures and adjust the plan.
79
+
80
+ Close by naming a point of contact and the date of the next review.
@@ -0,0 +1,538 @@
1
+ /* ==========================================================================
2
+ orz-paged · base.css
3
+ Structural, theme-agnostic print foundation for the paged document body.
4
+
5
+ - Consumes ONLY the :root CSS variables defined in docs/dom-contract.md
6
+ (--page-bg, --accent, --font-body, --font-heading, --font-size,
7
+ --line-height, --margin-*, --header-rule, --footer-rule), each with a
8
+ sensible fallback so the file works standalone.
9
+ - Light / print-first only. No dark rules, no prefers-color-scheme.
10
+ - Styles via the dom-contract classes: .orz-doc.markdown-body,
11
+ .orz-element.orz-el-<kind>, .page-break, .orz-toc.
12
+ - Theme files @import this, then layer accent/visual styling on top.
13
+ ========================================================================== */
14
+
15
+ /* --------------------------------------------------------------------------
16
+ 1. Page surface
17
+ The visible "paper". paged.js realizes @page boxes; here we set their
18
+ background to the light page color so screen and print match.
19
+ -------------------------------------------------------------------------- */
20
+ .pagedjs_page,
21
+ .pagedjs_pagebox,
22
+ .orz-doc.markdown-body {
23
+ background: var(--page-bg, #ffffff);
24
+ }
25
+
26
+ /* --------------------------------------------------------------------------
27
+ 2. Document body typography (driven by the contract tokens)
28
+ -------------------------------------------------------------------------- */
29
+ .orz-doc.markdown-body {
30
+ font-family: var(--font-body, Georgia, "Times New Roman", serif);
31
+ font-size: var(--font-size, 12pt);
32
+ line-height: var(--line-height, 1.5);
33
+ color: var(--text-main, #1a1a1a);
34
+ text-rendering: optimizeLegibility;
35
+ -webkit-font-smoothing: antialiased;
36
+ -webkit-text-size-adjust: 100%;
37
+ /* No outer margin/padding: paged.js margin boxes own the page geometry. */
38
+ margin: 0;
39
+ padding: 0;
40
+ }
41
+
42
+ .orz-doc.markdown-body > :first-child {
43
+ margin-top: 0;
44
+ }
45
+
46
+ .orz-doc.markdown-body > :last-child {
47
+ margin-bottom: 0;
48
+ }
49
+
50
+ /* --------------------------------------------------------------------------
51
+ 3. Headings
52
+ -------------------------------------------------------------------------- */
53
+ .orz-doc.markdown-body h1,
54
+ .orz-doc.markdown-body h2,
55
+ .orz-doc.markdown-body h3,
56
+ .orz-doc.markdown-body h4,
57
+ .orz-doc.markdown-body h5,
58
+ .orz-doc.markdown-body h6 {
59
+ font-family: var(--font-heading, var(--font-body, Georgia, serif));
60
+ color: var(--heading-color, var(--text-main, #1a1a1a));
61
+ font-weight: 600;
62
+ line-height: 1.25;
63
+ margin: 1.6em 0 0.5em;
64
+ /* Print: keep headings with the text that follows; never orphan them. */
65
+ break-after: avoid;
66
+ page-break-after: avoid;
67
+ break-inside: avoid;
68
+ }
69
+
70
+ .orz-doc.markdown-body h1 { font-size: 1.9em; margin-top: 0.4em; }
71
+ .orz-doc.markdown-body h2 { font-size: 1.5em; }
72
+ .orz-doc.markdown-body h3 { font-size: 1.25em; }
73
+ .orz-doc.markdown-body h4 { font-size: 1.08em; }
74
+ .orz-doc.markdown-body h5 { font-size: 1em; }
75
+ .orz-doc.markdown-body h6 { font-size: 0.9em; color: var(--text-muted, #555); }
76
+
77
+ /* --------------------------------------------------------------------------
78
+ 4. Body copy, inline
79
+ -------------------------------------------------------------------------- */
80
+ .orz-doc.markdown-body p {
81
+ margin: 0 0 0.85em;
82
+ orphans: 2;
83
+ widows: 2;
84
+ }
85
+
86
+ .orz-doc.markdown-body a {
87
+ color: var(--accent, #1a4f8b);
88
+ text-decoration: underline;
89
+ text-decoration-thickness: 0.5px;
90
+ text-underline-offset: 2px;
91
+ }
92
+
93
+ .orz-doc.markdown-body strong { font-weight: 700; }
94
+ .orz-doc.markdown-body em { font-style: italic; }
95
+
96
+ .orz-doc.markdown-body sub,
97
+ .orz-doc.markdown-body sup { font-size: 0.75em; line-height: 0; }
98
+
99
+ .orz-doc.markdown-body mark {
100
+ background: var(--mark-bg, #fff3a3);
101
+ color: inherit;
102
+ padding: 0 0.15em;
103
+ }
104
+
105
+ /* --------------------------------------------------------------------------
106
+ 5. Lists
107
+ -------------------------------------------------------------------------- */
108
+ .orz-doc.markdown-body ul,
109
+ .orz-doc.markdown-body ol {
110
+ margin: 0 0 0.85em;
111
+ padding-left: 1.6em;
112
+ }
113
+
114
+ .orz-doc.markdown-body li {
115
+ margin-bottom: 0.25em;
116
+ }
117
+
118
+ .orz-doc.markdown-body li > ul,
119
+ .orz-doc.markdown-body li > ol {
120
+ margin-top: 0.25em;
121
+ margin-bottom: 0;
122
+ }
123
+
124
+ .orz-doc.markdown-body .task-list-item {
125
+ list-style: none;
126
+ }
127
+
128
+ .orz-doc.markdown-body .task-list-item input[type="checkbox"],
129
+ .orz-doc.markdown-body .task-list-item-checkbox {
130
+ margin: 0 0.5em 0 -1.4em;
131
+ vertical-align: middle;
132
+ }
133
+
134
+ /* --------------------------------------------------------------------------
135
+ 6. Blockquote
136
+ -------------------------------------------------------------------------- */
137
+ .orz-doc.markdown-body blockquote {
138
+ margin: 1.2em 0;
139
+ padding: 0.2em 1.1em;
140
+ color: var(--text-muted, #555);
141
+ border-left: 3px solid var(--border-soft, #d6d6d6);
142
+ break-inside: avoid;
143
+ page-break-inside: avoid;
144
+ }
145
+
146
+ .orz-doc.markdown-body blockquote > :last-child {
147
+ margin-bottom: 0;
148
+ }
149
+
150
+ /* --------------------------------------------------------------------------
151
+ 7. Code
152
+ -------------------------------------------------------------------------- */
153
+ .orz-doc.markdown-body code,
154
+ .orz-doc.markdown-body kbd,
155
+ .orz-doc.markdown-body samp {
156
+ font-family: var(--font-code, "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace);
157
+ font-size: 0.86em;
158
+ }
159
+
160
+ .orz-doc.markdown-body :not(pre) > code {
161
+ background: var(--code-bg, #f4f4f2);
162
+ padding: 0.1em 0.35em;
163
+ border-radius: 3px;
164
+ }
165
+
166
+ .orz-doc.markdown-body pre {
167
+ margin: 1.1em 0;
168
+ padding: 0.85em 1em;
169
+ background: var(--code-bg, #f4f4f2);
170
+ border: 1px solid var(--border-soft, #e0e0dc);
171
+ border-radius: 4px;
172
+ overflow-x: auto;
173
+ font-size: 0.86em;
174
+ line-height: 1.45;
175
+ /* Print: a code block should avoid splitting where it reasonably can. */
176
+ break-inside: avoid;
177
+ page-break-inside: avoid;
178
+ white-space: pre-wrap;
179
+ word-wrap: break-word;
180
+ }
181
+
182
+ .orz-doc.markdown-body pre code {
183
+ background: none;
184
+ padding: 0;
185
+ border: 0;
186
+ font-size: inherit;
187
+ }
188
+
189
+ /* --------------------------------------------------------------------------
190
+ 8. Tables (print-friendly: real table layout, repeat header on break)
191
+ -------------------------------------------------------------------------- */
192
+ .orz-doc.markdown-body table {
193
+ width: 100%;
194
+ margin: 1.2em 0;
195
+ border-collapse: collapse;
196
+ font-size: 0.95em;
197
+ }
198
+
199
+ .orz-doc.markdown-body thead {
200
+ display: table-header-group; /* repeat header row across page breaks */
201
+ }
202
+
203
+ .orz-doc.markdown-body th,
204
+ .orz-doc.markdown-body td {
205
+ padding: 0.4em 0.7em;
206
+ border: 1px solid var(--border-soft, #d6d6d6);
207
+ text-align: left;
208
+ vertical-align: top;
209
+ }
210
+
211
+ .orz-doc.markdown-body th {
212
+ font-weight: 600;
213
+ background: var(--table-head-bg, #f3f3f0);
214
+ }
215
+
216
+ .orz-doc.markdown-body tr,
217
+ .orz-doc.markdown-body img,
218
+ .orz-doc.markdown-body svg,
219
+ .orz-doc.markdown-body canvas,
220
+ .orz-doc.markdown-body figure {
221
+ break-inside: avoid;
222
+ page-break-inside: avoid;
223
+ }
224
+
225
+ /* --------------------------------------------------------------------------
226
+ 9. Images / figures / media
227
+ -------------------------------------------------------------------------- */
228
+ .orz-doc.markdown-body img {
229
+ max-width: 100%;
230
+ height: auto;
231
+ display: block;
232
+ margin: 1em auto;
233
+ }
234
+
235
+ .orz-doc.markdown-body p > img {
236
+ display: inline;
237
+ margin: 0;
238
+ }
239
+
240
+ .orz-doc.markdown-body figure {
241
+ margin: 1.2em 0;
242
+ text-align: center;
243
+ }
244
+
245
+ .orz-doc.markdown-body figcaption {
246
+ margin-top: 0.4em;
247
+ font-size: 0.85em;
248
+ color: var(--text-muted, #555);
249
+ text-align: center;
250
+ }
251
+
252
+ .orz-doc.markdown-body .mermaid,
253
+ .orz-doc.markdown-body .smiles-render {
254
+ margin: 1.2em 0;
255
+ text-align: center;
256
+ break-inside: avoid;
257
+ page-break-inside: avoid;
258
+ }
259
+
260
+ .orz-doc.markdown-body .mermaid svg,
261
+ .orz-doc.markdown-body .smiles-render canvas {
262
+ max-width: 100%;
263
+ height: auto;
264
+ }
265
+
266
+ /* --------------------------------------------------------------------------
267
+ 10. Horizontal rule
268
+ -------------------------------------------------------------------------- */
269
+ .orz-doc.markdown-body hr {
270
+ border: 0;
271
+ height: 1px;
272
+ margin: 2em 0;
273
+ background: var(--border-soft, #d6d6d6);
274
+ }
275
+
276
+ /* --------------------------------------------------------------------------
277
+ 11. Math (KaTeX)
278
+ -------------------------------------------------------------------------- */
279
+ .orz-doc.markdown-body .katex-display {
280
+ margin: 1.1em 0;
281
+ overflow-x: auto;
282
+ overflow-y: hidden;
283
+ break-inside: avoid;
284
+ page-break-inside: avoid;
285
+ }
286
+
287
+ /* --------------------------------------------------------------------------
288
+ 12. Footnotes
289
+ -------------------------------------------------------------------------- */
290
+ .orz-doc.markdown-body .footnotes {
291
+ margin-top: 2em;
292
+ padding-top: 0.6em;
293
+ border-top: 1px solid var(--border-soft, #d6d6d6);
294
+ font-size: 0.88em;
295
+ color: var(--text-muted, #555);
296
+ }
297
+
298
+ .orz-doc.markdown-body .footnote-ref a,
299
+ .orz-doc.markdown-body .footnote-backref {
300
+ text-decoration: none;
301
+ color: var(--accent, #1a4f8b);
302
+ }
303
+
304
+ /* --------------------------------------------------------------------------
305
+ 13. Admonitions / containers (print-recommended subset, §9)
306
+ Light, neutral defaults; themes may recolor.
307
+ -------------------------------------------------------------------------- */
308
+ .orz-doc.markdown-body .info,
309
+ .orz-doc.markdown-body .success,
310
+ .orz-doc.markdown-body .warning,
311
+ .orz-doc.markdown-body .danger {
312
+ margin: 1.2em 0;
313
+ padding: 0.8em 1.1em;
314
+ border: 1px solid var(--border-soft, #d6d6d6);
315
+ border-left-width: 4px;
316
+ border-radius: 3px;
317
+ break-inside: avoid;
318
+ page-break-inside: avoid;
319
+ }
320
+
321
+ .orz-doc.markdown-body .info { border-left-color: #2b5585; }
322
+ .orz-doc.markdown-body .success { border-left-color: #2e8540; }
323
+ .orz-doc.markdown-body .warning { border-left-color: #a37213; }
324
+ .orz-doc.markdown-body .danger { border-left-color: #a32a2a; }
325
+
326
+ .orz-doc.markdown-body .info > :last-child,
327
+ .orz-doc.markdown-body .success > :last-child,
328
+ .orz-doc.markdown-body .warning > :last-child,
329
+ .orz-doc.markdown-body .danger > :last-child {
330
+ margin-bottom: 0;
331
+ }
332
+
333
+ /* Columns (:::: cols) — print-friendly multi-column */
334
+ .orz-doc.markdown-body .cols {
335
+ display: grid;
336
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
337
+ gap: 1.5em;
338
+ margin: 1.2em 0;
339
+ }
340
+
341
+ .orz-doc.markdown-body .col > :last-child {
342
+ margin-bottom: 0;
343
+ }
344
+
345
+ /* Inline alignment helpers */
346
+ .orz-doc.markdown-body .center { text-align: center; }
347
+ .orz-doc.markdown-body .right { text-align: right; }
348
+
349
+ /* Floated sidebar ( ::: left ) — a boxed aside floated beside the text. */
350
+ .orz-doc.markdown-body .left {
351
+ float: left;
352
+ max-width: min(44%, 20rem);
353
+ margin: 0 1.2em 0.8em 0;
354
+ padding: 0.7em 0.9em;
355
+ background: var(--surface-2, #f6f6f4);
356
+ border: 1px solid var(--border-soft, #e0e0dc);
357
+ border-radius: 4px;
358
+ break-inside: avoid;
359
+ }
360
+ .orz-doc.markdown-body .left > :last-child { margin-bottom: 0; }
361
+
362
+ /* --------------------------------------------------------------------------
363
+ 13b. Inline spans, semantic badges, ins/del (mirrors orz-markdown's
364
+ --span-* / --*-bg/text/border tokens; fallbacks here so `theme: none`
365
+ works, theme files override the tokens.)
366
+ -------------------------------------------------------------------------- */
367
+ .orz-doc.markdown-body span.red { color: var(--span-red, #c0392b); }
368
+ .orz-doc.markdown-body span.yellow { color: var(--span-yellow, #b7791f); }
369
+ .orz-doc.markdown-body span.green { color: var(--span-green, #2e7d32); }
370
+ .orz-doc.markdown-body span.blue { color: var(--span-blue, #1a4f8b); }
371
+
372
+ /* Inline badge ({{span[success] …}}): override the block-callout rule above so a
373
+ SPAN renders as a small pill, not a bordered block. */
374
+ .orz-doc.markdown-body span.success,
375
+ .orz-doc.markdown-body span.info,
376
+ .orz-doc.markdown-body span.warning,
377
+ .orz-doc.markdown-body span.danger {
378
+ display: inline;
379
+ margin: 0;
380
+ padding: 0.12em 0.55em;
381
+ border: 1px solid;
382
+ border-radius: 999px;
383
+ font-size: 0.82em;
384
+ font-weight: 700;
385
+ line-height: 1;
386
+ white-space: nowrap;
387
+ vertical-align: baseline;
388
+ }
389
+ .orz-doc.markdown-body span.success { background: var(--success-bg, #e6f4ea); color: var(--success-text, #1e6b2e); border-color: var(--success-border, #b6dcc0); }
390
+ .orz-doc.markdown-body span.info { background: var(--info-bg, #e8eff8); color: var(--info-text, #234e84); border-color: var(--info-border, #b9cfe8); }
391
+ .orz-doc.markdown-body span.warning { background: var(--warning-bg, #fbf2dc); color: var(--warning-text, #8a5a00); border-color: var(--warning-border, #ecd9a6); }
392
+ .orz-doc.markdown-body span.danger { background: var(--danger-bg, #fbe9e7); color: var(--danger-text, #9a2820); border-color: var(--danger-border, #ecc2bc); }
393
+
394
+ .orz-doc.markdown-body ins { text-decoration: none; border-bottom: 2px solid var(--ins-color, #2e8540); }
395
+ .orz-doc.markdown-body del { color: var(--text-muted, #777); }
396
+
397
+ /* --------------------------------------------------------------------------
398
+ 13c. QR codes + chart/SMILES canvases (print-safe: plate, no screen overlay)
399
+ -------------------------------------------------------------------------- */
400
+ .orz-doc.markdown-body span.qrcode {
401
+ display: inline-block;
402
+ padding: 6px;
403
+ line-height: 0;
404
+ background: #fff;
405
+ border-radius: 4px;
406
+ break-inside: avoid;
407
+ }
408
+ .orz-doc.markdown-body span.qrcode svg,
409
+ .orz-doc.markdown-body span.qrcode img {
410
+ display: block;
411
+ width: 100%;
412
+ height: auto;
413
+ max-width: 160px;
414
+ }
415
+ .orz-doc.markdown-body .qrcode__icon { display: none; } /* screen-only expand affordance */
416
+
417
+ .orz-doc.markdown-body canvas.orz-chart,
418
+ .orz-doc.markdown-body img.orz-chart,
419
+ .orz-doc.markdown-body canvas[data-smiles] {
420
+ display: block;
421
+ max-width: 100%;
422
+ height: auto;
423
+ margin: 1.2em auto;
424
+ break-inside: avoid;
425
+ }
426
+
427
+ /* --------------------------------------------------------------------------
428
+ 14. Page break ( ::: page-break → <div class="page-break"> )
429
+ -------------------------------------------------------------------------- */
430
+ .page-break {
431
+ break-before: page;
432
+ page-break-before: always;
433
+ }
434
+
435
+ /* --------------------------------------------------------------------------
436
+ 15. Document elements (.orz-element.orz-el-<kind>)
437
+ Base spacing only; specific element kinds get their look from the
438
+ element-scoped CSS injected by the engine and from theme layers.
439
+ -------------------------------------------------------------------------- */
440
+ .orz-element {
441
+ margin: 0 0 1.4em;
442
+ }
443
+
444
+ .orz-element:last-child {
445
+ margin-bottom: 0;
446
+ }
447
+
448
+ /* A title/cover element placed on its own page (placement: page).
449
+ The engine/elements emit the `.orz-place-page` class (see elements.ts +
450
+ docs/dom-contract.md); this mirrors its break for theme-level consistency. */
451
+ .orz-element.orz-place-page {
452
+ break-after: page;
453
+ page-break-after: always;
454
+ }
455
+
456
+ /* --------------------------------------------------------------------------
457
+ 16. Table of contents (.orz-toc)
458
+ Dotted leaders + right-aligned page numbers. The runtime fills the page
459
+ number text into the [data-page] / .orz-toc-page slots after pagination.
460
+ The leader is drawn between the title and the number using a flexible
461
+ dotted span so it stretches to fill the row.
462
+ -------------------------------------------------------------------------- */
463
+ .orz-toc {
464
+ margin: 1.4em 0;
465
+ }
466
+
467
+ .orz-toc ul,
468
+ .orz-toc ol {
469
+ list-style: none;
470
+ margin: 0;
471
+ padding-left: 0;
472
+ }
473
+
474
+ .orz-toc ul ul,
475
+ .orz-toc ol ol {
476
+ padding-left: 1.4em;
477
+ }
478
+
479
+ .orz-toc li {
480
+ margin: 0.25em 0;
481
+ }
482
+
483
+ /* Each entry is a row: link/title on the left, page number on the right,
484
+ with a dotted leader filling the gap. Works whether the entry markup is
485
+ <a> + page slot or a flC container. */
486
+ .orz-toc a,
487
+ .orz-toc .orz-toc-entry {
488
+ display: flex;
489
+ align-items: baseline;
490
+ text-decoration: none;
491
+ color: var(--text-main, #1a1a1a);
492
+ gap: 0.4em;
493
+ }
494
+
495
+ /* The dotted leader: a flexible element between title and page number. */
496
+ .orz-toc a::after,
497
+ .orz-toc .orz-toc-entry .orz-toc-leader {
498
+ content: "";
499
+ flex: 1 1 auto;
500
+ align-self: stretch;
501
+ margin: 0 0.25em;
502
+ border-bottom: 1px dotted var(--toc-leader, #999);
503
+ transform: translateY(-0.25em);
504
+ }
505
+
506
+ /* Right-aligned page number slot (runtime fills the text). */
507
+ .orz-toc a > .orz-toc-page,
508
+ .orz-toc .orz-toc-page,
509
+ .orz-toc [data-page]::after {
510
+ flex: 0 0 auto;
511
+ font-variant-numeric: tabular-nums;
512
+ color: var(--text-muted, #555);
513
+ }
514
+
515
+ /* When the page number is supplied via a data attribute, render it. */
516
+ .orz-toc [data-page]::after {
517
+ content: attr(data-page);
518
+ }
519
+
520
+ /* --------------------------------------------------------------------------
521
+ 17. Print hardening — hide screen-only constructs the skill discourages
522
+ (§9). Guidance, not a hard block, but a printed page should never show
523
+ video embeds or interactive chrome.
524
+ -------------------------------------------------------------------------- */
525
+ @media print {
526
+ .orz-doc.markdown-body .youtube-embed,
527
+ .orz-doc.markdown-body .tabs-bar {
528
+ display: none !important;
529
+ }
530
+
531
+ /* Reveal spoiler content on paper (it can't be toggled in print). */
532
+ .orz-doc.markdown-body details.spoil {
533
+ break-inside: avoid;
534
+ }
535
+ .orz-doc.markdown-body details.spoil > :not(summary) {
536
+ display: block !important;
537
+ }
538
+ }