@open-press/cli 0.3.0 → 0.6.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.
- package/dist/cli.js +125 -51
- package/package.json +1 -1
- package/template/core/CHANGELOG.md +73 -0
- package/template/core/engine/cli.mjs +6 -0
- package/template/core/engine/commands/_shared.mjs +9 -2
- package/template/core/engine/commands/deploy.mjs +3 -3
- package/template/core/engine/commands/dev.mjs +25 -2
- package/template/core/engine/commands/doctor.mjs +229 -0
- package/template/core/engine/commands/pdf.mjs +3 -3
- package/template/core/engine/commands/preview.mjs +4 -4
- package/template/core/engine/commands/upgrade.mjs +117 -0
- package/template/core/package.json +3 -1
- package/template/core/vite.config.ts +26 -11
- package/template/packs/academic-paper/document/chapters/01-introduction/content/01-introduction.mdx +21 -0
- package/template/packs/academic-paper/document/chapters/02-methods/content/01-methods.mdx +30 -0
- package/template/packs/academic-paper/document/chapters/03-results-and-discussion/content/01-results.mdx +29 -0
- package/template/packs/academic-paper/document/chapters/04-acknowledgment/content/01-acknowledgment.mdx +12 -0
- package/template/packs/academic-paper/document/chapters/05-references/content/01-references.mdx +27 -0
- package/template/packs/academic-paper/document/index.tsx +107 -0
- package/template/packs/academic-paper/document/openpress.config.mjs +26 -0
- package/template/packs/academic-paper/document/theme/page-surfaces/cover.css +267 -0
- package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/chapters/03-agent-skills-contributors/content/01-agent-skills-contributors.mdx +2 -3
- package/template/packs/editorial-monograph/document/components/ChapterOpenerVisual/index.tsx +76 -0
- package/template/packs/editorial-monograph/document/components/Page.tsx +27 -0
- package/template/packs/editorial-monograph/document/components/TokenSwatchGrid/index.tsx +46 -0
- package/template/packs/editorial-monograph/document/components/TokenSwatchGrid/style.css +63 -0
- package/template/packs/editorial-monograph/document/components/TypeSpecimen/index.tsx +38 -0
- package/template/packs/editorial-monograph/document/components/TypeSpecimen/style.css +111 -0
- package/template/packs/editorial-monograph/document/design.md +279 -0
- package/template/packs/editorial-monograph/document/media/README.md +13 -0
- package/template/packs/editorial-monograph/document/theme/README.md +11 -0
- package/template/packs/editorial-monograph/document/theme/base/page-contract.css +505 -0
- package/template/packs/editorial-monograph/document/theme/base/print.css +93 -0
- package/template/packs/editorial-monograph/document/theme/base/typography.css +336 -0
- package/template/packs/editorial-monograph/document/theme/fonts.css +3 -0
- package/template/packs/editorial-monograph/document/theme/page-surfaces/back-cover.css +43 -0
- package/template/packs/editorial-monograph/document/theme/page-surfaces/chapter-opener.css +205 -0
- package/template/packs/editorial-monograph/document/theme/page-surfaces/toc.css +139 -0
- package/template/packs/editorial-monograph/document/theme/patterns/_chart-frame.css +49 -0
- package/template/packs/editorial-monograph/document/theme/patterns/figure-grid.css +68 -0
- package/template/packs/editorial-monograph/document/theme/patterns/table-utilities.css +66 -0
- package/template/packs/editorial-monograph/document/theme/shell/reader-controls.css +761 -0
- package/template/packs/editorial-monograph/document/theme/tokens.css +80 -0
- package/template/packs/editorial-monograph/openpress.config.mjs +5 -0
- package/template/core/.turbo/turbo-test.log +0 -341
- package/template/skills/chinese-ai-writing-polish/SKILL.md +0 -195
- package/template/skills/claude-document/SKILL.md +0 -66
- package/template/skills/editorial-monograph/SKILL.md +0 -73
- package/template/skills/openpress/SKILL.md +0 -114
- package/template/skills/openpress/references/cli-commands.md +0 -31
- package/template/skills/openpress/references/local-review.md +0 -43
- package/template/skills/openpress-deploy/SKILL.md +0 -69
- package/template/skills/openpress-deploy/references/cloudflare-pages.md +0 -51
- package/template/skills/openpress-design/SKILL.md +0 -51
- package/template/skills/openpress-design/references/pdf-safe-css.md +0 -29
- package/template/skills/openpress-design/references/responsive-fixed-layout.md +0 -48
- package/template/skills/openpress-design/references/theme-and-components.md +0 -77
- package/template/skills/openpress-diagram-drawing/SKILL.md +0 -44
- package/template/skills/openpress-diagram-drawing/references/diagram-patterns.md +0 -93
- package/template/skills/openpress-document-hierarchy/SKILL.md +0 -81
- package/template/skills/openpress-document-hierarchy/agents/openai.yaml +0 -4
- package/template/skills/openpress-document-hierarchy/references/data-structures-outline.md +0 -115
- package/template/skills/openpress-init/SKILL.md +0 -84
- package/template/skills/openpress-style-pack-contributor/SKILL.md +0 -62
- package/template/skills/openpress-style-pack-contributor/references/starter-contract.md +0 -49
- package/template/skills/openpress-update/SKILL.md +0 -88
- package/template/skills/openpress-writing/SKILL.md +0 -68
- package/template/skills/openpress-writing/references/source-and-writing-rules.md +0 -120
- package/template/skills/teaching-notes-writing/SKILL.md +0 -54
- package/template/skills/teaching-notes-writing/references/programming.md +0 -65
- package/template/skills/teaching-notes-writing/references/teaching-patterns.md +0 -60
- /package/template/{skills/editorial-monograph/starter → packs/academic-paper}/document/components/ChapterOpenerVisual/index.tsx +0 -0
- /package/template/{skills/claude-document/starter → packs/academic-paper}/document/components/Page.tsx +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/academic-paper}/document/components/TokenSwatchGrid/index.tsx +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/academic-paper}/document/components/TokenSwatchGrid/style.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/academic-paper}/document/components/TypeSpecimen/index.tsx +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/academic-paper}/document/components/TypeSpecimen/style.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/academic-paper}/document/design.md +0 -0
- /package/template/{skills/claude-document/starter → packs/academic-paper}/document/media/README.md +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/academic-paper}/document/theme/README.md +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/academic-paper}/document/theme/base/page-contract.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/academic-paper}/document/theme/base/print.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/academic-paper}/document/theme/base/typography.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/academic-paper}/document/theme/fonts.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/academic-paper}/document/theme/page-surfaces/back-cover.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/academic-paper}/document/theme/page-surfaces/chapter-opener.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/academic-paper}/document/theme/page-surfaces/toc.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/academic-paper}/document/theme/patterns/_chart-frame.css +0 -0
- /package/template/{skills/claude-document/starter → packs/academic-paper}/document/theme/patterns/figure-grid.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/academic-paper}/document/theme/patterns/table-utilities.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/academic-paper}/document/theme/shell/reader-controls.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/academic-paper}/document/theme/tokens.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/academic-paper}/openpress.config.mjs +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/chapters/01-document-shape/chapter.tsx +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/chapters/01-document-shape/content/01-document-shape.mdx +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/chapters/02-review-loop/chapter.tsx +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/chapters/02-review-loop/content/01-review-loop.mdx +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/components/ChapterOpenerVisual.tsx +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/claude-document}/document/components/Page.tsx +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/design.md +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/index.tsx +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/claude-document}/document/media/README.md +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/openpress.config.mjs +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/README.md +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/base/page-contract.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/base/print.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/base/typography.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/fonts.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/page-surfaces/back-cover.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/page-surfaces/chapter-opener.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/page-surfaces/cover.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/page-surfaces/toc.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/patterns/_chart-frame.css +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/claude-document}/document/theme/patterns/figure-grid.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/patterns/table-utilities.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/shell/reader-controls.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/document/theme/tokens.css +0 -0
- /package/template/{skills/claude-document/starter → packs/claude-document}/openpress.config.mjs +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/chapters/01-product-and-use-cases/content/01-product-and-use-cases.mdx +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/chapters/02-workflow/content/01-workflow.mdx +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/chapters/04-validation-deploy/content/01-validation-deploy.mdx +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/index.tsx +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/openpress.config.mjs +0 -0
- /package/template/{skills/editorial-monograph/starter → packs/editorial-monograph}/document/theme/page-surfaces/cover.css +0 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { Manifest } from "@openpress/core";
|
|
2
|
+
import { BaseBackCoverPage, BaseCoverPage, BaseTocPage } from "@openpress/core";
|
|
3
|
+
|
|
4
|
+
export const config: Manifest = {
|
|
5
|
+
title: "Paper Title",
|
|
6
|
+
subtitle: "An academic-paper draft built with open-press",
|
|
7
|
+
organization: "Department · Institution",
|
|
8
|
+
sourceDir: "chapters",
|
|
9
|
+
mediaDir: "media",
|
|
10
|
+
themeDir: "theme",
|
|
11
|
+
designDoc: "design.md",
|
|
12
|
+
componentsDir: "components",
|
|
13
|
+
publicDir: "public/openpress",
|
|
14
|
+
outputDir: "dist-react",
|
|
15
|
+
pdf: {
|
|
16
|
+
filename: "paper.pdf",
|
|
17
|
+
},
|
|
18
|
+
deploy: {
|
|
19
|
+
adapter: "cloudflare-pages",
|
|
20
|
+
source: ".deploy/document",
|
|
21
|
+
projectName: null,
|
|
22
|
+
commitDirty: false,
|
|
23
|
+
requiresConfirmation: true,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The cover renders the academic title block: paper title, author grid,
|
|
29
|
+
* abstract band, and index terms. Replace the placeholders with your own.
|
|
30
|
+
*/
|
|
31
|
+
export const cover = (
|
|
32
|
+
<BaseCoverPage data-page-title="Title page" aria-labelledby="paper-title">
|
|
33
|
+
<div className="paper-cover">
|
|
34
|
+
<h1 id="paper-title" className="paper-title">
|
|
35
|
+
Conference Paper Title
|
|
36
|
+
</h1>
|
|
37
|
+
<p className="paper-subtitle">
|
|
38
|
+
Sub-title (optional). Not captured by indexing services like IEEE Xplore.
|
|
39
|
+
</p>
|
|
40
|
+
|
|
41
|
+
<ol className="paper-authors" aria-label="Authors">
|
|
42
|
+
<li className="paper-author">
|
|
43
|
+
<p className="paper-author-name">First Author Surname</p>
|
|
44
|
+
<p className="paper-author-affiliation">dept. of organization</p>
|
|
45
|
+
<p className="paper-author-affiliation">name of organization</p>
|
|
46
|
+
<p className="paper-author-location">City, Country</p>
|
|
47
|
+
<p className="paper-author-contact">email or ORCID</p>
|
|
48
|
+
</li>
|
|
49
|
+
<li className="paper-author">
|
|
50
|
+
<p className="paper-author-name">Second Author Surname</p>
|
|
51
|
+
<p className="paper-author-affiliation">dept. of organization</p>
|
|
52
|
+
<p className="paper-author-affiliation">name of organization</p>
|
|
53
|
+
<p className="paper-author-location">City, Country</p>
|
|
54
|
+
<p className="paper-author-contact">email or ORCID</p>
|
|
55
|
+
</li>
|
|
56
|
+
<li className="paper-author">
|
|
57
|
+
<p className="paper-author-name">Third Author Surname</p>
|
|
58
|
+
<p className="paper-author-affiliation">dept. of organization</p>
|
|
59
|
+
<p className="paper-author-affiliation">name of organization</p>
|
|
60
|
+
<p className="paper-author-location">City, Country</p>
|
|
61
|
+
<p className="paper-author-contact">email or ORCID</p>
|
|
62
|
+
</li>
|
|
63
|
+
</ol>
|
|
64
|
+
|
|
65
|
+
<section className="paper-abstract" aria-label="Abstract">
|
|
66
|
+
<p>
|
|
67
|
+
<span className="paper-abstract-label">Abstract</span>—This document
|
|
68
|
+
is a model and starting point for an academic paper drafted in
|
|
69
|
+
open-press. Replace this abstract with your own — keep it under
|
|
70
|
+
250 words. Do not use abbreviations, symbols, footnotes, or math
|
|
71
|
+
in the abstract.
|
|
72
|
+
</p>
|
|
73
|
+
</section>
|
|
74
|
+
|
|
75
|
+
<section className="paper-index-terms" aria-label="Index terms">
|
|
76
|
+
<p>
|
|
77
|
+
<span className="paper-abstract-label">Index Terms</span>—keyword
|
|
78
|
+
one, keyword two, keyword three, keyword four
|
|
79
|
+
</p>
|
|
80
|
+
</section>
|
|
81
|
+
</div>
|
|
82
|
+
</BaseCoverPage>
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
export const toc = (
|
|
86
|
+
<BaseTocPage data-page-title="Contents" id="toc">
|
|
87
|
+
<div className="page-frame">
|
|
88
|
+
<header className="page-header" aria-hidden="true"></header>
|
|
89
|
+
<main className="page-body">
|
|
90
|
+
<h2 id="toc-title" className="toc-heading">Contents</h2>
|
|
91
|
+
</main>
|
|
92
|
+
</div>
|
|
93
|
+
</BaseTocPage>
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
export const backCover = (
|
|
97
|
+
<BaseBackCoverPage data-page-title="Back cover">
|
|
98
|
+
<div className="paper-back-cover">
|
|
99
|
+
<p className="paper-back-kicker">open-press · academic-paper</p>
|
|
100
|
+
<p className="paper-back-statement">
|
|
101
|
+
Draft built with open-press. When the paper is ready for submission,
|
|
102
|
+
port the prose into the publisher's LaTeX class (IEEEtran, acmart,
|
|
103
|
+
etc.). open-press is the iteration loop, not the camera-ready output.
|
|
104
|
+
</p>
|
|
105
|
+
</div>
|
|
106
|
+
</BaseBackCoverPage>
|
|
107
|
+
);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// academic-paper starter — replace with your paper's metadata.
|
|
2
|
+
export default {
|
|
3
|
+
title: "Paper Title",
|
|
4
|
+
subtitle: "An academic-paper draft built with open-press",
|
|
5
|
+
organization: "Department · Institution",
|
|
6
|
+
|
|
7
|
+
sourceDir: "chapters",
|
|
8
|
+
mediaDir: "media",
|
|
9
|
+
themeDir: "theme",
|
|
10
|
+
designDoc: "design.md",
|
|
11
|
+
componentsDir: "components",
|
|
12
|
+
publicDir: "public/openpress",
|
|
13
|
+
outputDir: "dist-react",
|
|
14
|
+
|
|
15
|
+
pdf: {
|
|
16
|
+
filename: "paper.pdf",
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
deploy: {
|
|
20
|
+
adapter: "cloudflare-pages",
|
|
21
|
+
source: ".deploy/document",
|
|
22
|
+
projectName: null,
|
|
23
|
+
commitDirty: false,
|
|
24
|
+
requiresConfirmation: true,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/* page-surfaces / cover
|
|
2
|
+
* Cover and back-cover share most of their layout chrome (meta header, byline
|
|
3
|
+
* footer, central main column). Shared selectors live here so cover is the
|
|
4
|
+
* primary reference; back-cover.css only refines the parts that differ.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
.reader-page--cover,
|
|
8
|
+
.reader-page--back-cover {
|
|
9
|
+
background: var(--openpress-color-document);
|
|
10
|
+
padding: clamp(28px, 5cqw, 48px) clamp(24px, 4.5cqw, 42px);
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
justify-content: space-between;
|
|
13
|
+
gap: clamp(16px, 2.5cqw, 24px);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.reader-app.is-ready .reader-page--cover,
|
|
17
|
+
.reader-app.is-ready .reader-page--back-cover,
|
|
18
|
+
.reader-page--cover.is-active,
|
|
19
|
+
.reader-page--back-cover.is-active {
|
|
20
|
+
display: flex;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.cover-meta,
|
|
24
|
+
.back-cover-meta {
|
|
25
|
+
display: flex;
|
|
26
|
+
justify-content: space-between;
|
|
27
|
+
align-items: flex-start;
|
|
28
|
+
gap: var(--openpress-space-3);
|
|
29
|
+
padding-bottom: var(--openpress-space-2);
|
|
30
|
+
border-bottom: 1px solid var(--openpress-color-ink);
|
|
31
|
+
font-family: var(--openpress-font-body);
|
|
32
|
+
font-size: clamp(8pt, 1.25cqw, 9.5pt);
|
|
33
|
+
color: var(--openpress-color-muted);
|
|
34
|
+
letter-spacing: 0.12em;
|
|
35
|
+
flex-shrink: 0;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.mihua-logo,
|
|
39
|
+
.openpress-logo {
|
|
40
|
+
display: block;
|
|
41
|
+
width: clamp(112px, 18cqw, 154px);
|
|
42
|
+
height: auto;
|
|
43
|
+
flex-shrink: 0;
|
|
44
|
+
object-fit: contain;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.cover-meta-title {
|
|
48
|
+
margin-left: auto;
|
|
49
|
+
max-width: 48%;
|
|
50
|
+
padding-top: 0.35em;
|
|
51
|
+
text-align: right;
|
|
52
|
+
white-space: nowrap;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.cover-main,
|
|
56
|
+
.back-cover-main {
|
|
57
|
+
display: flex;
|
|
58
|
+
flex-direction: column;
|
|
59
|
+
flex: 1;
|
|
60
|
+
min-height: 0;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.cover-title {
|
|
64
|
+
margin: 0;
|
|
65
|
+
font-family: var(--openpress-font-serif);
|
|
66
|
+
font-size: clamp(36px, 8.5cqw, 64px);
|
|
67
|
+
font-weight: 300;
|
|
68
|
+
line-height: 1;
|
|
69
|
+
letter-spacing: 0.01em;
|
|
70
|
+
color: var(--openpress-color-ink);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.cover-tagline {
|
|
74
|
+
margin: var(--openpress-space-2) 0 0;
|
|
75
|
+
font-family: var(--openpress-font-serif);
|
|
76
|
+
font-size: clamp(14px, 2.4cqw, 20px);
|
|
77
|
+
font-weight: 300;
|
|
78
|
+
letter-spacing: 0.08em;
|
|
79
|
+
color: var(--openpress-color-muted);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.cover-rule,
|
|
83
|
+
.back-cover-rule {
|
|
84
|
+
height: 1px;
|
|
85
|
+
width: 40px;
|
|
86
|
+
background: var(--openpress-color-ink);
|
|
87
|
+
margin: var(--openpress-space-3) 0;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.cover-subtitle {
|
|
91
|
+
margin: 0;
|
|
92
|
+
font-family: var(--openpress-font-body);
|
|
93
|
+
font-size: clamp(10.5pt, 1.85cqw, 12.5pt);
|
|
94
|
+
font-weight: 400;
|
|
95
|
+
letter-spacing: 0.02em;
|
|
96
|
+
line-height: 1.55;
|
|
97
|
+
color: var(--openpress-color-ink);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.cover-summary {
|
|
101
|
+
margin: var(--openpress-space-2) 0 0;
|
|
102
|
+
font-family: var(--openpress-font-body);
|
|
103
|
+
font-size: clamp(9pt, 1.65cqw, 10pt);
|
|
104
|
+
line-height: 1.8;
|
|
105
|
+
color: var(--openpress-color-muted);
|
|
106
|
+
max-width: 90%;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.cover-visual,
|
|
110
|
+
.back-cover-visual {
|
|
111
|
+
margin: var(--openpress-space-3) 0 0;
|
|
112
|
+
flex-shrink: 0;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.cover-visual img,
|
|
116
|
+
.back-cover-visual img {
|
|
117
|
+
display: block;
|
|
118
|
+
width: 100%;
|
|
119
|
+
height: auto;
|
|
120
|
+
max-height: 22cqh;
|
|
121
|
+
object-fit: cover;
|
|
122
|
+
border: 0;
|
|
123
|
+
padding: 0;
|
|
124
|
+
background: transparent;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.cover-byline,
|
|
128
|
+
.back-cover-byline {
|
|
129
|
+
display: flex;
|
|
130
|
+
justify-content: space-between;
|
|
131
|
+
align-items: baseline;
|
|
132
|
+
padding-top: var(--openpress-space-2);
|
|
133
|
+
border-top: 1px solid var(--openpress-color-ink);
|
|
134
|
+
font-family: var(--openpress-font-body);
|
|
135
|
+
font-size: clamp(8pt, 1.25cqw, 9.5pt);
|
|
136
|
+
color: var(--openpress-color-muted);
|
|
137
|
+
letter-spacing: 0.12em;
|
|
138
|
+
flex-shrink: 0;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.cover-byline span:first-child,
|
|
142
|
+
.back-cover-byline span:first-child {
|
|
143
|
+
font-family: var(--openpress-font-serif);
|
|
144
|
+
font-weight: 400;
|
|
145
|
+
letter-spacing: 0.04em;
|
|
146
|
+
color: var(--openpress-color-ink);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/* ─ academic-paper title block ──────────────────────────────────────────── */
|
|
150
|
+
/* IEEE-style title page: large serif title, optional subtitle, 3-column */
|
|
151
|
+
/* author grid, abstract band, index terms band. Single-column body picks */
|
|
152
|
+
/* up after this surface. Two-column body arrives with the v0.8 paged.js */
|
|
153
|
+
/* migration. */
|
|
154
|
+
|
|
155
|
+
.paper-cover {
|
|
156
|
+
display: flex;
|
|
157
|
+
flex-direction: column;
|
|
158
|
+
gap: clamp(18px, 2.4cqw, 32px);
|
|
159
|
+
padding-block: clamp(24px, 3cqw, 40px) 0;
|
|
160
|
+
font-family: var(--openpress-font-serif);
|
|
161
|
+
color: var(--openpress-color-ink);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.paper-title {
|
|
165
|
+
font-family: var(--openpress-font-serif);
|
|
166
|
+
font-size: clamp(28px, 4.4cqw, 36px);
|
|
167
|
+
line-height: 1.2;
|
|
168
|
+
font-weight: 400;
|
|
169
|
+
text-align: center;
|
|
170
|
+
margin: 0;
|
|
171
|
+
letter-spacing: 0;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.paper-subtitle {
|
|
175
|
+
font-size: clamp(11px, 1.4cqw, 12px);
|
|
176
|
+
font-style: italic;
|
|
177
|
+
text-align: center;
|
|
178
|
+
color: var(--openpress-color-muted);
|
|
179
|
+
margin: 0;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.paper-authors {
|
|
183
|
+
list-style: none;
|
|
184
|
+
padding: 0;
|
|
185
|
+
margin: clamp(8px, 1.6cqw, 16px) 0 0;
|
|
186
|
+
display: grid;
|
|
187
|
+
grid-template-columns: repeat(3, 1fr);
|
|
188
|
+
gap: clamp(10px, 1.4cqw, 16px) clamp(8px, 1.2cqw, 14px);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.paper-author {
|
|
192
|
+
display: flex;
|
|
193
|
+
flex-direction: column;
|
|
194
|
+
align-items: center;
|
|
195
|
+
text-align: center;
|
|
196
|
+
font-size: clamp(10.5px, 1.3cqw, 11.5px);
|
|
197
|
+
line-height: 1.35;
|
|
198
|
+
gap: 0;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.paper-author-name {
|
|
202
|
+
font-weight: 500;
|
|
203
|
+
margin: 0 0 0.25em 0;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.paper-author-affiliation {
|
|
207
|
+
font-style: italic;
|
|
208
|
+
margin: 0;
|
|
209
|
+
color: var(--openpress-color-ink);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.paper-author-location,
|
|
213
|
+
.paper-author-contact {
|
|
214
|
+
margin: 0;
|
|
215
|
+
color: var(--openpress-color-ink);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.paper-abstract,
|
|
219
|
+
.paper-index-terms {
|
|
220
|
+
margin-top: clamp(8px, 1.6cqw, 14px);
|
|
221
|
+
font-size: clamp(10.5px, 1.3cqw, 11.5px);
|
|
222
|
+
line-height: 1.45;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.paper-abstract p,
|
|
226
|
+
.paper-index-terms p {
|
|
227
|
+
margin: 0;
|
|
228
|
+
text-indent: 1.2em;
|
|
229
|
+
font-style: italic;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.paper-abstract-label {
|
|
233
|
+
font-style: normal;
|
|
234
|
+
font-weight: 700;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/* Single-column flush body (v0.6). The v0.8 paged.js migration replaces */
|
|
238
|
+
/* this declaration with `column-count: 2; column-gap: 1rem;` and adds */
|
|
239
|
+
/* `column-span: all` for the title block + abstract above. */
|
|
240
|
+
.reader-page--content .page-body {
|
|
241
|
+
max-width: none;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/* ─ academic-paper back cover ───────────────────────────────────────────── */
|
|
245
|
+
|
|
246
|
+
.paper-back-cover {
|
|
247
|
+
display: flex;
|
|
248
|
+
flex-direction: column;
|
|
249
|
+
gap: clamp(10px, 1.6cqw, 16px);
|
|
250
|
+
font-family: var(--openpress-font-serif);
|
|
251
|
+
padding-inline: clamp(24px, 4cqw, 56px);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.paper-back-kicker {
|
|
255
|
+
font-family: var(--openpress-font-mono, monospace);
|
|
256
|
+
font-size: 11px;
|
|
257
|
+
letter-spacing: 0.08em;
|
|
258
|
+
text-transform: uppercase;
|
|
259
|
+
color: var(--openpress-color-muted);
|
|
260
|
+
margin: 0;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.paper-back-statement {
|
|
264
|
+
font-size: clamp(13px, 1.6cqw, 15px);
|
|
265
|
+
line-height: 1.5;
|
|
266
|
+
margin: 0;
|
|
267
|
+
}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
| 從既有資料建立文件 | 請參考這一份文件(自行上傳),使用 `openpress-writing skill` 協助整理成 8 頁產品提案。保留既有事實,不要新增未確認的數字。 |
|
|
11
11
|
| 以風格起手建立新文件 | 請以 `editorial-monograph skill` 作為風格,使用 `openpress-writing skill` 建立一份研究報告。讀者是管理層,缺少的事實請標成 placeholder。 |
|
|
12
12
|
| 開啟本機審稿 | 請使用 `openpress skill` 打開本機 workbench,讓我檢查 Document、Design System 與 Project 狀態。 |
|
|
13
|
-
| 規劃長篇文件層級 | 請使用 `openpress-
|
|
13
|
+
| 規劃長篇文件層級 | 請使用 `openpress-writing skill` 規劃 H2/H3/H4、目錄深度與附錄位置(已併入 writing skill 的 Hierarchy section)。 |
|
|
14
14
|
| 重寫章節 | 請使用 `openpress-writing skill` 重整章節,讓第一章先講問題、第二章講方案,語氣維持正式研究報告。 |
|
|
15
15
|
| 調整版面 | 請使用 `openpress-design skill` 調整 theme 與 components,讓文件維持 A4 長文閱讀節奏。 |
|
|
16
16
|
| 中文潤飾 | 請使用 `chinese-ai-writing-polish skill` 潤飾中文,保留原意,不要改成廣告文案。 |
|
|
@@ -26,8 +26,7 @@ open-press 使用 skill 讓 Agent 在不同層次工作。`openpress` 是 Core /
|
|
|
26
26
|
| --- | --- | --- |
|
|
27
27
|
| `openpress` | CLI、workspace inspect/search/replace、本機 workbench、驗證與輸出邊界 | Agent 不確定該用哪個 open-press 工具、要開本機審稿、或要選 specialist skill |
|
|
28
28
|
| `openpress-deploy` | 部署設定、preflight、dry run、公開發布確認 | 準備上線或接前端部署按鈕 |
|
|
29
|
-
| `openpress-
|
|
30
|
-
| `openpress-writing` | 章節順序、敘事結構、表格與 caption 文案 | 建立、重寫或重整內容 |
|
|
29
|
+
| `openpress-writing` | 章節順序、敘事結構、表格與 caption 文案、**H1/H2/H3/H4 結構、TOC 深度、附錄位置** | 建立、重寫或重整內容;長文骨架調整 |
|
|
31
30
|
| `openpress-design` | theme、版面、page rhythm、components | 調整視覺系統與輸出穩定性 |
|
|
32
31
|
| `openpress-style-pack-contributor` | style pack 設計、starter 契約、貢獻驗證 | 新增或改良 `skills/<pack>/starter/` |
|
|
33
32
|
| `editorial-monograph` | A4 嚴肅長文風格 | 報告、提案、白皮書、產品說明 |
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
const TONES = new Set(["sage", "lavender", "mint", "amber"]);
|
|
2
|
+
|
|
3
|
+
const VISUALS = {
|
|
4
|
+
"linked-list": `<svg viewBox="0 0 520 330" focusable="false" aria-hidden="true">
|
|
5
|
+
<rect class="chapter-opener-illustration__paper" x="42" y="96" width="116" height="82" rx="4" />
|
|
6
|
+
<rect class="chapter-opener-illustration__paper" x="204" y="96" width="116" height="82" rx="4" />
|
|
7
|
+
<rect class="chapter-opener-illustration__paper" x="366" y="96" width="116" height="82" rx="4" />
|
|
8
|
+
<path class="chapter-opener-illustration__stroke" d="M158 137 H204" />
|
|
9
|
+
<path class="chapter-opener-illustration__stroke" d="M320 137 H366" />
|
|
10
|
+
<path class="chapter-opener-illustration__arrow" d="M190 122 206 137 190 152" />
|
|
11
|
+
<path class="chapter-opener-illustration__arrow" d="M352 122 368 137 352 152" />
|
|
12
|
+
<path class="chapter-opener-illustration__thin" d="M72 128 H118 M72 150 H128 M234 128 H280 M234 150 H286 M396 128 H442 M396 150 H452" />
|
|
13
|
+
<circle class="chapter-opener-illustration__node" cx="144" cy="137" r="13" />
|
|
14
|
+
<circle class="chapter-opener-illustration__node" cx="306" cy="137" r="13" />
|
|
15
|
+
<circle class="chapter-opener-illustration__node" cx="468" cy="137" r="13" />
|
|
16
|
+
<path class="chapter-opener-illustration__stroke" d="M262 178 C262 222 220 244 158 244 C98 244 68 222 68 190" />
|
|
17
|
+
<path class="chapter-opener-illustration__arrow" d="M52 204 68 188 84 204" />
|
|
18
|
+
</svg>`,
|
|
19
|
+
tree: `<svg viewBox="0 0 520 330" focusable="false" aria-hidden="true">
|
|
20
|
+
<path class="chapter-opener-illustration__paper" d="M232 40 316 40 352 86 330 132 218 132 194 86Z" />
|
|
21
|
+
<path class="chapter-opener-illustration__paper" d="M88 198 170 178 228 218 204 288 100 288 58 240Z" />
|
|
22
|
+
<path class="chapter-opener-illustration__paper" d="M314 198 400 176 466 224 450 292 328 292 282 238Z" />
|
|
23
|
+
<path class="chapter-opener-illustration__stroke" d="M262 118 160 214 M270 118 374 214" />
|
|
24
|
+
<path class="chapter-opener-illustration__stroke" d="M160 214 122 258 M160 214 204 258 M374 214 330 258 M374 214 420 258" />
|
|
25
|
+
<circle class="chapter-opener-illustration__node" cx="266" cy="100" r="24" />
|
|
26
|
+
<circle class="chapter-opener-illustration__node" cx="160" cy="214" r="22" />
|
|
27
|
+
<circle class="chapter-opener-illustration__node" cx="374" cy="214" r="22" />
|
|
28
|
+
<circle class="chapter-opener-illustration__dot" cx="122" cy="258" r="13" />
|
|
29
|
+
<circle class="chapter-opener-illustration__dot" cx="204" cy="258" r="13" />
|
|
30
|
+
<circle class="chapter-opener-illustration__dot" cx="330" cy="258" r="13" />
|
|
31
|
+
<circle class="chapter-opener-illustration__dot" cx="420" cy="258" r="13" />
|
|
32
|
+
</svg>`,
|
|
33
|
+
code: `<svg viewBox="0 0 520 330" focusable="false" aria-hidden="true">
|
|
34
|
+
<path class="chapter-opener-illustration__paper" d="M92 52 338 52 386 104 386 286 92 286Z" />
|
|
35
|
+
<path class="chapter-opener-illustration__paper" d="M348 82 438 82 476 122 452 226 356 226 326 154Z" />
|
|
36
|
+
<path class="chapter-opener-illustration__thin" d="M132 112 H250 M132 146 H292 M132 180 H238 M132 214 H276" />
|
|
37
|
+
<path class="chapter-opener-illustration__stroke" d="M308 114 C340 122 356 148 356 180 C356 220 332 244 292 250" />
|
|
38
|
+
<path class="chapter-opener-illustration__arrow" d="M304 226 288 250 316 260" />
|
|
39
|
+
<path class="chapter-opener-illustration__stroke" d="M406 124 V202" />
|
|
40
|
+
<circle class="chapter-opener-illustration__node" cx="406" cy="124" r="17" />
|
|
41
|
+
<circle class="chapter-opener-illustration__node" cx="406" cy="202" r="17" />
|
|
42
|
+
</svg>`,
|
|
43
|
+
answers: `<svg viewBox="0 0 520 330" focusable="false" aria-hidden="true">
|
|
44
|
+
<path class="chapter-opener-illustration__paper" d="M128 44 396 44 440 90 418 292 104 292 82 86Z" />
|
|
45
|
+
<path class="chapter-opener-illustration__thin" d="M178 116 H350 M178 168 H350 M178 220 H322" />
|
|
46
|
+
<path class="chapter-opener-illustration__stroke" d="M128 112 148 134 190 88" />
|
|
47
|
+
<path class="chapter-opener-illustration__stroke" d="M128 164 148 186 190 140" />
|
|
48
|
+
<path class="chapter-opener-illustration__stroke" d="M128 216 148 238 190 192" />
|
|
49
|
+
<circle class="chapter-opener-illustration__node" cx="386" cy="92" r="18" />
|
|
50
|
+
<path class="chapter-opener-illustration__stroke" d="M386 92 C420 126 424 172 394 208" />
|
|
51
|
+
<path class="chapter-opener-illustration__arrow" d="M380 186 394 210 420 200" />
|
|
52
|
+
</svg>`,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export type ChapterOpenerVisualVariant = keyof typeof VISUALS;
|
|
56
|
+
|
|
57
|
+
export interface ChapterOpenerVisualProps {
|
|
58
|
+
variant?: ChapterOpenerVisualVariant;
|
|
59
|
+
tone?: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export default function ChapterOpenerVisual({
|
|
63
|
+
variant = "linked-list",
|
|
64
|
+
tone = "sage",
|
|
65
|
+
}: ChapterOpenerVisualProps) {
|
|
66
|
+
const visual = VISUALS[variant] ?? VISUALS["linked-list"];
|
|
67
|
+
const safeTone = TONES.has(tone) ? tone : "sage";
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<figure
|
|
71
|
+
className={`chapter-opener-illustration chapter-opener-illustration--${variant} chapter-opener-tone--${safeTone}`}
|
|
72
|
+
aria-hidden="true"
|
|
73
|
+
dangerouslySetInnerHTML={{ __html: visual }}
|
|
74
|
+
/>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { PageProps } from "@openpress/core";
|
|
2
|
+
|
|
3
|
+
export default function Page({
|
|
4
|
+
pageIndex,
|
|
5
|
+
totalPages,
|
|
6
|
+
chapterSlug,
|
|
7
|
+
chapterTone,
|
|
8
|
+
children,
|
|
9
|
+
}: PageProps) {
|
|
10
|
+
return (
|
|
11
|
+
<section
|
|
12
|
+
className="reader-page reader-page--content"
|
|
13
|
+
data-page-kind="content"
|
|
14
|
+
data-page-footer="true"
|
|
15
|
+
data-page-index={pageIndex}
|
|
16
|
+
data-total-pages={totalPages}
|
|
17
|
+
data-chapter-slug={chapterSlug}
|
|
18
|
+
data-chapter-tone={chapterTone}
|
|
19
|
+
>
|
|
20
|
+
<div className="page-frame">
|
|
21
|
+
<header className="page-header" aria-hidden="true" />
|
|
22
|
+
<main className="page-body">{children}</main>
|
|
23
|
+
<footer className="page-footer" aria-hidden="true" />
|
|
24
|
+
</div>
|
|
25
|
+
</section>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { CSSProperties } from "react";
|
|
2
|
+
|
|
3
|
+
export interface TokenSwatch {
|
|
4
|
+
name: string;
|
|
5
|
+
hex: string;
|
|
6
|
+
summary: string;
|
|
7
|
+
swatchVar: string;
|
|
8
|
+
swatchBorderVar?: string;
|
|
9
|
+
dark?: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface TokenSwatchGridProps {
|
|
13
|
+
ariaLabel?: string;
|
|
14
|
+
swatches: TokenSwatch[];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default function TokenSwatchGrid({
|
|
18
|
+
ariaLabel = "Color specimen",
|
|
19
|
+
swatches,
|
|
20
|
+
}: TokenSwatchGridProps) {
|
|
21
|
+
return (
|
|
22
|
+
<section className="token-swatch-grid" data-openpress-component="TokenSwatchGrid" aria-label={ariaLabel}>
|
|
23
|
+
{swatches.map((swatch) => (
|
|
24
|
+
<article
|
|
25
|
+
key={swatch.name}
|
|
26
|
+
className={swatch.dark ? "token-swatch token-swatch--dark" : "token-swatch"}
|
|
27
|
+
style={swatchStyle(swatch)}
|
|
28
|
+
>
|
|
29
|
+
<div className="token-swatch__sample" />
|
|
30
|
+
<div className="token-swatch__body">
|
|
31
|
+
<h4>{swatch.name}</h4>
|
|
32
|
+
<code>{swatch.hex}</code>
|
|
33
|
+
<p>{swatch.summary}</p>
|
|
34
|
+
</div>
|
|
35
|
+
</article>
|
|
36
|
+
))}
|
|
37
|
+
</section>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function swatchStyle(swatch: TokenSwatch): CSSProperties {
|
|
42
|
+
return {
|
|
43
|
+
"--swatch": swatch.swatchVar,
|
|
44
|
+
...(swatch.swatchBorderVar ? { "--swatch-border": swatch.swatchBorderVar } : {}),
|
|
45
|
+
} as CSSProperties;
|
|
46
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/* token-swatch-grid
|
|
2
|
+
* Color specimen grid referenced by design.md to display each color token with
|
|
3
|
+
* its sample, hex, and usage note.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
.token-swatch-grid {
|
|
7
|
+
display: grid;
|
|
8
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
9
|
+
gap: 3mm;
|
|
10
|
+
margin: var(--openpress-space-3) 0 var(--openpress-space-4);
|
|
11
|
+
break-inside: avoid;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.token-swatch {
|
|
15
|
+
min-height: 42mm;
|
|
16
|
+
overflow: hidden;
|
|
17
|
+
border: 1px solid var(--openpress-color-line);
|
|
18
|
+
border-radius: 6px;
|
|
19
|
+
background: var(--openpress-color-document);
|
|
20
|
+
box-sizing: border-box;
|
|
21
|
+
break-inside: avoid;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.token-swatch__sample {
|
|
25
|
+
height: 17mm;
|
|
26
|
+
background: var(--swatch);
|
|
27
|
+
border-bottom: 1px solid var(--swatch-border, var(--openpress-color-line));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.token-swatch__body {
|
|
31
|
+
padding: 3mm;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.token-swatch h4 {
|
|
35
|
+
margin: 0;
|
|
36
|
+
color: var(--openpress-color-ink);
|
|
37
|
+
font-family: var(--openpress-font-body);
|
|
38
|
+
font-size: 9pt;
|
|
39
|
+
font-weight: 600;
|
|
40
|
+
line-height: 1.25;
|
|
41
|
+
letter-spacing: 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.token-swatch code {
|
|
45
|
+
display: block;
|
|
46
|
+
margin-top: 1mm;
|
|
47
|
+
color: var(--openpress-color-muted);
|
|
48
|
+
font-size: 8pt;
|
|
49
|
+
line-height: 1.35;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.token-swatch p {
|
|
53
|
+
margin: 2mm 0 0;
|
|
54
|
+
color: #333333;
|
|
55
|
+
font-size: 8.4pt;
|
|
56
|
+
line-height: 1.45;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@media (max-width: 899px) {
|
|
60
|
+
.token-swatch-grid {
|
|
61
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export type TypeSpecimenVariant =
|
|
2
|
+
| "metric"
|
|
3
|
+
| "cover-title"
|
|
4
|
+
| "chapter-title"
|
|
5
|
+
| "section-title"
|
|
6
|
+
| "body"
|
|
7
|
+
| "caption";
|
|
8
|
+
|
|
9
|
+
export interface TypeSpecimenRow {
|
|
10
|
+
name: string;
|
|
11
|
+
spec: string;
|
|
12
|
+
sample: string;
|
|
13
|
+
sampleVariant: TypeSpecimenVariant;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface TypeSpecimenProps {
|
|
17
|
+
ariaLabel?: string;
|
|
18
|
+
rows: TypeSpecimenRow[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default function TypeSpecimen({
|
|
22
|
+
ariaLabel = "Typography specimen",
|
|
23
|
+
rows,
|
|
24
|
+
}: TypeSpecimenProps) {
|
|
25
|
+
return (
|
|
26
|
+
<section className="type-specimen" data-openpress-component="TypeSpecimen" aria-label={ariaLabel}>
|
|
27
|
+
{rows.map((row) => (
|
|
28
|
+
<div className="type-specimen__row" key={row.name}>
|
|
29
|
+
<div className="type-specimen__meta">
|
|
30
|
+
<strong>{row.name}</strong>
|
|
31
|
+
<span>{row.spec}</span>
|
|
32
|
+
</div>
|
|
33
|
+
<p className={`type-specimen__sample type-specimen__sample--${row.sampleVariant}`}>{row.sample}</p>
|
|
34
|
+
</div>
|
|
35
|
+
))}
|
|
36
|
+
</section>
|
|
37
|
+
);
|
|
38
|
+
}
|