@litfamily/litgrok 1.0.13 → 1.0.15

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 (114) hide show
  1. package/.grok/hooks/auto-handoff-gate.mjs +15 -2
  2. package/.grok/rules/00-litgrok.md +1 -1
  3. package/.grok/skills/frontend-ui-ux/THIRD-PARTY-NOTICE.txt +0 -5
  4. package/.grok/skills/frontend-ui-ux/references/slop-register.md +4 -4
  5. package/.grok/skills/frontend-ui-ux/scripts/import-design-intelligence.mjs +1 -1
  6. package/.grok/skills/lit-docx/SKILL.md +59 -11
  7. package/.grok/skills/lit-docx/examples/01-report-ko.md +137 -0
  8. package/.grok/skills/lit-docx/examples/02-brief-ko.md +82 -0
  9. package/.grok/skills/lit-docx/examples/03-manual-ko.md +118 -0
  10. package/.grok/skills/lit-docx/examples/04-proposal-ko.md +92 -0
  11. package/.grok/skills/lit-docx/examples/05-memo-en.md +42 -0
  12. package/.grok/skills/lit-docx/examples/06-journal-en.md +90 -0
  13. package/.grok/skills/lit-docx/examples/07-report-en.md +103 -0
  14. package/.grok/skills/lit-docx/examples/08-proposal-en.md +90 -0
  15. package/.grok/skills/lit-docx/examples/09-memo-ko.md +41 -0
  16. package/.grok/skills/lit-docx/references/components.md +151 -0
  17. package/.grok/skills/lit-docx/references/direction-step.md +129 -0
  18. package/.grok/skills/lit-docx/references/page-composition.md +129 -0
  19. package/.grok/skills/lit-docx/references/tonalities/brief.md +98 -0
  20. package/.grok/skills/lit-docx/references/tonalities/journal.md +100 -0
  21. package/.grok/skills/lit-docx/references/tonalities/manual.md +107 -0
  22. package/.grok/skills/lit-docx/references/tonalities/memo.md +95 -0
  23. package/.grok/skills/lit-docx/references/tonalities/proposal.md +105 -0
  24. package/.grok/skills/lit-docx/references/tonalities/report.md +114 -0
  25. package/.grok/skills/lit-docx/scripts/convert_md_to_docx.py +394 -51
  26. package/.grok/skills/lit-docx/scripts/docx_design.py +2446 -0
  27. package/.grok/skills/lit-docx/scripts/docx_gate.py +203 -0
  28. package/.grok/skills/lit-docx/scripts/docx_layout.py +959 -0
  29. package/.grok/skills/lit-docx/scripts/run.mjs +3 -2
  30. package/.grok/skills/lit-docx/scripts/slop_lint.py +63 -17
  31. package/.grok/skills/lit-docx/templates/tonalities/brief.yaml +29 -0
  32. package/.grok/skills/lit-docx/templates/tonalities/journal.yaml +26 -0
  33. package/.grok/skills/lit-docx/templates/tonalities/manual.yaml +27 -0
  34. package/.grok/skills/lit-docx/templates/tonalities/memo.yaml +27 -0
  35. package/.grok/skills/lit-docx/templates/tonalities/proposal.yaml +27 -0
  36. package/.grok/skills/lit-docx/templates/tonalities/report.yaml +27 -0
  37. package/.grok/skills/lit-pptx/NOTICE.md +1 -1
  38. package/.grok/skills/lit-pptx/SKILL.md +70 -14
  39. package/.grok/skills/lit-pptx/agents/analyst.md +1 -1
  40. package/.grok/skills/lit-pptx/agents/thesis.md +2 -2
  41. package/.grok/skills/lit-pptx/examples/01-pitch-signal-ko.md +175 -0
  42. package/.grok/skills/lit-pptx/examples/02-business-review-ledger-ko.md +199 -0
  43. package/.grok/skills/lit-pptx/examples/03-research-talk-paper-en.md +177 -0
  44. package/.grok/skills/lit-pptx/examples/04-lecture-chalk-ko.md +176 -0
  45. package/.grok/skills/lit-pptx/examples/05-data-review-night-en.md +221 -0
  46. package/.grok/skills/lit-pptx/examples/06-image-led-atlas-en.md +143 -0
  47. package/.grok/skills/lit-pptx/examples/07-briefing-gazette-ko.md +192 -0
  48. package/.grok/skills/lit-pptx/examples/08-status-update-ledger-en.md +168 -0
  49. package/.grok/skills/lit-pptx/examples/09-pitch-studio-en.md +157 -0
  50. package/.grok/skills/lit-pptx/examples/10-image-led-studio-ko.md +175 -0
  51. package/.grok/skills/lit-pptx/examples/11-business-review-night-en.md +181 -0
  52. package/.grok/skills/lit-pptx/examples/12-status-update-gazette-ko.md +199 -0
  53. package/.grok/skills/lit-pptx/pretendard-font/public/static/Pretendard-Bold.otf +0 -0
  54. package/.grok/skills/lit-pptx/pretendard-font/public/static/Pretendard-Regular.otf +0 -0
  55. package/.grok/skills/lit-pptx/references/density-and-fill.md +155 -0
  56. package/.grok/skills/lit-pptx/references/direction-step.md +211 -0
  57. package/.grok/skills/lit-pptx/references/layout-families.md +193 -0
  58. package/.grok/skills/lit-pptx/references/title-treatments.md +134 -0
  59. package/.grok/skills/lit-pptx/references/tonalities/atlas.md +124 -0
  60. package/.grok/skills/lit-pptx/references/tonalities/chalk.md +135 -0
  61. package/.grok/skills/lit-pptx/references/tonalities/gazette.md +127 -0
  62. package/.grok/skills/lit-pptx/references/tonalities/ledger.md +134 -0
  63. package/.grok/skills/lit-pptx/references/tonalities/night.md +132 -0
  64. package/.grok/skills/lit-pptx/references/tonalities/paper.md +127 -0
  65. package/.grok/skills/lit-pptx/references/tonalities/signal.md +118 -0
  66. package/.grok/skills/lit-pptx/references/tonalities/studio.md +123 -0
  67. package/.grok/skills/lit-pptx/scripts/compile-deck.js +65 -17
  68. package/.grok/skills/lit-pptx/scripts/craft_extras.py +82 -18
  69. package/.grok/skills/lit-pptx/scripts/deck_output.py +598 -0
  70. package/.grok/skills/lit-pptx/scripts/embed_fonts.py +1 -1
  71. package/.grok/skills/lit-pptx/scripts/inventory.py +6 -2
  72. package/.grok/skills/lit-pptx/scripts/lib/directive-parser.js +2 -2
  73. package/.grok/skills/lit-pptx/scripts/lib/grid-resolver.js +521 -0
  74. package/.grok/skills/lit-pptx/scripts/lib/layout-resolver.js +401 -16
  75. package/.grok/skills/lit-pptx/scripts/lib/markdown-loader.js +6 -4
  76. package/.grok/skills/lit-pptx/scripts/lib/render-adapter-html.js +2 -2
  77. package/.grok/skills/lit-pptx/scripts/lib/render-adapter-pptx.js +500 -126
  78. package/.grok/skills/lit-pptx/scripts/lib/render-pack.js +3558 -0
  79. package/.grok/skills/lit-pptx/scripts/lib/slide-ast.js +54 -6
  80. package/.grok/skills/lit-pptx/scripts/lib/template-registry.js +335 -11
  81. package/.grok/skills/lit-pptx/scripts/qa_deck.py +43 -10
  82. package/.grok/skills/lit-pptx/scripts/run.mjs +3 -2
  83. package/.grok/skills/lit-pptx/scripts/validate_pptx.py +17 -5
  84. package/.grok/skills/lit-pptx/templates/boilerplate_professional.css +6 -6
  85. package/.grok/skills/lit-pptx/templates/enrolled/AZURE-A2Z/layout-mapping.yaml +1 -1
  86. package/.grok/skills/lit-pptx/templates/enrolled/AZURE-A2Z/template.yaml +4 -1
  87. package/.grok/skills/lit-pptx/templates/enrolled/AZURE-PRO/layout-mapping.yaml +1 -1
  88. package/.grok/skills/lit-pptx/templates/enrolled/AZURE-PRO/template.yaml +4 -1
  89. package/.grok/skills/lit-pptx/templates/tonalities/atlas/pack.yaml +99 -0
  90. package/.grok/skills/lit-pptx/templates/tonalities/chalk/pack.yaml +104 -0
  91. package/.grok/skills/lit-pptx/templates/tonalities/gazette/pack.yaml +99 -0
  92. package/.grok/skills/lit-pptx/templates/tonalities/ledger/pack.yaml +100 -0
  93. package/.grok/skills/lit-pptx/templates/tonalities/night/pack.yaml +100 -0
  94. package/.grok/skills/lit-pptx/templates/tonalities/paper/pack.yaml +105 -0
  95. package/.grok/skills/lit-pptx/templates/tonalities/signal/pack.yaml +101 -0
  96. package/.grok/skills/lit-pptx/templates/tonalities/studio/pack.yaml +99 -0
  97. package/.grok/skills/lit-typographic-motion/THIRD_PARTY_NOTICES +1 -1
  98. package/.grok/skills/lit-typographic-motion/fonts/pins.json +6 -6
  99. package/.grok/skills/lit-typographic-motion/references/runtime.md +1 -1
  100. package/.grok/skills/lit-typographic-motion/references/style-bible.md +2 -2
  101. package/.grok/skills/lit-typographic-motion/references/type-craft.md +2 -2
  102. package/.grok/skills/lit-typographic-motion/scripts/lib/gate.mjs +1 -1
  103. package/.grok/skills/litgrok/SKILL.md +1 -1
  104. package/.grok-plugin/plugin.json +1 -1
  105. package/CHANGELOG.md +11 -0
  106. package/README.md +9 -9
  107. package/README_ko-KR.md +9 -9
  108. package/docs/assets/readme/badge-version.svg +1 -1
  109. package/docs/reference.md +1 -1
  110. package/docs/reference_ko-KR.md +1 -1
  111. package/package.json +1 -1
  112. package/plugin.json +1 -1
  113. package/.grok/skills/lit-pptx/pretendard-font/public/static/PretendardGOV-Bold.otf +0 -0
  114. package/.grok/skills/lit-pptx/pretendard-font/public/static/PretendardGOV-Regular.otf +0 -0
