@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.
- package/.grok/hooks/auto-handoff-gate.mjs +15 -2
- package/.grok/rules/00-litgrok.md +1 -1
- package/.grok/skills/frontend-ui-ux/THIRD-PARTY-NOTICE.txt +0 -5
- package/.grok/skills/frontend-ui-ux/references/slop-register.md +4 -4
- package/.grok/skills/frontend-ui-ux/scripts/import-design-intelligence.mjs +1 -1
- package/.grok/skills/lit-docx/SKILL.md +59 -11
- package/.grok/skills/lit-docx/examples/01-report-ko.md +137 -0
- package/.grok/skills/lit-docx/examples/02-brief-ko.md +82 -0
- package/.grok/skills/lit-docx/examples/03-manual-ko.md +118 -0
- package/.grok/skills/lit-docx/examples/04-proposal-ko.md +92 -0
- package/.grok/skills/lit-docx/examples/05-memo-en.md +42 -0
- package/.grok/skills/lit-docx/examples/06-journal-en.md +90 -0
- package/.grok/skills/lit-docx/examples/07-report-en.md +103 -0
- package/.grok/skills/lit-docx/examples/08-proposal-en.md +90 -0
- package/.grok/skills/lit-docx/examples/09-memo-ko.md +41 -0
- package/.grok/skills/lit-docx/references/components.md +151 -0
- package/.grok/skills/lit-docx/references/direction-step.md +129 -0
- package/.grok/skills/lit-docx/references/page-composition.md +129 -0
- package/.grok/skills/lit-docx/references/tonalities/brief.md +98 -0
- package/.grok/skills/lit-docx/references/tonalities/journal.md +100 -0
- package/.grok/skills/lit-docx/references/tonalities/manual.md +107 -0
- package/.grok/skills/lit-docx/references/tonalities/memo.md +95 -0
- package/.grok/skills/lit-docx/references/tonalities/proposal.md +105 -0
- package/.grok/skills/lit-docx/references/tonalities/report.md +114 -0
- package/.grok/skills/lit-docx/scripts/convert_md_to_docx.py +394 -51
- package/.grok/skills/lit-docx/scripts/docx_design.py +2446 -0
- package/.grok/skills/lit-docx/scripts/docx_gate.py +203 -0
- package/.grok/skills/lit-docx/scripts/docx_layout.py +959 -0
- package/.grok/skills/lit-docx/scripts/run.mjs +3 -2
- package/.grok/skills/lit-docx/scripts/slop_lint.py +63 -17
- package/.grok/skills/lit-docx/templates/tonalities/brief.yaml +29 -0
- package/.grok/skills/lit-docx/templates/tonalities/journal.yaml +26 -0
- package/.grok/skills/lit-docx/templates/tonalities/manual.yaml +27 -0
- package/.grok/skills/lit-docx/templates/tonalities/memo.yaml +27 -0
- package/.grok/skills/lit-docx/templates/tonalities/proposal.yaml +27 -0
- package/.grok/skills/lit-docx/templates/tonalities/report.yaml +27 -0
- package/.grok/skills/lit-pptx/NOTICE.md +1 -1
- package/.grok/skills/lit-pptx/SKILL.md +70 -14
- package/.grok/skills/lit-pptx/agents/analyst.md +1 -1
- package/.grok/skills/lit-pptx/agents/thesis.md +2 -2
- package/.grok/skills/lit-pptx/examples/01-pitch-signal-ko.md +175 -0
- package/.grok/skills/lit-pptx/examples/02-business-review-ledger-ko.md +199 -0
- package/.grok/skills/lit-pptx/examples/03-research-talk-paper-en.md +177 -0
- package/.grok/skills/lit-pptx/examples/04-lecture-chalk-ko.md +176 -0
- package/.grok/skills/lit-pptx/examples/05-data-review-night-en.md +221 -0
- package/.grok/skills/lit-pptx/examples/06-image-led-atlas-en.md +143 -0
- package/.grok/skills/lit-pptx/examples/07-briefing-gazette-ko.md +192 -0
- package/.grok/skills/lit-pptx/examples/08-status-update-ledger-en.md +168 -0
- package/.grok/skills/lit-pptx/examples/09-pitch-studio-en.md +157 -0
- package/.grok/skills/lit-pptx/examples/10-image-led-studio-ko.md +175 -0
- package/.grok/skills/lit-pptx/examples/11-business-review-night-en.md +181 -0
- package/.grok/skills/lit-pptx/examples/12-status-update-gazette-ko.md +199 -0
- package/.grok/skills/lit-pptx/pretendard-font/public/static/Pretendard-Bold.otf +0 -0
- package/.grok/skills/lit-pptx/pretendard-font/public/static/Pretendard-Regular.otf +0 -0
- package/.grok/skills/lit-pptx/references/density-and-fill.md +155 -0
- package/.grok/skills/lit-pptx/references/direction-step.md +211 -0
- package/.grok/skills/lit-pptx/references/layout-families.md +193 -0
- package/.grok/skills/lit-pptx/references/title-treatments.md +134 -0
- package/.grok/skills/lit-pptx/references/tonalities/atlas.md +124 -0
- package/.grok/skills/lit-pptx/references/tonalities/chalk.md +135 -0
- package/.grok/skills/lit-pptx/references/tonalities/gazette.md +127 -0
- package/.grok/skills/lit-pptx/references/tonalities/ledger.md +134 -0
- package/.grok/skills/lit-pptx/references/tonalities/night.md +132 -0
- package/.grok/skills/lit-pptx/references/tonalities/paper.md +127 -0
- package/.grok/skills/lit-pptx/references/tonalities/signal.md +118 -0
- package/.grok/skills/lit-pptx/references/tonalities/studio.md +123 -0
- package/.grok/skills/lit-pptx/scripts/compile-deck.js +65 -17
- package/.grok/skills/lit-pptx/scripts/craft_extras.py +82 -18
- package/.grok/skills/lit-pptx/scripts/deck_output.py +598 -0
- package/.grok/skills/lit-pptx/scripts/embed_fonts.py +1 -1
- package/.grok/skills/lit-pptx/scripts/inventory.py +6 -2
- package/.grok/skills/lit-pptx/scripts/lib/directive-parser.js +2 -2
- package/.grok/skills/lit-pptx/scripts/lib/grid-resolver.js +521 -0
- package/.grok/skills/lit-pptx/scripts/lib/layout-resolver.js +401 -16
- package/.grok/skills/lit-pptx/scripts/lib/markdown-loader.js +6 -4
- package/.grok/skills/lit-pptx/scripts/lib/render-adapter-html.js +2 -2
- package/.grok/skills/lit-pptx/scripts/lib/render-adapter-pptx.js +500 -126
- package/.grok/skills/lit-pptx/scripts/lib/render-pack.js +3558 -0
- package/.grok/skills/lit-pptx/scripts/lib/slide-ast.js +54 -6
- package/.grok/skills/lit-pptx/scripts/lib/template-registry.js +335 -11
- package/.grok/skills/lit-pptx/scripts/qa_deck.py +43 -10
- package/.grok/skills/lit-pptx/scripts/run.mjs +3 -2
- package/.grok/skills/lit-pptx/scripts/validate_pptx.py +17 -5
- package/.grok/skills/lit-pptx/templates/boilerplate_professional.css +6 -6
- package/.grok/skills/lit-pptx/templates/enrolled/AZURE-A2Z/layout-mapping.yaml +1 -1
- package/.grok/skills/lit-pptx/templates/enrolled/AZURE-A2Z/template.yaml +4 -1
- package/.grok/skills/lit-pptx/templates/enrolled/AZURE-PRO/layout-mapping.yaml +1 -1
- package/.grok/skills/lit-pptx/templates/enrolled/AZURE-PRO/template.yaml +4 -1
- package/.grok/skills/lit-pptx/templates/tonalities/atlas/pack.yaml +99 -0
- package/.grok/skills/lit-pptx/templates/tonalities/chalk/pack.yaml +104 -0
- package/.grok/skills/lit-pptx/templates/tonalities/gazette/pack.yaml +99 -0
- package/.grok/skills/lit-pptx/templates/tonalities/ledger/pack.yaml +100 -0
- package/.grok/skills/lit-pptx/templates/tonalities/night/pack.yaml +100 -0
- package/.grok/skills/lit-pptx/templates/tonalities/paper/pack.yaml +105 -0
- package/.grok/skills/lit-pptx/templates/tonalities/signal/pack.yaml +101 -0
- package/.grok/skills/lit-pptx/templates/tonalities/studio/pack.yaml +99 -0
- package/.grok/skills/lit-typographic-motion/THIRD_PARTY_NOTICES +1 -1
- package/.grok/skills/lit-typographic-motion/fonts/pins.json +6 -6
- package/.grok/skills/lit-typographic-motion/references/runtime.md +1 -1
- package/.grok/skills/lit-typographic-motion/references/style-bible.md +2 -2
- package/.grok/skills/lit-typographic-motion/references/type-craft.md +2 -2
- package/.grok/skills/lit-typographic-motion/scripts/lib/gate.mjs +1 -1
- package/.grok/skills/litgrok/SKILL.md +1 -1
- package/.grok-plugin/plugin.json +1 -1
- package/CHANGELOG.md +11 -0
- package/README.md +9 -9
- package/README_ko-KR.md +9 -9
- package/docs/assets/readme/badge-version.svg +1 -1
- package/docs/reference.md +1 -1
- package/docs/reference_ko-KR.md +1 -1
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/.grok/skills/lit-pptx/pretendard-font/public/static/PretendardGOV-Bold.otf +0 -0
- 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
|
+

|
|
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
|
+

|
|
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: ["
|
|
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
|
-
|
|
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 (
|
|
150
|
-
// of which template was chosen. Applied before accent (independent of colour).
|
|
151
|
-
if (options.font &&
|
|
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 (
|
|
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 &&
|
|
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 (
|
|
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" &&
|
|
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-
|
|
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
|
-
|
|
343
|
-
|
|
344
|
-
|
|
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 (
|
|
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) {
|