gutterpress 0.0.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/README.md +422 -0
- package/dist/CGATS21_CRPC1-g0e3k7kr.icc +0 -0
- package/dist/api/index.d.ts +76 -0
- package/dist/api/index.js +272 -0
- package/dist/assets/preview/scripts/pagedjs-bridge.d.ts +1 -0
- package/dist/assets/preview/scripts/pagedjs-interface.d.ts +1 -0
- package/dist/assets/preview/scripts/preview-shell.d.ts +1 -0
- package/dist/audit-1jrwwacz.js +66 -0
- package/dist/build-5s92kgpc.js +77 -0
- package/dist/chapter-01-6fn9pvd0.md +31 -0
- package/dist/chapter-01-7jwqg1ct.md +20 -0
- package/dist/chapter-01-jj8ftn4c.md +29 -0
- package/dist/chapter-01-rkpyvjna.md +26 -0
- package/dist/checks/asset/approved-fonts.d.ts +3 -0
- package/dist/checks/asset/extensions.d.ts +41 -0
- package/dist/checks/asset/font-license.d.ts +3 -0
- package/dist/checks/asset/image-alpha.d.ts +3 -0
- package/dist/checks/asset/image-color-space.d.ts +3 -0
- package/dist/checks/asset/image-file-size.d.ts +3 -0
- package/dist/checks/asset/image-resolution.d.ts +3 -0
- package/dist/checks/asset/image-tac.d.ts +3 -0
- package/dist/checks/asset/index.d.ts +7 -0
- package/dist/checks/formatter.d.ts +3 -0
- package/dist/checks/heuristic/index.d.ts +4 -0
- package/dist/checks/heuristic/layer-count.d.ts +3 -0
- package/dist/checks/heuristic/placement-variance.d.ts +3 -0
- package/dist/checks/heuristic/section-density.d.ts +3 -0
- package/dist/checks/heuristic/text-density.d.ts +3 -0
- package/dist/checks/pdf/bleed.d.ts +3 -0
- package/dist/checks/pdf/bookmarks.d.ts +3 -0
- package/dist/checks/pdf/color-spaces.d.ts +3 -0
- package/dist/checks/pdf/cross-refs.d.ts +3 -0
- package/dist/checks/pdf/embedded-fonts.d.ts +3 -0
- package/dist/checks/pdf/image-resolution.d.ts +3 -0
- package/dist/checks/pdf/index.d.ts +15 -0
- package/dist/checks/pdf/ink-coverage.d.ts +3 -0
- package/dist/checks/pdf/page-labels.d.ts +3 -0
- package/dist/checks/pdf/page-size.d.ts +3 -0
- package/dist/checks/pdf/pdfx-markers.d.ts +3 -0
- package/dist/checks/pdf/pdfx-metadata.d.ts +3 -0
- package/dist/checks/pdf/pdfx-structure.d.ts +6 -0
- package/dist/checks/pdf/qpdf-structure.d.ts +3 -0
- package/dist/checks/pdf/rasterized-pages.d.ts +3 -0
- package/dist/checks/pdf/toc-links.d.ts +3 -0
- package/dist/checks/pdf/transparency.d.ts +3 -0
- package/dist/checks/policy.d.ts +61 -0
- package/dist/checks/register-builtins.d.ts +17 -0
- package/dist/checks/registry.d.ts +40 -0
- package/dist/checks/runner.d.ts +25 -0
- package/dist/checks/source/accessibility-alt-text.d.ts +3 -0
- package/dist/checks/source/accessibility-heading-order.d.ts +3 -0
- package/dist/checks/source/config-file.d.ts +8 -0
- package/dist/checks/source/htmlhint.d.ts +3 -0
- package/dist/checks/source/index.d.ts +6 -0
- package/dist/checks/source/local-refs.d.ts +3 -0
- package/dist/checks/source/markdownlint.d.ts +3 -0
- package/dist/checks/source/stylelint.d.ts +3 -0
- package/dist/checks/tool-check.d.ts +23 -0
- package/dist/checks/types.d.ts +52 -0
- package/dist/cli-1tyj4bk3.js +124 -0
- package/dist/cli-37x76zdn.js +4 -0
- package/dist/cli-506tg37g.js +26 -0
- package/dist/cli-5bxx0c4y.js +464 -0
- package/dist/cli-7ykx7pp0.js +12378 -0
- package/dist/cli-h7phg3ka.js +746 -0
- package/dist/cli-hvqjs342.js +284 -0
- package/dist/cli-yja077f6.js +92 -0
- package/dist/cli.js +157 -0
- package/dist/constants.d.ts +17 -0
- package/dist/doctor-25zjt8dz.js +57 -0
- package/dist/favicon-wkbm9cjn.ico +0 -0
- package/dist/git-http-yrb4ag6z.js +17 -0
- package/dist/index-1tyj4bk3.js +124 -0
- package/dist/index-37x76zdn.js +4 -0
- package/dist/index-3h3fef7r.js +15218 -0
- package/dist/index-5bxx0c4y.js +464 -0
- package/dist/index-yja077f6.js +92 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +310 -0
- package/dist/lib/app-heartbeat.d.ts +102 -0
- package/dist/lib/asset-inline.d.ts +73 -0
- package/dist/lib/browser-pool.d.ts +17 -0
- package/dist/lib/build-error.d.ts +52 -0
- package/dist/lib/build-fingerprint.d.ts +15 -0
- package/dist/lib/build-preflight.d.ts +43 -0
- package/dist/lib/build-runner.d.ts +161 -0
- package/dist/lib/build-staging.d.ts +64 -0
- package/dist/lib/chromium.d.ts +20 -0
- package/dist/lib/cli-args.d.ts +45 -0
- package/dist/lib/desktop.d.ts +14 -0
- package/dist/lib/diagnostics.d.ts +64 -0
- package/dist/lib/embedded-assets.d.ts +29 -0
- package/dist/lib/exec.d.ts +84 -0
- package/dist/lib/fetch-timeout.d.ts +41 -0
- package/dist/lib/ghostscript.d.ts +48 -0
- package/dist/lib/host-policy.d.ts +75 -0
- package/dist/lib/image-inspect.d.ts +32 -0
- package/dist/lib/install-hints.d.ts +21 -0
- package/dist/lib/lint-runner.d.ts +10 -0
- package/dist/lib/manifest-config.d.ts +31 -0
- package/dist/lib/manifest-doc.d.ts +25 -0
- package/dist/lib/manifest.d.ts +41 -0
- package/dist/lib/markdown/assemble.d.ts +78 -0
- package/dist/lib/markdown/chapter-id.d.ts +24 -0
- package/dist/lib/markdown/images.d.ts +34 -0
- package/dist/lib/markdown/index.d.ts +78 -0
- package/dist/lib/markdown/markdown-it-paged.d.ts +30 -0
- package/dist/lib/markdown/plugins.d.ts +69 -0
- package/dist/lib/markdown/renderer.d.ts +111 -0
- package/dist/lib/npm-plugin-installer.d.ts +33 -0
- package/dist/lib/open-path.d.ts +5 -0
- package/dist/lib/output-paths.d.ts +23 -0
- package/dist/lib/pagedjs-marker.d.ts +42 -0
- package/dist/lib/pagedjs.d.ts +26 -0
- package/dist/lib/pagination.d.ts +169 -0
- package/dist/lib/pdf-inspect.d.ts +123 -0
- package/dist/lib/pdf-parse.d.ts +57 -0
- package/dist/lib/plugin-manager.d.ts +108 -0
- package/dist/lib/plugin-vendor.d.ts +107 -0
- package/dist/lib/presets.d.ts +45 -0
- package/dist/lib/printsafe.d.ts +17 -0
- package/dist/lib/project-scaffold.d.ts +116 -0
- package/dist/lib/project-source.d.ts +140 -0
- package/dist/lib/project-templates.d.ts +49 -0
- package/dist/lib/publish/butler.d.ts +10 -0
- package/dist/lib/publish/command-runner.d.ts +18 -0
- package/dist/lib/publish/connect.d.ts +23 -0
- package/dist/lib/publish/manifest-publish.d.ts +9 -0
- package/dist/lib/publish/providers/azure-swa.d.ts +3 -0
- package/dist/lib/publish/providers/drivethrurpg.d.ts +10 -0
- package/dist/lib/publish/providers/guided.d.ts +3 -0
- package/dist/lib/publish/providers/itch.d.ts +5 -0
- package/dist/lib/publish/providers/kdp.d.ts +9 -0
- package/dist/lib/publish/providers/shopify.d.ts +5 -0
- package/dist/lib/publish/registry.d.ts +5 -0
- package/dist/lib/publish/run-publish.d.ts +30 -0
- package/dist/lib/publish/selections.d.ts +25 -0
- package/dist/lib/publish/types.d.ts +258 -0
- package/dist/lib/remote-auth/clone.d.ts +87 -0
- package/dist/lib/remote-auth/conflict-resolution.d.ts +29 -0
- package/dist/lib/remote-auth/diagnose.d.ts +77 -0
- package/dist/lib/remote-auth/generic-auth.d.ts +97 -0
- package/dist/lib/remote-auth/git-http.d.ts +85 -0
- package/dist/lib/remote-auth/github-auth.d.ts +69 -0
- package/dist/lib/remote-auth/github-repos.d.ts +64 -0
- package/dist/lib/remote-auth/operation-log.d.ts +66 -0
- package/dist/lib/remote-auth/recovery/abort-interrupted-operation.d.ts +103 -0
- package/dist/lib/remote-auth/recovery/backup.d.ts +113 -0
- package/dist/lib/remote-auth/recovery/classify.d.ts +109 -0
- package/dist/lib/remote-auth/recovery/context.d.ts +47 -0
- package/dist/lib/remote-auth/recovery/dispatch.d.ts +33 -0
- package/dist/lib/remote-auth/recovery/failsafe.d.ts +33 -0
- package/dist/lib/remote-auth/recovery/inspect.d.ts +74 -0
- package/dist/lib/remote-auth/recovery/manual-guidance.d.ts +28 -0
- package/dist/lib/remote-auth/recovery/outcome-mapping.d.ts +58 -0
- package/dist/lib/remote-auth/recovery/policy.d.ts +47 -0
- package/dist/lib/remote-auth/recovery/recover-auth.d.ts +42 -0
- package/dist/lib/remote-auth/recovery/recover-binary-conflict.d.ts +37 -0
- package/dist/lib/remote-auth/recovery/recover-corrupt-index.d.ts +40 -0
- package/dist/lib/remote-auth/recovery/recover-detached-head.d.ts +70 -0
- package/dist/lib/remote-auth/recovery/recover-interrupted-cherry-pick.d.ts +23 -0
- package/dist/lib/remote-auth/recovery/recover-interrupted-merge.d.ts +28 -0
- package/dist/lib/remote-auth/recovery/recover-interrupted-rebase.d.ts +39 -0
- package/dist/lib/remote-auth/recovery/recover-merge-conflict.d.ts +34 -0
- package/dist/lib/remote-auth/recovery/recover-missing-git-dir.d.ts +37 -0
- package/dist/lib/remote-auth/recovery/recover-missing-objects.d.ts +56 -0
- package/dist/lib/remote-auth/recovery/recover-network.d.ts +34 -0
- package/dist/lib/remote-auth/recovery/recover-non-fast-forward.d.ts +27 -0
- package/dist/lib/remote-auth/recovery/recover-stale-lock.d.ts +76 -0
- package/dist/lib/remote-auth/recovery/recover-unrelated-histories.d.ts +44 -0
- package/dist/lib/remote-auth/recovery/recover-wrong-remote.d.ts +35 -0
- package/dist/lib/remote-auth/recovery/types.d.ts +235 -0
- package/dist/lib/remote-auth/resolution-plan.d.ts +64 -0
- package/dist/lib/remote-auth/sync-messages.d.ts +26 -0
- package/dist/lib/remote-auth/sync-types.d.ts +225 -0
- package/dist/lib/remote-auth/sync.d.ts +45 -0
- package/dist/lib/remote-auth/test-access.d.ts +47 -0
- package/dist/lib/remote-auth/test-support/git-http-server.d.ts +71 -0
- package/dist/lib/remote-auth/token-store.d.ts +95 -0
- package/dist/lib/remote-auth/transport.d.ts +105 -0
- package/dist/lib/slug.d.ts +28 -0
- package/dist/lib/snippets.d.ts +39 -0
- package/dist/lib/source-provider.d.ts +244 -0
- package/dist/lib/static-serve.d.ts +54 -0
- package/dist/lib/style-resolver.d.ts +30 -0
- package/dist/lib/theme-import.d.ts +70 -0
- package/dist/lib/theme-manager.d.ts +128 -0
- package/dist/lib/tool-probe.d.ts +37 -0
- package/dist/lib/validation-exec.d.ts +47 -0
- package/dist/lib/validation-profile.d.ts +18 -0
- package/dist/lib/version.d.ts +9 -0
- package/dist/lint-f63nxjfj.js +65 -0
- package/dist/manifest-n1gh3qw5.yaml +9 -0
- package/dist/manifest-ryyg71nf.yaml +9 -0
- package/dist/manifest.schema-rn1dpdpn.json +564 -0
- package/dist/new-7b08a42h.js +105 -0
- package/dist/paged.polyfill-n95pbxfn.js +33288 -0
- package/dist/pagedjs-bridge-vn4hk9fx.js +111 -0
- package/dist/pagedjs-interface-80g3xa8p.js +498 -0
- package/dist/platform.d.ts +100 -0
- package/dist/plugin-wf2cbmwc.js +129 -0
- package/dist/preflight-tg4mpz1h.js +222 -0
- package/dist/preview/file-watcher.d.ts +174 -0
- package/dist/preview/http-server.d.ts +45 -0
- package/dist/preview/lifecycle.d.ts +67 -0
- package/dist/preview/server-context.d.ts +36 -0
- package/dist/preview-h2bwbb2x.js +102 -0
- package/dist/preview-shell-rghtfmc8.js +155 -0
- package/dist/project-source-0tg0r6vm.js +17 -0
- package/dist/publish-ztaet53r.js +233 -0
- package/dist/render.d.ts +20 -0
- package/dist/render.js +682 -0
- package/dist/repair-jkp4n3j8.js +171 -0
- package/dist/schema/manifest.types.d.ts +218 -0
- package/dist/server.d.ts +34 -0
- package/dist/source-provider-hp96b5jf.js +46 -0
- package/dist/test-helpers/testkit.d.ts +91 -0
- package/dist/theme-0yzvthe8.css +65 -0
- package/dist/theme-570zmh2t.css +58 -0
- package/dist/theme-6a2fngc8.json +6 -0
- package/dist/theme-cd6efzjw.json +6 -0
- package/dist/theme-nya4nqh6.css +70 -0
- package/dist/theme-tqfypc1w.json +6 -0
- package/dist/theme-xt0hjb1b.json +6 -0
- package/dist/theme-zz2ktzqs.css +60 -0
- package/dist/types.d.ts +31 -0
- package/dist/utils/file-utils.d.ts +53 -0
- package/dist/utils/logger.d.ts +59 -0
- package/dist/validate-k2drs19j.js +99 -0
- package/package.json +102 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildRecoveryContext,
|
|
3
|
+
classifyFromHealth,
|
|
4
|
+
classifyGitError,
|
|
5
|
+
inspectRepo,
|
|
6
|
+
isAppHeartbeatFresh,
|
|
7
|
+
isUnbornRepo,
|
|
8
|
+
makeManualGuidance,
|
|
9
|
+
recover,
|
|
10
|
+
verifyRepoReadable
|
|
11
|
+
} from "./cli-7ykx7pp0.js";
|
|
12
|
+
import {
|
|
13
|
+
FileTokenStore,
|
|
14
|
+
defaultConfigDir
|
|
15
|
+
} from "./cli-h7phg3ka.js";
|
|
16
|
+
import {
|
|
17
|
+
UsageError,
|
|
18
|
+
rejectExtraPositionals,
|
|
19
|
+
rejectUnknownFlags
|
|
20
|
+
} from "./cli-hvqjs342.js";
|
|
21
|
+
import"./cli-5bxx0c4y.js";
|
|
22
|
+
import"./cli-1tyj4bk3.js";
|
|
23
|
+
import"./cli-yja077f6.js";
|
|
24
|
+
import"./cli-37x76zdn.js";
|
|
25
|
+
|
|
26
|
+
// src/commands/repair.ts
|
|
27
|
+
import { defineCommand } from "citty";
|
|
28
|
+
import * as readline from "node:readline/promises";
|
|
29
|
+
import path from "node:path";
|
|
30
|
+
async function promptYesNo(question) {
|
|
31
|
+
if (!process.stdin.isTTY)
|
|
32
|
+
return false;
|
|
33
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
34
|
+
try {
|
|
35
|
+
const answer = (await rl.question(`${question} [y/N] `)).trim().toLowerCase();
|
|
36
|
+
return answer === "y" || answer === "yes";
|
|
37
|
+
} finally {
|
|
38
|
+
rl.close();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function describeRepair(req) {
|
|
42
|
+
const lines = [
|
|
43
|
+
"",
|
|
44
|
+
` ${req.summary}`,
|
|
45
|
+
"",
|
|
46
|
+
` • Changes your project files: ${req.willChangeLocalFiles ? "yes" : "no"}`,
|
|
47
|
+
` • Changes version-history internals: ${req.willChangeGitMetadata ? "yes" : "no"}`,
|
|
48
|
+
` • Changes anything online: ${req.willChangeRemote ? "yes" : "no"}`
|
|
49
|
+
];
|
|
50
|
+
if (req.backupZipPath) {
|
|
51
|
+
lines.push(` • Safety copy saved first: ${req.backupZipPath}`);
|
|
52
|
+
}
|
|
53
|
+
lines.push("");
|
|
54
|
+
return lines.join(`
|
|
55
|
+
`);
|
|
56
|
+
}
|
|
57
|
+
function printResult(result) {
|
|
58
|
+
console.log(result.message);
|
|
59
|
+
if ("guidance" in result && result.guidance) {
|
|
60
|
+
const g = result.guidance;
|
|
61
|
+
console.log(`
|
|
62
|
+
Next step: ${g.recommendedNextStep}`);
|
|
63
|
+
for (const step of g.safeNextSteps ?? [])
|
|
64
|
+
console.log(` - ${step}`);
|
|
65
|
+
if (g.supportDetails)
|
|
66
|
+
console.log(`
|
|
67
|
+
Details (for support): ${g.supportDetails}`);
|
|
68
|
+
}
|
|
69
|
+
if ("backupZipPath" in result && result.backupZipPath) {
|
|
70
|
+
console.log(`
|
|
71
|
+
Safety copy: ${result.backupZipPath}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function terminalConfirmationGate(autoApprove) {
|
|
75
|
+
return {
|
|
76
|
+
confirmRepair: async (req) => {
|
|
77
|
+
console.log(describeRepair(req));
|
|
78
|
+
if (autoApprove) {
|
|
79
|
+
console.log("Proceeding (--yes).");
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
return promptYesNo("Apply this fix?");
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
var commandArgs = {
|
|
87
|
+
dir: {
|
|
88
|
+
type: "positional",
|
|
89
|
+
description: "Project directory (defaults to the current directory)",
|
|
90
|
+
required: false
|
|
91
|
+
},
|
|
92
|
+
check: {
|
|
93
|
+
type: "boolean",
|
|
94
|
+
description: "Diagnose only — never change anything (exit 1 when repair is needed)",
|
|
95
|
+
default: false
|
|
96
|
+
},
|
|
97
|
+
yes: {
|
|
98
|
+
type: "boolean",
|
|
99
|
+
description: "Approve the repair without prompting",
|
|
100
|
+
default: false
|
|
101
|
+
},
|
|
102
|
+
force: {
|
|
103
|
+
type: "boolean",
|
|
104
|
+
description: "Repair even if the Gutterpress app appears to have this project open",
|
|
105
|
+
default: false
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
var repair_default = defineCommand({
|
|
109
|
+
meta: {
|
|
110
|
+
name: "repair",
|
|
111
|
+
description: "Diagnose and repair the project's version history"
|
|
112
|
+
},
|
|
113
|
+
args: commandArgs,
|
|
114
|
+
async run({ args, rawArgs }) {
|
|
115
|
+
try {
|
|
116
|
+
rejectUnknownFlags(rawArgs, commandArgs, "repair");
|
|
117
|
+
rejectExtraPositionals(args._, 1, "repair");
|
|
118
|
+
} catch (error) {
|
|
119
|
+
if (error instanceof UsageError) {
|
|
120
|
+
console.error(error.message);
|
|
121
|
+
process.exitCode = error.exitCode;
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
const openedDir = path.resolve(args.dir ?? ".");
|
|
127
|
+
const ctx = await buildRecoveryContext({
|
|
128
|
+
projectDir: openedDir,
|
|
129
|
+
confirmation: terminalConfirmationGate(args.yes),
|
|
130
|
+
tokenStore: new FileTokenStore(defaultConfigDir())
|
|
131
|
+
});
|
|
132
|
+
const health = await inspectRepo({ repoDir: ctx.repoDir, source: ctx.source });
|
|
133
|
+
let kind = classifyFromHealth(health, { minLockAgeMs: 0 });
|
|
134
|
+
if (kind === null) {
|
|
135
|
+
try {
|
|
136
|
+
await verifyRepoReadable(ctx.repoDir);
|
|
137
|
+
} catch (err) {
|
|
138
|
+
if (!isUnbornRepo(ctx.repoDir)) {
|
|
139
|
+
kind = classifyGitError(err, health);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (kind === null) {
|
|
144
|
+
console.log("Your project's version history looks healthy. Nothing to repair.");
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const guidance = makeManualGuidance(ctx, kind);
|
|
148
|
+
console.log(`Found a problem: ${guidance.userSummary}`);
|
|
149
|
+
if (args.check) {
|
|
150
|
+
console.log(`
|
|
151
|
+
Run \`gutterpress repair\` to fix it. ${guidance.recommendedNextStep}`);
|
|
152
|
+
process.exitCode = 1;
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
if (!args.force && await isAppHeartbeatFresh(ctx.repoDir)) {
|
|
156
|
+
console.log(`
|
|
157
|
+
The Gutterpress app appears to have this project open. Close it first, or re-run with --force.`);
|
|
158
|
+
process.exitCode = 1;
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const result = await recover(kind, ctx);
|
|
162
|
+
console.log("");
|
|
163
|
+
printResult(result);
|
|
164
|
+
if (result.status !== "recovered" && result.status !== "retry_later") {
|
|
165
|
+
process.exitCode = 1;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
export {
|
|
170
|
+
repair_default as default
|
|
171
|
+
};
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
export type CheckSeverity = "error" | "warning" | "info";
|
|
2
|
+
export interface PluginConfig {
|
|
3
|
+
path?: string;
|
|
4
|
+
name?: string;
|
|
5
|
+
/** Exact project-local npm version. Legacy ranges remain informational. */
|
|
6
|
+
version?: string;
|
|
7
|
+
/** Named module export to use when the package has no default plugin export. */
|
|
8
|
+
export?: string;
|
|
9
|
+
priority?: number;
|
|
10
|
+
options?: Record<string, unknown>;
|
|
11
|
+
/**
|
|
12
|
+
* Per-project enable flag (#30). Absent or `true` = active; `false` = the
|
|
13
|
+
* entry stays in the manifest (reversible toggle) but is skipped by
|
|
14
|
+
* `resolveConfig` so it is not loaded at build/preview time.
|
|
15
|
+
*/
|
|
16
|
+
enabled?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Non-secret, per-provider publish settings (#35), keyed by provider id —
|
|
20
|
+
* the same spelling as `gutterpress publish --provider <id>`. Secrets (API
|
|
21
|
+
* keys, tokens) NEVER live in the manifest — they belong to the host's
|
|
22
|
+
* credential store (CLI: 0600 file under the user config dir; desktop:
|
|
23
|
+
* Electron safeStorage).
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* The name (label) of the SAVED credential this book uses for a provider, when
|
|
27
|
+
* the user keeps more than one (e.g. two itch.io accounts). It is NOT a secret
|
|
28
|
+
* — just a reference into the host credential store's named entries; empty/
|
|
29
|
+
* absent uses the default (bare-host) credential. This book-level choice
|
|
30
|
+
* overrides any project/global default.
|
|
31
|
+
*/
|
|
32
|
+
export interface PublishSettings {
|
|
33
|
+
itch?: {
|
|
34
|
+
/** itch.io project as `user/game` (the butler push target). */
|
|
35
|
+
target?: string;
|
|
36
|
+
/** butler channel name (default: "pdf"). */
|
|
37
|
+
channel?: string;
|
|
38
|
+
/** Saved-credential label to use (see PublishSettings doc). */
|
|
39
|
+
credential?: string;
|
|
40
|
+
};
|
|
41
|
+
drivethrurpg?: {
|
|
42
|
+
/** Existing product page URL, when updating a published title. */
|
|
43
|
+
productUrl?: string;
|
|
44
|
+
};
|
|
45
|
+
kdp?: Record<string, never>;
|
|
46
|
+
"azure-swa"?: {
|
|
47
|
+
/** Deploy environment (default: "production"). */
|
|
48
|
+
env?: string;
|
|
49
|
+
/** Saved-credential label to use (see PublishSettings doc). */
|
|
50
|
+
credential?: string;
|
|
51
|
+
};
|
|
52
|
+
shopify?: {
|
|
53
|
+
/** The store domain, e.g. `my-store.myshopify.com`. */
|
|
54
|
+
shop?: string;
|
|
55
|
+
/** Existing product GID/id to update instead of creating a new one. */
|
|
56
|
+
productId?: string;
|
|
57
|
+
/** Admin GraphQL API version (default: "2026-04"). */
|
|
58
|
+
apiVersion?: string;
|
|
59
|
+
/** Saved-credential label to use (see PublishSettings doc). */
|
|
60
|
+
credential?: string;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export interface GutterpressManifest {
|
|
64
|
+
title?: string;
|
|
65
|
+
authors?: string[];
|
|
66
|
+
publish?: PublishSettings;
|
|
67
|
+
preset?: "dtrpg" | "book";
|
|
68
|
+
styles?: string[];
|
|
69
|
+
plugins?: (string | PluginConfig)[];
|
|
70
|
+
source?: {
|
|
71
|
+
files?: string[] | null;
|
|
72
|
+
};
|
|
73
|
+
pdfx?: {
|
|
74
|
+
flavor?: "x1a" | "x3";
|
|
75
|
+
icc?: string;
|
|
76
|
+
stripAnnotations?: boolean;
|
|
77
|
+
};
|
|
78
|
+
page?: {
|
|
79
|
+
width?: number;
|
|
80
|
+
height?: number;
|
|
81
|
+
tolerance?: number;
|
|
82
|
+
};
|
|
83
|
+
ink?: {
|
|
84
|
+
maxTac?: number;
|
|
85
|
+
tacTolerance?: number;
|
|
86
|
+
};
|
|
87
|
+
lint?: {
|
|
88
|
+
enabled?: boolean;
|
|
89
|
+
configPath?: string | null;
|
|
90
|
+
};
|
|
91
|
+
validate?: {
|
|
92
|
+
enabled?: boolean;
|
|
93
|
+
checks?: Record<string, boolean | {
|
|
94
|
+
enabled?: boolean;
|
|
95
|
+
severity?: CheckSeverity;
|
|
96
|
+
options?: Record<string, unknown>;
|
|
97
|
+
}>;
|
|
98
|
+
source?: {
|
|
99
|
+
markdownlint?: string | false;
|
|
100
|
+
htmlhint?: string | false;
|
|
101
|
+
stylelint?: string | false;
|
|
102
|
+
/**
|
|
103
|
+
* @deprecated `:::name` container syntax was removed 2026-05-17 and the
|
|
104
|
+
* callout-validation check it gated was removed at the same time. This
|
|
105
|
+
* field is now a no-op kept for backward-compatible manifest parsing.
|
|
106
|
+
* Will be removed in a future major version. See
|
|
107
|
+
* docs/migrations/2026-05-removing-container-syntax.md.
|
|
108
|
+
*/
|
|
109
|
+
allowedCallouts?: string[];
|
|
110
|
+
};
|
|
111
|
+
assets?: {
|
|
112
|
+
maxImageSize?: number;
|
|
113
|
+
minImageDpi?: number;
|
|
114
|
+
allowedColorSpaces?: string[];
|
|
115
|
+
allowAlpha?: boolean;
|
|
116
|
+
approvedFontFiles?: string[];
|
|
117
|
+
requireFontLicense?: boolean;
|
|
118
|
+
};
|
|
119
|
+
pdf?: {
|
|
120
|
+
requireBookmarks?: boolean;
|
|
121
|
+
requireTocLinks?: boolean;
|
|
122
|
+
minImageResolution?: number;
|
|
123
|
+
forbidTransparency?: boolean;
|
|
124
|
+
requireBleed?: boolean;
|
|
125
|
+
bleedSize?: number;
|
|
126
|
+
};
|
|
127
|
+
heuristics?: {
|
|
128
|
+
maxDecorativeLayers?: number;
|
|
129
|
+
textDensityRange?: {
|
|
130
|
+
min?: number;
|
|
131
|
+
max?: number;
|
|
132
|
+
};
|
|
133
|
+
maxParagraphsPerSection?: number;
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
export interface ResolvedPluginConfig {
|
|
138
|
+
path?: string;
|
|
139
|
+
name?: string;
|
|
140
|
+
/** Exact version for a project-local vendored npm plugin. */
|
|
141
|
+
version?: string;
|
|
142
|
+
/** Named module export selected as the plugin function. */
|
|
143
|
+
export?: string;
|
|
144
|
+
priority: number;
|
|
145
|
+
options: Record<string, unknown>;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Fully-resolved config. Every field is a concrete default with one
|
|
149
|
+
* deliberate exception: `styles` (ARCH finding #2). There is no preset
|
|
150
|
+
* default for it — `undefined` means "the manifest didn't set one", and
|
|
151
|
+
* `resolveActiveStyles` (style-resolver.ts) is the single source of truth for
|
|
152
|
+
* what that resolves to (styles/book.css, else the first discovered `.css`,
|
|
153
|
+
* else `[]`). Baking a preset default in here defeated that fallback chain.
|
|
154
|
+
*/
|
|
155
|
+
export interface ResolvedConfig {
|
|
156
|
+
title: string;
|
|
157
|
+
authors: string[];
|
|
158
|
+
styles?: string[];
|
|
159
|
+
plugins: ResolvedPluginConfig[];
|
|
160
|
+
source: {
|
|
161
|
+
files: string[] | null;
|
|
162
|
+
};
|
|
163
|
+
pdfx: {
|
|
164
|
+
flavor: "x1a" | "x3";
|
|
165
|
+
icc: string;
|
|
166
|
+
stripAnnotations: boolean;
|
|
167
|
+
};
|
|
168
|
+
page: {
|
|
169
|
+
width: number;
|
|
170
|
+
height: number;
|
|
171
|
+
tolerance: number;
|
|
172
|
+
};
|
|
173
|
+
ink: {
|
|
174
|
+
maxTac: number;
|
|
175
|
+
tacTolerance: number;
|
|
176
|
+
};
|
|
177
|
+
lint: {
|
|
178
|
+
enabled: boolean;
|
|
179
|
+
configPath: string | null;
|
|
180
|
+
};
|
|
181
|
+
validate: {
|
|
182
|
+
enabled: boolean;
|
|
183
|
+
checks: Record<string, boolean | {
|
|
184
|
+
enabled?: boolean;
|
|
185
|
+
severity?: CheckSeverity;
|
|
186
|
+
options?: Record<string, unknown>;
|
|
187
|
+
}>;
|
|
188
|
+
source: {
|
|
189
|
+
markdownlint: string | false | null;
|
|
190
|
+
htmlhint: string | false | null;
|
|
191
|
+
stylelint: string | false | null;
|
|
192
|
+
};
|
|
193
|
+
assets: {
|
|
194
|
+
maxImageSize: number;
|
|
195
|
+
minImageDpi: number;
|
|
196
|
+
allowedColorSpaces: string[];
|
|
197
|
+
allowAlpha: boolean;
|
|
198
|
+
approvedFontFiles: string[];
|
|
199
|
+
requireFontLicense: boolean;
|
|
200
|
+
};
|
|
201
|
+
pdf: {
|
|
202
|
+
requireBookmarks: boolean;
|
|
203
|
+
requireTocLinks: boolean;
|
|
204
|
+
minImageResolution: number;
|
|
205
|
+
forbidTransparency: boolean;
|
|
206
|
+
requireBleed: boolean;
|
|
207
|
+
bleedSize: number;
|
|
208
|
+
};
|
|
209
|
+
heuristics: {
|
|
210
|
+
maxDecorativeLayers: number;
|
|
211
|
+
textDensityRange: {
|
|
212
|
+
min: number;
|
|
213
|
+
max: number;
|
|
214
|
+
};
|
|
215
|
+
maxParagraphsPerSection: number;
|
|
216
|
+
};
|
|
217
|
+
};
|
|
218
|
+
}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preview server entry point.
|
|
3
|
+
*
|
|
4
|
+
* Loads config via lib/manifest, generates HTML via lib/markdown, and serves
|
|
5
|
+
* the preview through a node:http + `ws` HTTP+WebSocket server (see
|
|
6
|
+
* `src/preview/http-server.ts`). Live reload is handled by broadcasting
|
|
7
|
+
* `full-reload` over the HMR WebSocket whenever the file watcher fires.
|
|
8
|
+
*/
|
|
9
|
+
import type { PreviewServerOptions } from './types';
|
|
10
|
+
export interface PreviewServerHandle {
|
|
11
|
+
url: string;
|
|
12
|
+
port: number;
|
|
13
|
+
host: string;
|
|
14
|
+
inputPath: string;
|
|
15
|
+
/** Stop the server, file watcher, and any signal handlers. */
|
|
16
|
+
stop: () => Promise<void>;
|
|
17
|
+
/** Switch the watched directory and regenerate HTML. */
|
|
18
|
+
restart: (newInputPath: string) => Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
export interface StartPreviewServerOptions extends PreviewServerOptions {
|
|
21
|
+
/**
|
|
22
|
+
* Install SIGINT/SIGTERM handlers that shut down the server on Ctrl+C.
|
|
23
|
+
* Defaults to true (CLI usage). Library/embedded callers (Electron+SvelteKit)
|
|
24
|
+
* should pass false and call handle.stop() themselves.
|
|
25
|
+
*/
|
|
26
|
+
installSignalHandlers?: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Start the preview server backed by a node:http + `ws` HTTP/WebSocket server.
|
|
30
|
+
*
|
|
31
|
+
* Returns a handle the caller can use to introspect the URL or stop the server.
|
|
32
|
+
* CLI callers can simply ignore the handle and rely on SIGINT/SIGTERM.
|
|
33
|
+
*/
|
|
34
|
+
export declare function startPreviewServer(options: StartPreviewServerOptions): Promise<PreviewServerHandle>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AUTO_SNAPSHOT_MESSAGE,
|
|
3
|
+
HISTORY_PAGE_LIMIT,
|
|
4
|
+
RESTORE_BACKUP_MESSAGE,
|
|
5
|
+
SNAPSHOT_STAGING_MARKER,
|
|
6
|
+
__repoLockQueueSizeForTests,
|
|
7
|
+
gitAuthor,
|
|
8
|
+
gitDirFor,
|
|
9
|
+
gitScopeFor,
|
|
10
|
+
hasPendingChanges,
|
|
11
|
+
hasUncommittedChanges,
|
|
12
|
+
isNoChangesError,
|
|
13
|
+
listWorkdirChanges,
|
|
14
|
+
providerFor,
|
|
15
|
+
readGitAuthor,
|
|
16
|
+
resolveGitAuthor,
|
|
17
|
+
restoreVersionWithBackup,
|
|
18
|
+
snapshotStagingMarkerPath,
|
|
19
|
+
snapshotWorkingTreeUnlocked,
|
|
20
|
+
stageChanges,
|
|
21
|
+
withRepoLock
|
|
22
|
+
} from "./cli-5bxx0c4y.js";
|
|
23
|
+
import"./cli-1tyj4bk3.js";
|
|
24
|
+
import"./cli-37x76zdn.js";
|
|
25
|
+
export {
|
|
26
|
+
withRepoLock,
|
|
27
|
+
stageChanges,
|
|
28
|
+
snapshotWorkingTreeUnlocked,
|
|
29
|
+
snapshotStagingMarkerPath,
|
|
30
|
+
restoreVersionWithBackup,
|
|
31
|
+
resolveGitAuthor,
|
|
32
|
+
readGitAuthor,
|
|
33
|
+
providerFor,
|
|
34
|
+
listWorkdirChanges,
|
|
35
|
+
isNoChangesError,
|
|
36
|
+
hasUncommittedChanges,
|
|
37
|
+
hasPendingChanges,
|
|
38
|
+
gitScopeFor,
|
|
39
|
+
gitDirFor,
|
|
40
|
+
gitAuthor,
|
|
41
|
+
__repoLockQueueSizeForTests,
|
|
42
|
+
SNAPSHOT_STAGING_MARKER,
|
|
43
|
+
RESTORE_BACKUP_MESSAGE,
|
|
44
|
+
HISTORY_PAGE_LIMIT,
|
|
45
|
+
AUTO_SNAPSHOT_MESSAGE
|
|
46
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared CLI test-scaffolding kit.
|
|
3
|
+
*
|
|
4
|
+
* TEST-ONLY. This module is imported exclusively by `*.test.ts` files — it is
|
|
5
|
+
* never referenced by production entrypoints (`src/index.ts`, `src/cli.ts`),
|
|
6
|
+
* so it never lands in the `bun build`/`bun build --compile` output. It exists
|
|
7
|
+
* to kill the copy-pasted scaffolding that used to live inline in dozens of
|
|
8
|
+
* test files (`makeTempDir` ~13×, `makeCtx` ~2× for the CheckContext shape,
|
|
9
|
+
* plus the isomorphic-git repo builders).
|
|
10
|
+
*
|
|
11
|
+
* Where copies differed meaningfully, the canonical helper keeps every
|
|
12
|
+
* behavior via options rather than silently picking one — callers pass the
|
|
13
|
+
* exact prefix/author/content they relied on.
|
|
14
|
+
*/
|
|
15
|
+
import { spyOn } from "bun:test";
|
|
16
|
+
import type { FsClient } from "isomorphic-git";
|
|
17
|
+
import type { CheckContext } from "../checks/types";
|
|
18
|
+
/**
|
|
19
|
+
* Create a fresh, unique temp directory under `os.tmpdir()`.
|
|
20
|
+
*
|
|
21
|
+
* The `prefix` is purely a human-readable naming segment for the OS-assigned
|
|
22
|
+
* unique dir (handy when eyeballing leftover fixtures); callers that relied on
|
|
23
|
+
* a suite-specific prefix pass it through so behavior is byte-identical.
|
|
24
|
+
*/
|
|
25
|
+
export declare function makeTempDir(prefix?: string): Promise<string>;
|
|
26
|
+
/**
|
|
27
|
+
* Build a {@link CheckContext} for check/policy unit tests, filling the
|
|
28
|
+
* required fields with defaults and shallow-merging a partial override
|
|
29
|
+
* (last-write-wins), matching the copies that lived in
|
|
30
|
+
* `checks.test.ts` / `policy.test.ts`.
|
|
31
|
+
*/
|
|
32
|
+
export declare function makeCtx(partial?: Partial<CheckContext>): CheckContext;
|
|
33
|
+
export interface TestAuthor {
|
|
34
|
+
name: string;
|
|
35
|
+
email: string;
|
|
36
|
+
}
|
|
37
|
+
/** The author most recovery-test copies used. */
|
|
38
|
+
export declare const DEFAULT_TEST_AUTHOR: TestAuthor;
|
|
39
|
+
export interface InitRepoOptions {
|
|
40
|
+
branch?: string;
|
|
41
|
+
content?: string;
|
|
42
|
+
message?: string;
|
|
43
|
+
author?: TestAuthor;
|
|
44
|
+
fs?: FsClient;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Initialize a git repo with a single committed `chapter-01.md` and return the
|
|
48
|
+
* initial commit oid. Every varying bit (branch, file content, commit message,
|
|
49
|
+
* author, fs impl) is an option so the previously-bespoke copies map onto it
|
|
50
|
+
* without changing behavior.
|
|
51
|
+
*/
|
|
52
|
+
export declare function initRepo(dir: string, opts?: InitRepoOptions): Promise<string>;
|
|
53
|
+
/**
|
|
54
|
+
* Like {@link initRepo} but defaults to the `"initial"` commit message the
|
|
55
|
+
* `makeTestRepo` copies used. Always on `main`. Returns the commit oid.
|
|
56
|
+
*/
|
|
57
|
+
export declare function makeTestRepo(dir: string, opts?: Omit<InitRepoOptions, "branch">): Promise<string>;
|
|
58
|
+
export interface CommitFileOptions {
|
|
59
|
+
message?: string;
|
|
60
|
+
author?: TestAuthor;
|
|
61
|
+
fs?: FsClient;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Write `body` to `filename` inside an existing repo, stage it and commit.
|
|
65
|
+
* Defaults the message to `add <filename>` (the copies' convention). Returns
|
|
66
|
+
* the commit oid.
|
|
67
|
+
*/
|
|
68
|
+
export declare function commitFile(dir: string, filename: string, body: string, opts?: CommitFileOptions): Promise<string>;
|
|
69
|
+
/**
|
|
70
|
+
* Thrown by {@link stubProcessExit}'s stub instead of actually terminating
|
|
71
|
+
* the test worker. Carries the exit code so `expect(...).rejects.toThrow(...)`
|
|
72
|
+
* can assert on it directly.
|
|
73
|
+
*/
|
|
74
|
+
export declare class ProcessExitSignal extends Error {
|
|
75
|
+
code: number;
|
|
76
|
+
constructor(code: number);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Replace `process.exit` with a stub that THROWS a {@link ProcessExitSignal}
|
|
80
|
+
* instead of ending the process — mirroring real `process.exit()` semantics
|
|
81
|
+
* (nothing after the call site ever runs) while staying observable in tests.
|
|
82
|
+
* Command handlers routinely do `log.error(...); process.exit(code);` with no
|
|
83
|
+
* `return` after — without this, a naive no-op stub would fall through into
|
|
84
|
+
* whatever code follows and throw on unrelated undefined state.
|
|
85
|
+
*
|
|
86
|
+
* Callers MUST `mockRestore()` the returned spy (e.g. in `afterEach`) —
|
|
87
|
+
* `process` is a shared global across the whole test run, exactly like the
|
|
88
|
+
* `spyOn`/`mockRestore` discipline documented in
|
|
89
|
+
* `build-runner.browser-lifecycle.test.ts`.
|
|
90
|
+
*/
|
|
91
|
+
export declare function stubProcessExit(): ReturnType<typeof spyOn<typeof process, "exit">>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/* =============================================================================
|
|
2
|
+
TTRPG Supplement — gutterpress built-in theme (theme.css)
|
|
3
|
+
Bold headings, parchment fills, boxed blocks. Customize the tokens in :root.
|
|
4
|
+
============================================================================= */
|
|
5
|
+
|
|
6
|
+
:root {
|
|
7
|
+
--color-ink: #241a12; /* body text */
|
|
8
|
+
--color-ink-muted: #5c4a36; /* captions, secondary text */
|
|
9
|
+
--color-accent: #7a2222; /* headings, key accents */
|
|
10
|
+
--color-paper: #faf4e6; /* parchment page background */
|
|
11
|
+
--color-tint: #efe3c8; /* stat-block / callout fill */
|
|
12
|
+
--color-rule: #b89a6a; /* borders, rules */
|
|
13
|
+
|
|
14
|
+
--font-body: "Palatino Linotype", "Book Antiqua", Palatino, serif;
|
|
15
|
+
--font-display: "Trajan Pro", "Cinzel", "Georgia", serif;
|
|
16
|
+
--font-mono: "Consolas", "Menlo", monospace;
|
|
17
|
+
|
|
18
|
+
--scale-h1: 2.4rem;
|
|
19
|
+
--scale-h2: 1.7rem;
|
|
20
|
+
--scale-h3: 1.25rem;
|
|
21
|
+
--leading: 1.45;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@page {
|
|
25
|
+
size: 8.5in 11in;
|
|
26
|
+
margin: 0.7in;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
body {
|
|
30
|
+
color: var(--color-ink);
|
|
31
|
+
background: var(--color-paper);
|
|
32
|
+
font-family: var(--font-body);
|
|
33
|
+
line-height: var(--leading);
|
|
34
|
+
font-size: 10.5pt;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
h1, h2, h3 {
|
|
38
|
+
font-family: var(--font-display);
|
|
39
|
+
color: var(--color-accent);
|
|
40
|
+
letter-spacing: 0.02em;
|
|
41
|
+
text-transform: uppercase;
|
|
42
|
+
font-weight: 700;
|
|
43
|
+
}
|
|
44
|
+
h1 { font-size: var(--scale-h1); margin: 0 0 0.5em; border-bottom: 3px double var(--color-rule); padding-bottom: 0.2em; }
|
|
45
|
+
h2 { font-size: var(--scale-h2); margin: 1.3em 0 0.4em; }
|
|
46
|
+
h3 { font-size: var(--scale-h3); margin: 1.1em 0 0.3em; letter-spacing: 0; }
|
|
47
|
+
|
|
48
|
+
p { margin: 0 0 0.7em; }
|
|
49
|
+
|
|
50
|
+
a { color: var(--color-accent); text-decoration: none; }
|
|
51
|
+
|
|
52
|
+
blockquote {
|
|
53
|
+
margin: 1em 0; padding: 0.6em 0.9em;
|
|
54
|
+
background: var(--color-tint);
|
|
55
|
+
border: 1px solid var(--color-rule);
|
|
56
|
+
border-radius: 4px;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
table {
|
|
60
|
+
width: 100%; border-collapse: collapse; margin: 1em 0;
|
|
61
|
+
}
|
|
62
|
+
th, td { border: 1px solid var(--color-rule); padding: 0.35em 0.6em; text-align: left; }
|
|
63
|
+
th { background: var(--color-tint); font-family: var(--font-display); }
|
|
64
|
+
|
|
65
|
+
code, pre { font-family: var(--font-mono); font-size: 0.9em; }
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/* =============================================================================
|
|
2
|
+
Clean Book — gutterpress built-in theme (theme.css)
|
|
3
|
+
A calm, classic long-form book look. Customize the tokens in :root.
|
|
4
|
+
============================================================================= */
|
|
5
|
+
|
|
6
|
+
:root {
|
|
7
|
+
--color-ink: #1a1a1a; /* body text */
|
|
8
|
+
--color-ink-muted: #555555; /* captions, secondary text */
|
|
9
|
+
--color-accent: #2b4c7e; /* headings, links */
|
|
10
|
+
--color-paper: #ffffff; /* page background */
|
|
11
|
+
--color-rule: #d9d9d9; /* borders, rules */
|
|
12
|
+
|
|
13
|
+
--font-body: "Georgia", "Times New Roman", serif;
|
|
14
|
+
--font-display: "Georgia", "Times New Roman", serif;
|
|
15
|
+
--font-mono: "Menlo", "Consolas", monospace;
|
|
16
|
+
|
|
17
|
+
--scale-h1: 2.1rem;
|
|
18
|
+
--scale-h2: 1.5rem;
|
|
19
|
+
--scale-h3: 1.2rem;
|
|
20
|
+
--leading: 1.55;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@page {
|
|
24
|
+
size: 6in 9in;
|
|
25
|
+
margin: 0.85in 0.75in;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
body {
|
|
29
|
+
color: var(--color-ink);
|
|
30
|
+
background: var(--color-paper);
|
|
31
|
+
font-family: var(--font-body);
|
|
32
|
+
line-height: var(--leading);
|
|
33
|
+
font-size: 11pt;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
h1, h2, h3 {
|
|
37
|
+
font-family: var(--font-display);
|
|
38
|
+
color: var(--color-accent);
|
|
39
|
+
line-height: 1.2;
|
|
40
|
+
font-weight: 600;
|
|
41
|
+
}
|
|
42
|
+
h1 { font-size: var(--scale-h1); margin: 0 0 0.6em; }
|
|
43
|
+
h2 { font-size: var(--scale-h2); margin: 1.4em 0 0.4em; }
|
|
44
|
+
h3 { font-size: var(--scale-h3); margin: 1.2em 0 0.3em; }
|
|
45
|
+
|
|
46
|
+
p { margin: 0 0 0.8em; text-align: justify; hyphens: auto; }
|
|
47
|
+
|
|
48
|
+
a { color: var(--color-accent); text-decoration: none; }
|
|
49
|
+
|
|
50
|
+
blockquote {
|
|
51
|
+
margin: 1em 0; padding: 0.2em 0 0.2em 1em;
|
|
52
|
+
border-left: 3px solid var(--color-rule);
|
|
53
|
+
color: var(--color-ink-muted); font-style: italic;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
code, pre { font-family: var(--font-mono); font-size: 0.9em; }
|
|
57
|
+
|
|
58
|
+
hr { border: 0; border-top: 1px solid var(--color-rule); margin: 1.5em 0; }
|