@@ -0,0 +1,127 @@
1
+ # Paper
2
+
3
+ Paper is a journal page on a screen. Ink on white, hairlines instead of fills, figures first with
4
+ numbered captions, booktabs tables, and one deep crimson kept for the proposed method. The cover is a
5
+ title page: a heavy rule, the title, a hairline, the authors, the place and the date. Nothing on a
6
+ Paper slide is decoration; every mark is a rule, a figure or a word.
7
+
8
+ **Choose it** for research talks, thesis defences, technical reviews and written analyses: decks
9
+ built on figures, tables and citations, often with a references slide. **It is wrong** for a sales or
10
+ launch room, where the restraint reads as cold, and for decks that need an agenda, a KPI row, a
11
+ timeline or a process, none of which Paper carries.
12
+
13
+ ## Tokens
14
+
15
+ | Role | Value |
16
+ |---|---|
17
+ | ground / surface | `#FFFFFF` / `#F5F5F6` |
18
+ | ink / ink-muted / line | `#111418` / `#50565E` / `#C9CDD2` |
19
+ | accent / accent-deep / accent-tint | `#8C1C2B` / `#5E121C` / `#F6E6E8` |
20
+ | field / on-field | `#111418` / `#FFFFFF` |
21
+ | positive / negative | `#1E6B3A` / `#50565E` |
22
+ | chart series | `#8C1C2B`, `#111418`, `#50565E`, `#2E5E8A` (series order, first is the proposed method) |
23
+ | faces | Pretendard Bold for titles and display, Regular for body and numerals |
24
+ | figures | tabular |
25
+ | radius / edge | 0 / border |
26
+
27
+ Density 10, compact ramp. Variance 5 allows four treatments, which is all Paper has.
28
+
29
+ **Tables**: booktabs (a heavy rule above the header, a light one under it, a heavy one at the foot),
30
+ no fills, numbers right-aligned and tabular, totals bold. **Charts**: hairline gridlines, direct
31
+ labels, colour by series order with the proposed method first, no annotation. **Pictures** never
32
+ bleed, crop or take a frame.
33
+
34
+ ## Titles by role
35
+
36
+ | Role | Default | Also allowed |
37
+ |---|---|---|
38
+ | content | `top-rule` | `side-rail` (text-column) |
39
+ | data | `top-rule`; a comparison is a ruled table under `top-rule` (the pack's `structure`, kept even when the deck already leans on it) | `side-rail`, `bottom-anchor` |
40
+ | data-takeaway | `bottom-anchor` | `top-rule`, `side-rail` |
41
+ | image | `bottom-anchor` | `top-rule`, `side-rail` |
42
+ | statement | `statement` | `top-rule` (quote) |
43
+ | definition | `side-rail` | `top-rule` |
44
+ | reference | `top-rule` | — |
45
+
46
+ The top-rule title rests on a full-width hairline; Paper has no short accent bar.
47
+
48
+ ## Families and variants
49
+
50
+ figure-academic, figure-pair, method, chart-insight, full-chart, table-insight, comparison, quote,
51
+ statement, text-column, references-appendix.
52
+
53
+ - Covers: `cover-index` (the title beside the part list; needs two or more sections, since Paper has
54
+ no agenda family), `cover-typographic` (the journal title page), `cover-split-image`.
55
+ - Sections: `section-rule` (an index page with this part marked), `section-field`.
56
+ - Closings: `closing-summary-list` (findings, limits, next experiment with owner and date),
57
+ `closing-ask`.
58
+ - Display: statements sit between two hairlines; big-number panels are outlined in ink; closings set
59
+ the next step under a rule.
60
+
61
+ Decoration: hairline rules and box outlines only.
62
+
63
+ ## Do
64
+
65
+ - Number every figure and table and give each caption its condition and source: "Figure 2. Logger
66
+ positions at k = 12, test district (sample)".
67
+ - Use `figure-academic` for a figure that needs reading: observation, limitation, implication.
68
+ - Reserve crimson for one thing across the whole talk: the proposed method's series, row or label.
69
+ - Put the method on a `method` slide with the objective and each term defined.
70
+ - End with references and the definitions the talk relies on, eight to ten lines.
71
+
72
+ ## Avoid
73
+
74
+ - The short accent bar under a title.
75
+ - Coloured card fills.
76
+ - Figures without numbered captions.
77
+ - The accent on anything other than the proposed method.
78
+ - Bullets longer than about 60 characters beside a figure under a bottom title; that column is three
79
+ grid columns wide.
80
+
81
+ ## Two worked slides
82
+
83
+ Both are trimmed for reading. Complete slides of the same kind in the example decks carry the
84
+ extra rows, groups and takeaways that fill a compact page and pass the gate.
85
+
86
+ A results table with the reading beside it:
87
+
88
+ ```markdown
89
+ ---
90
+ layout: table-insight
91
+
92
+ ## Detection and localisation by logger budget
93
+
94
+ | Loggers (k) | Detected | Top-3 segment hit | Median error |
95
+ |---|---|---|---|
96
+ | 4 | 71 % | 38 % | 610 m |
97
+ | 8 | 84 % | 55 % | 390 m |
98
+ | 12 | 91 % | 68 % | 240 m |
99
+ | 16 | 94 % | 74 % | 190 m |
100
+ | 24 | 96 % | 79 % | 150 m |
101
+
102
+ > Table 1. Results over 6,800 simulated leaks, night demand (sample data)
103
+
104
+ - Gains flatten after k = 16
105
+ - At k = 12 the median search radius is 240 m
106
+ - Source: sample simulation study, October 2026 (sample)
107
+ ---
108
+ ```
109
+
110
+ A numbered figure with its reading:
111
+
112
+ ```markdown
113
+ ---
114
+ layout: figure-academic
115
+
116
+ ## 시험 관망과 압력계 배치
117
+
118
+ ![압력계 12대 배치, 시험 구역 (예시) | 출처: 예시 그림](assets/example-b.png)
119
+
120
+ - **관찰** 절반이 구역 중심이 아닌 긴 송수관 위에 놓인다
121
+ - **한계** 야간 수요 기준으로 맞춘 배치다
122
+ - **의미** 접근이 쉬운 지점을 골라도 정확도 손실이 작다
123
+ - 출처: 예시 수리 모형, 2025년 소화전 시험으로 보정 (예시)
124
+ ---
125
+ ```
126
+
127
+ Full deck: `examples/03-research-talk-paper-en.md`.
@@ -0,0 +1,118 @@
1
+ # Signal
2
+
3
+ Signal is for a room that listens: a pitch, a launch, a proposal presented live. One idea per slide,
4
+ set large on white, with a single hot red that belongs to the subject. Titles take display size,
5
+ figures stand on red panels, and a statement page is allowed for a real quotation. The density is
6
+ still 10: the large title is offset by full evidence underneath.
7
+
8
+ **Choose it** for pitches and launches presented in person, and when content slides are short
9
+ (around 40 Korean glyphs or 80 Latin characters of argument each) but every slide still has figures
10
+ behind it. **It is wrong** when the audience studies the file afterwards, when tables make up most of
11
+ the content (Signal has no `ledger-table` and no dashboard), and when the deck needs an agenda, a
12
+ timeline or long itemised text, none of which the pack carries.
13
+
14
+ ## Tokens
15
+
16
+ | Role | Value |
17
+ |---|---|
18
+ | ground / surface | `#FFFFFF` / `#F4F4F5` |
19
+ | ink / ink-muted / line | `#15131A` / `#55525C` / `#D4D4D8` |
20
+ | accent / accent-deep / accent-tint | `#C8361A` / `#6E1A0C` / `#FBE7E2` |
21
+ | field / on-field | `#C8361A` / `#FFFFFF` |
22
+ | positive / negative | `#1E7A3F` / `#15131A` (a loss keeps the ink and carries its ▼) |
23
+ | chart series | `#C8361A`, `#15131A`, `#6B6870`, `#2F6F8F` |
24
+ | faces | Pretendard Bold for display, titles and figures; Regular for body and labels |
25
+ | figures | proportional |
26
+ | radius / edge | 0 / fill |
27
+
28
+ Density 10, compact ramp (title 26, display 36). Variance 6 allows four treatments; the pack has four.
29
+
30
+ **Tables**: open style, no header fill, a rule above and below, numbers right-aligned, totals bold;
31
+ the row whose first cell appears in the title is tinted red-pale as the row the slide is about.
32
+ **Charts**: no gridlines, direct labels, the red on the highlighted series, annotations allowed.
33
+ **Pictures** may bleed and crop.
34
+
35
+ ## Titles by role
36
+
37
+ | Role | Default | Also allowed |
38
+ |---|---|---|
39
+ | content | `top-plain-large` | `top-rule`, `bottom-anchor` (by family) |
40
+ | data | `top-rule` | `top-plain-large`, `bottom-anchor` |
41
+ | data-takeaway | `top-plain-large` | `top-rule`, `bottom-anchor` |
42
+ | sequence | `top-rule` | `top-plain-large` |
43
+ | image | `bottom-anchor` | `top-plain-large`, `top-rule` |
44
+ | statement | `statement` | — |
45
+
46
+ `top-plain-large` sets the title at 36 pt in two lines of about 20 Korean glyphs; write titles that
47
+ fit, or the engine moves the slide to `top-rule`.
48
+
49
+ ## Families and variants
50
+
51
+ statement, big-number, image-split, asymmetric-feature, process, kpi-row, chart-insight, full-chart,
52
+ comparison, table-insight, quote.
53
+
54
+ - Covers: `cover-numeral` (a year or real figure above the title), `cover-typographic` (drawn as a
55
+ drench: the whole page red, the title low), `cover-split-field` (half the page red).
56
+ - Sections: `section-field`, `section-numeral`.
57
+ - Closings: `closing-statement` (one sentence, no table), `closing-ask` (the ask as action rows with
58
+ the next step on a red band). Use `closing-ask` whenever there is money, a decision or a date.
59
+ - Display: statements stand open on white; big numbers sit on the red field with white figures.
60
+
61
+ Decoration: colour field, hairline rules, real numerals. No cards.
62
+
63
+ ## Do
64
+
65
+ - Write the title as the topic, then let the first takeaway say the claim in one line.
66
+ - Use `big-number` for two to four related figures, each with its basis; the red panel carries them.
67
+ - Put the product on an `image-split` or `asymmetric-feature` early, so the room sees the thing.
68
+ - Keep lists to four items; a fifth goes to the next slide or into a table.
69
+ - Use `comparison` with matching criteria labels for "today versus with us".
70
+
71
+ ## Avoid
72
+
73
+ - Red for losses; a loss is ink with ▼.
74
+ - More than two lines of display text on any slide.
75
+ - Cards and boxed bullet groups.
76
+ - A statement slide that holds a claim; claims go in the body of a content slide.
77
+
78
+ ## Two worked slides
79
+
80
+ Both are trimmed for reading. Complete slides of the same kind in the example decks carry the
81
+ extra rows, groups and takeaways that fill a compact page and pass the gate.
82
+
83
+ Pilot figures on the red panel, with their evidence:
84
+
85
+ ```markdown
86
+ ---
87
+ layout: big-number
88
+
89
+ ## 시범 운영 6개월 핵심 지표
90
+
91
+ | 폐기 비율 변화 | 유료 전환율 | 월 이탈률 |
92
+ |---|---|---|
93
+ | −3.3%p | 83% | 1.8% |
94
+ | 8.9% → 5.6% | 시범 12곳 중 10곳 | 유료 전환 후 3개월 평균 |
95
+
96
+ - 시범 매장 한 곳당 월 폐기 금액이 평균 47만 원 줄었다
97
+ - 이탈한 매장 두 곳은 모두 폐업이 사유였다
98
+ - 출처: 예시 스타트업 시범 운영 기록, 2026년 4-9월 (예시)
99
+ ---
100
+ ```
101
+
102
+ A short process, each step saying what happens:
103
+
104
+ ```markdown
105
+ ---
106
+ layout: process
107
+
108
+ ## From order to restock suggestion
109
+
110
+ - **1. Sales sync** menu sales arrive from the till every 15 minutes
111
+ - **2. Stock deduction** recipes convert each sale into ingredient use
112
+ - **3. Count correction** the closing count fixes the gap between book and shelf
113
+ - **4. Order suggestion** tomorrow's bookings and weekday patterns set the quantity
114
+ - Source: sample service design document v0.9, September 2026 (sample)
115
+ ---
116
+ ```
117
+
118
+ Full deck: `examples/01-pitch-signal-ko.md`.
@@ -0,0 +1,123 @@
1
+ # Studio
2
+
3
+ Studio is an editorial spread. The 12-column grid shows through hairlines between columns, titles
4
+ take a side rail or open a page at display size, splits are asymmetric, real figures run on tinted
5
+ panels, and a dark ochre points at one thing per slide. It mixes the most title treatments of any
6
+ pack, so a deck feels laid out page by page rather than filled from one template.
7
+
8
+ **Choose it** for narratives that combine pictures and figures: a pitch for a physical product, a
9
+ portfolio, a public lecture, an annual story. **It is wrong** for dense data reviews, where its
10
+ open layouts starve tables (Studio has no table family), and for read-alone briefings.
11
+
12
+ ## Tokens
13
+
14
+ | Role | Value |
15
+ |---|---|
16
+ | ground / surface | `#FFFFFF` / `#F2F2F0` |
17
+ | ink / ink-muted / line | `#141414` / `#525252` / `#D2D2CE` |
18
+ | accent / accent-deep / accent-tint | `#8A5A00` / `#4D3200` / `#F5ECD9` |
19
+ | field / on-field | `#141414` / `#FFFFFF` |
20
+ | positive / negative | `#1E7A3F` / `#B3261E` |
21
+ | chart series | `#8A5A00`, `#141414`, `#525252`, `#3B5F7F` |
22
+ | faces | Pretendard Bold for titles, display and figures; Regular for body |
23
+ | figures | proportional |
24
+ | radius / edge | 0 / fill |
25
+
26
+ Density 10, compact ramp. **Variance 8 allows all five treatments**, and the engine uses them.
27
+
28
+ **Tables** (inside KPI rows and timelines): open style, a 2 pt rule under the header, no fills,
29
+ numbers right-aligned. **Charts**: no gridlines, direct labels, the ochre on the highlighted series,
30
+ annotations allowed. **Pictures** bleed and crop freely, with no frame.
31
+
32
+ ## Titles by role
33
+
34
+ | Role | Default | Also allowed |
35
+ |---|---|---|
36
+ | content | `side-rail` | `top-plain-large` (text-two-column takes only this) |
37
+ | data | `top-plain-large` | `side-rail`, `bottom-anchor` |
38
+ | data-takeaway | `side-rail` | `bottom-anchor`, `top-plain-large` |
39
+ | sequence | `side-rail` in the pack map | the timeline takes `top-plain-large` or `bottom-anchor` |
40
+ | image | `side-rail`: the picture across columns 5-12, its facts in the rail under the title | `top-plain-large`, `bottom-anchor`, `overlay` (image-full only) |
41
+ | statement | `statement` | — |
42
+
43
+ ## Families and variants
44
+
45
+ asymmetric-feature, big-number, image-split, image-full, photo-grid, text-two-column, chart-insight,
46
+ kpi-row, timeline, comparison, statement.
47
+
48
+ - Covers: `cover-split-image` (the title beside the deck's first picture), `cover-rail`,
49
+ `cover-numeral` (a year in the title or date, e.g. "포트폴리오 2026").
50
+ - Sections: `section-numeral`, `section-rail`. A single section with no agenda draws no numeral and
51
+ sets its title as a statement over the slides it opens.
52
+ - Closings: `closing-contact-split` (action rows beside a dark field holding each amount or date, the
53
+ next step as a band meeting it), `closing-summary-list`.
54
+ - Display: a statement stands between two hairlines on the open page (a short rail beside it stood
55
+ empty); big-number panels use the ochre
56
+ tint; closings put the next step on a dark band.
57
+
58
+ Decoration: column hairlines, real numerals, rail fill, colour field, caption band.
59
+
60
+ ## Captions
61
+
62
+ The cover borrows the deck's first picture with its caption, and `image-full` sets its caption on a
63
+ panel, where the gate reads caption and source. Leave the number out of the caption: the engine
64
+ numbers figures in deck order.
65
+
66
+ ## Do
67
+
68
+ - Let large figures be real figures: a `big-number` panel of two or three values with their basis.
69
+ - Use asymmetric splits: `asymmetric-feature` with five short bullets beside a large picture.
70
+ - Give `text-two-column` four to six groups with two or three sub-points each; flat bullets leave the
71
+ page half empty at density 10 (example 10).
72
+ - Alternate full-bleed pages with split pages and a grid of three.
73
+ - Close with `closing-contact-split` when there is money to ask for, keyed by the amount column.
74
+
75
+ ## Avoid
76
+
77
+ - Large numerals that are not real figures.
78
+ - Column hairlines running through text.
79
+ - Two side-rail slides with the same split in a row.
80
+ - Centred body text.
81
+
82
+ ## Two worked slides
83
+
84
+ Both are trimmed for reading. Complete slides of the same kind in the example decks carry the
85
+ extra rows, groups and takeaways that fill a compact page and pass the gate.
86
+
87
+ A feature told by one large picture and a narrow column:
88
+
89
+ ```markdown
90
+ ---
91
+ layout: asymmetric-feature
92
+
93
+ ## A refill station inside a neighbourhood grocer
94
+
95
+ ![Station with six products in 0.9 m of shelf width (sample) | Source: sample photo](assets/example-a.png)
96
+
97
+ - **What it is** a self-service dispenser for six cleaning products
98
+ - **How it works** customers bring any bottle; the scale reads the tare
99
+ - **Price** 25-35 % below the same product in a new bottle
100
+ - **Store share** 18 % of refill revenue goes to the grocer
101
+ ---
102
+ ```
103
+
104
+ Figures as a panel with their evidence:
105
+
106
+ ```markdown
107
+ ---
108
+ layout: big-number
109
+
110
+ ## 스테이션당 단위 경제성
111
+
112
+ | 월 매출 | 월 공헌이익 | 회수 기간 |
113
+ |---|---|---|
114
+ | 119만 원 | 31만 원 | 19개월 |
115
+ | 월 412회 리필 기준 | 매장 몫과 재고 차감 후 | 설치비 590만 원 |
116
+
117
+ - 9월 시범 평균이며 전망치가 아니다
118
+ - 월 500회 리필이면 회수 기간은 14개월로 줄어든다
119
+ - 출처: 예시 시범 운영 손익, 2026년 9월 (예시)
120
+ ---
121
+ ```
122
+
123
+ Full decks: `examples/09-pitch-studio-en.md`, `examples/10-image-led-studio-ko.md`.
@@ -88,7 +88,7 @@ function compileDeck(source) {
88
88
  // export exists to prevent.
89
89
  const BUNDLED_FONTS = [
90
90
  { match: /Pretendard/i, dir: "pretendard-font/public/static",
91
- files: ["PretendardGOV-Regular.otf", "PretendardGOV-Bold.otf"] },
91
+ files: ["Pretendard-Regular.otf", "Pretendard-Bold.otf"] },
92
92
  { match: /에이투지체/, dir: "fonts/a2z-font",
93
93
  files: ["A2Z-Regular.otf", "A2Z-Bold.otf"] },
94
94
  ];
@@ -144,11 +144,23 @@ async function resolveAndRender(ast, templateName, outputs, options = {}) {
144
144
  throw new Error("layout-resolver module not available. Cannot resolve layouts.");
145
145
  }
146
146
 
147
- const templateObj = templateRegistry.loadTemplate(templateName);
147
+ // A tonality (flag or frontmatter) is a design direction read from a pack; without one the named
148
+ // template loads as a legacy pack and keeps its own look.
149
+ const meta = (ast.deck && ast.deck.metadata) || {};
150
+ const tonality = options.tonality || meta.tonality || null;
151
+ const templateObj = tonality
152
+ ? templateRegistry.loadTonality(tonality, { density: meta.density, variance: meta.variance, canvas: meta.canvas, faces: options.faces || meta.faces })
153
+ : templateRegistry.loadTemplate(templateName);
154
+ if (tonality) {
155
+ const d = templateObj.pack.dials;
156
+ console.log(`Tonality ${templateObj.pack.id} · density ${d.density} · variance ${d.variance} · ${d.canvas} ${templateObj.pack.grid.name} grid` +
157
+ (templateName && templateName !== tonality ? ` (template ${templateName} not used)` : ""));
158
+ }
159
+ const can = (capability) => templateRegistry.hasCapability(templateObj, capability);
148
160
 
149
- // Font override (azure-style templates): swap the whole font system regardless
150
- // of which template was chosen. Applied before accent (independent of colour).
151
- if (options.font && templateObj.template && templateObj.template.render_style === "azure") {
161
+ // Font override (templates with the font-swap capability): swap the whole font system
162
+ // regardless of which template was chosen. Applied before accent (independent of colour).
163
+ if (options.font && can("font-swap")) {
152
164
  const { applyFont, KEYS } = require("./lib/font-map");
153
165
  if (KEYS.includes(options.font)) {
154
166
  applyFont(templateObj, options.font);
@@ -159,10 +171,10 @@ async function resolveAndRender(ast, templateName, outputs, options = {}) {
159
171
  const resolved = layoutResolver.resolve(ast, templateObj);
160
172
  if (options.sourceDir) resolved.sourceDir = options.sourceDir;
161
173
 
162
- // Custom accent recolor (azure-style templates only): derive a WCAG-safe
174
+ // Custom accent recolor (templates with the recolor capability): derive a WCAG-safe
163
175
  // palette from the accent hex, override template tokens + hardcoded decoration
164
176
  // colors, and regenerate the gradient circle PNGs in the new hue.
165
- if (options.accent && templateObj.template && templateObj.template.render_style === "azure") {
177
+ if (options.accent && can("recolor")) {
166
178
  const { derivePalette, defaultToDerivedMap } = require("./lib/derive-palette");
167
179
  const { genGradientAssets } = require("./lib/gen-gradient-assets");
168
180
  const os = require("os");
@@ -200,11 +212,11 @@ async function resolveAndRender(ast, templateName, outputs, options = {}) {
200
212
  console.log(`Accent ${options.accent} → primary ${derived.primary} (white-contrast ${derived._ratios.whiteOnPrimary}:1)`);
201
213
  }
202
214
 
203
- // Blurred gradient-mesh background (azure-style): ambient wash on cover/closing/
215
+ // Blurred gradient-mesh background (mesh-background capability): ambient wash on cover/closing/
204
216
  // content (light) and a deep textured wash on section dividers (dark). Uses the
205
217
  // ACTIVE palette (so it respects --accent). The dark mesh sits ABOVE the base
206
218
  // section fill rect, so qa_deck still resolves the (dark) fill behind white text.
207
- if (options.bg === "mesh" && templateObj.template && templateObj.template.render_style === "azure") {
219
+ if (options.bg === "mesh" && can("mesh-background")) {
208
220
  const { genMeshBg } = require("./lib/gen-bg");
209
221
  const os = require("os");
210
222
  const dims = templateObj.template.dimensions || {};
@@ -278,8 +290,36 @@ if (require.main === module) {
278
290
  }
279
291
  process.exit(0);
280
292
  }
293
+ if (args[0] === "--list-tonalities") {
294
+ const reg = require("./lib/template-registry");
295
+ for (const id of reg.listTonalities()) {
296
+ const p = reg.loadPack(id);
297
+ console.log(`${id} — ${p.intent} [density ${p.density}, variance ${p.variance}; ${p.treatments.join(", ")}]`);
298
+ }
299
+ for (const name of reg.listTemplates()) console.log(`${name} (legacy template)`);
300
+ process.exit(0);
301
+ }
281
302
  if (args[0] === "--list-layouts" && args[1]) {
282
303
  const reg = require("./lib/template-registry");
304
+ if (reg.listTonalities().includes(String(args[1]).toLowerCase())) {
305
+ // A tonality lists its families with the titles each can take there, and its variants.
306
+ const G = require("./lib/grid-resolver");
307
+ const p = reg.loadPack(args[1]);
308
+ console.log(`${p.id} — ${p.intent}`);
309
+ console.log(`treatments: ${p.treatments.join(", ")}`);
310
+ console.log("layout families:");
311
+ for (const f of p["layout-families"]) {
312
+ console.log(` ${f} [${G.familyAllows(f).filter((t) => p.treatments.includes(t)).join(", ")}]`);
313
+ }
314
+ console.log(`covers: ${p.covers.join(", ")}`);
315
+ console.log(`sections: ${p.sections.join(", ")}`);
316
+ console.log(`closings: ${p.closings.join(", ")}`);
317
+ process.exit(0);
318
+ }
319
+ if (!reg.listTemplates().includes(args[1])) {
320
+ console.error(`Unknown tonality or template "${args[1]}". Tonalities: ${reg.listTonalities().join(", ")}; legacy templates: ${reg.listTemplates().join(", ")}`);
321
+ process.exit(1);
322
+ }
283
323
  const t = reg.loadTemplate(args[1]);
284
324
  const layouts = (t.mapping && t.mapping.layouts) || {};
285
325
  const caps = (t.capabilities && t.capabilities.supported_blocks) || {};
@@ -295,10 +335,13 @@ if (require.main === module) {
295
335
  if (args.length === 0) {
296
336
  console.error("Usage:");
297
337
  console.error(" node compile-deck.js --list-templates");
298
- console.error(" node compile-deck.js --list-layouts <template>");
338
+ console.error(" node compile-deck.js --list-tonalities");
339
+ console.error(" node compile-deck.js --list-layouts <template or tonality>");
299
340
  console.error(" node compile-deck.js <input.md> [--ast out.json]");
300
341
  console.error(" node compile-deck.js <input.md> --template <name> --html out.html");
301
342
  console.error(" node compile-deck.js <input.md> --template <name> --pptx out.pptx");
343
+ console.error(" node compile-deck.js <input.md> --tonality <id> --pptx out.pptx (or tonality: in the frontmatter)");
344
+ console.error(" node compile-deck.js <input.md> --tonality <id> --faces a2z --pptx out.pptx (A2Z faces on request; Pretendard by default)");
302
345
  console.error(" node compile-deck.js <input.md> --template <name> --ast out.json --html out.html --pptx out.pptx");
303
346
  console.error(" node compile-deck.js <input.md> --template <name> --export-viz-context ctx.json");
304
347
  process.exit(1);
@@ -310,10 +353,12 @@ if (require.main === module) {
310
353
  let htmlPath = null;
311
354
  let pptxPath = null;
312
355
  let embedFonts = false;
356
+ let facesFlag = null;
313
357
  let accent = null;
314
358
  let font = null;
315
359
  let bg = null;
316
360
  let vizContextPath = null;
361
+ let tonalityFlag = null;
317
362
 
318
363
  for (let i = 1; i < args.length; i++) {
319
364
  if (args[i] === "--embed-fonts") { embedFonts = true; continue; }
@@ -321,6 +366,8 @@ if (require.main === module) {
321
366
  if (args[i] === "--font" && args[i + 1]) { font = args[i + 1]; i++; continue; }
322
367
  if (args[i] === "--bg" && args[i + 1]) { bg = args[i + 1]; i++; continue; }
323
368
  if (args[i] === "--export-viz-context" && args[i + 1]) { vizContextPath = args[i + 1]; i++; continue; }
369
+ if (args[i] === "--tonality" && args[i + 1]) { tonalityFlag = args[i + 1]; i++; continue; }
370
+ if (args[i] === "--faces" && args[i + 1]) { facesFlag = args[i + 1]; i++; continue; }
324
371
  if (args[i] === "--ast" && args[i + 1]) {
325
372
  astPath = args[i + 1];
326
373
  i++;
@@ -339,13 +386,14 @@ if (require.main === module) {
339
386
  }
340
387
  }
341
388
 
342
- // If --html or --pptx is requested, --template is required
343
- if ((htmlPath || pptxPath || vizContextPath) && !templateName) {
344
- console.error("Error: --template is required when using --html, --pptx or --export-viz-context");
389
+ const source = fs.readFileSync(inputPath, "utf-8");
390
+
391
+ // A render needs a design: --template, --tonality, or a tonality: line in the frontmatter.
392
+ const frontTonality = (source.match(/^---[ \t]*\n([\s\S]*?)\n---/) || ["", ""])[1].match(/^tonality:[ \t]*(\S+)/m);
393
+ if ((htmlPath || pptxPath || vizContextPath) && !templateName && !tonalityFlag && !frontTonality) {
394
+ console.error("Error: --template or --tonality (or tonality: in the frontmatter) is required when using --html, --pptx or --export-viz-context");
345
395
  process.exit(1);
346
396
  }
347
-
348
- const source = fs.readFileSync(inputPath, "utf-8");
349
397
  const sourceDir = path.dirname(path.resolve(inputPath));
350
398
 
351
399
  (async () => {
@@ -374,12 +422,12 @@ if (require.main === module) {
374
422
  }
375
423
 
376
424
  // Resolve and render if template + output formats specified
377
- if (templateName && (htmlPath || pptxPath || vizContextPath)) {
425
+ if (htmlPath || pptxPath || vizContextPath) {
378
426
  await resolveAndRender(ast, templateName, {
379
427
  html: htmlPath,
380
428
  pptx: pptxPath,
381
429
  vizContext: vizContextPath,
382
- }, { sourceDir, accent: effectiveAccent, font: effectiveFont, bg: effectiveBg });
430
+ }, { sourceDir, accent: effectiveAccent, font: effectiveFont, bg: effectiveBg, tonality: tonalityFlag, faces: facesFlag });
383
431
 
384
432
  // Optional: embed bundled fonts into the PPTX for a self-contained deck.
385
433
  if (embedFonts && pptxPath) {