@rtorcato/repo-tooling 4.8.0 → 5.0.1
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/AGENTS.md +0 -1
- package/dist/base/checks.js +0 -75
- package/dist/base/fixers.js +0 -36
- package/dist/cli/commands/doctor.js +2 -8
- package/dist/cli/commands/fix-targets.js +0 -7
- package/dist/cli/commands/setup-presets.js +3 -5
- package/dist/cli/commands/setup.js +0 -9
- package/dist/cli/generators/index.js +0 -6
- package/dist/cli/index.js +9 -6
- package/dist/cli/utils/copy-preset.js +0 -20
- package/dist/cli/utils/lockfile.js +5 -3
- package/dist/languages/js/checks.js +0 -62
- package/dist/languages/js/fixers.js +1 -44
- package/package.json +1 -11
- package/tooling/semantic-release/github.mjs +1 -1
- package/dist/cli/generators/brand.js +0 -467
- package/dist/cli/generators/docs-site.js +0 -463
- package/tooling/docusaurus/docs-helpers.mjs +0 -109
- package/tooling/docusaurus/index.d.mts +0 -17
- package/tooling/docusaurus/index.mjs +0 -38
- package/tooling/docusaurus/sync-changelog.mjs +0 -106
- package/tooling/docusaurus/theme-tokens.css +0 -79
- package/tooling/docusaurus/theme.css +0 -390
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
// Canonical sync-changelog for @rtorcato/* docs sites (shipped by
|
|
2
|
-
// @rtorcato/repo-tooling — copy via `repo-tooling copy docusaurus-sync-changelog`).
|
|
3
|
-
//
|
|
4
|
-
// Builds the docs site's changelog page from **GitHub Releases**, not from
|
|
5
|
-
// CHANGELOG.md. The output file is gitignored — it is regenerated on every docs
|
|
6
|
-
// build (wire it into the docs app's `build`/`start` scripts; pnpm 8 doesn't run
|
|
7
|
-
// `pre*` hooks reliably, so chain it explicitly).
|
|
8
|
-
//
|
|
9
|
-
// Why Releases and not the file: the shipped semantic-release github preset
|
|
10
|
-
// does not use @semantic-release/git, because the `code-scanning-main` ruleset
|
|
11
|
-
// rejects the release commit with GH013 (see tooling/semantic-release/github.mjs
|
|
12
|
-
// and rtorcato/repo-tooling#417). Nothing commits CHANGELOG.md back, so it is
|
|
13
|
-
// frozen at whatever the last release with that plugin wrote — and it freezes at
|
|
14
|
-
// a *real* release, which is why it reads as current. @semantic-release/github
|
|
15
|
-
// writes Releases from the same notes that used to build CHANGELOG.md, so
|
|
16
|
-
// concatenating their bodies reproduces the old page and cannot go stale.
|
|
17
|
-
//
|
|
18
|
-
// The target defaults to Docusaurus's `apps/docs/docs/changelog.md`. Override
|
|
19
|
-
// with the CHANGELOG_TARGET env var (path relative to the repo root) for other
|
|
20
|
-
// layouts — e.g. a Fumadocs content root:
|
|
21
|
-
// CHANGELOG_TARGET=apps/web/content/docs/changelog.mdx node scripts/sync-changelog.mjs
|
|
22
|
-
// The title/description frontmatter is framework-neutral (both Docusaurus and
|
|
23
|
-
// Fumadocs read it), so only the path changes between frameworks.
|
|
24
|
-
//
|
|
25
|
-
// The docs workflow must rebuild on `release: types: [published]` — with no
|
|
26
|
-
// release commit landing on the default branch, a `push` trigger never fires.
|
|
27
|
-
|
|
28
|
-
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs'
|
|
29
|
-
import { dirname, resolve } from 'node:path'
|
|
30
|
-
import { fileURLToPath } from 'node:url'
|
|
31
|
-
|
|
32
|
-
const here = dirname(fileURLToPath(import.meta.url))
|
|
33
|
-
const repoRoot = resolve(here, '..')
|
|
34
|
-
const target = resolve(repoRoot, process.env.CHANGELOG_TARGET ?? 'apps/docs/docs/changelog.md')
|
|
35
|
-
|
|
36
|
-
/** `owner/name` — from CI, else from package.json `repository`. */
|
|
37
|
-
function resolveRepo() {
|
|
38
|
-
if (process.env.GITHUB_REPOSITORY) return process.env.GITHUB_REPOSITORY
|
|
39
|
-
const pkg = JSON.parse(readFileSync(resolve(repoRoot, 'package.json'), 'utf8'))
|
|
40
|
-
const url = typeof pkg.repository === 'string' ? pkg.repository : pkg.repository?.url
|
|
41
|
-
const match = /github\.com[/:]([^/]+\/[^/.]+)/.exec(url ?? '')
|
|
42
|
-
if (!match) throw new Error('no GITHUB_REPOSITORY and no github repository in package.json')
|
|
43
|
-
return match[1]
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const frontmatter = `---
|
|
47
|
-
title: Changelog
|
|
48
|
-
description: Release notes, generated by semantic-release and published to GitHub Releases.
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
`
|
|
52
|
-
|
|
53
|
-
const footer = (repo, note) =>
|
|
54
|
-
`\n\n---\n\n${note}Every entry above is generated by semantic-release and published to [GitHub Releases](https://github.com/${repo}/releases). Anything older than the first GitHub Release is recorded in [CHANGELOG.md](https://github.com/${repo}/blob/main/CHANGELOG.md).\n`
|
|
55
|
-
|
|
56
|
-
async function fetchReleases(repo) {
|
|
57
|
-
const headers = { Accept: 'application/vnd.github+json' }
|
|
58
|
-
// Optional: lifts the 60/hr unauthenticated rate limit. CI passes it; local
|
|
59
|
-
// builds work fine without it at a typical repo's release count.
|
|
60
|
-
// ponytail: one page of 100. Paginate when a repo outgrows it.
|
|
61
|
-
const token = process.env.GITHUB_TOKEN ?? process.env.GH_TOKEN
|
|
62
|
-
if (token) headers.Authorization = `Bearer ${token}`
|
|
63
|
-
|
|
64
|
-
const res = await fetch(`https://api.github.com/repos/${repo}/releases?per_page=100`, { headers })
|
|
65
|
-
if (!res.ok) throw new Error(`GitHub API ${res.status} ${res.statusText}`)
|
|
66
|
-
return res.json()
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function render(releases) {
|
|
70
|
-
// The API does not guarantee date order, and a release body already carries
|
|
71
|
-
// its own version heading and date — so sort here and emit bodies verbatim.
|
|
72
|
-
const sorted = releases
|
|
73
|
-
.filter((r) => !r.draft && r.body?.trim())
|
|
74
|
-
.sort((a, b) => new Date(b.published_at) - new Date(a.published_at))
|
|
75
|
-
|
|
76
|
-
if (sorted.length === 0) throw new Error('no releases with a body')
|
|
77
|
-
return sorted.map((r) => r.body.trim()).join('\n\n')
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
let repo = ''
|
|
81
|
-
let body
|
|
82
|
-
try {
|
|
83
|
-
repo = resolveRepo()
|
|
84
|
-
body = render(await fetchReleases(repo)) + footer(repo, '')
|
|
85
|
-
console.log(`sync-changelog: built from ${repo} GitHub Releases`)
|
|
86
|
-
} catch (error) {
|
|
87
|
-
// Never fail the docs build on a network blip — fall back to the frozen file
|
|
88
|
-
// and say so on the page rather than shipping a silently truncated one.
|
|
89
|
-
console.warn(`sync-changelog: ${error.message} — falling back to CHANGELOG.md`)
|
|
90
|
-
try {
|
|
91
|
-
body =
|
|
92
|
-
readFileSync(resolve(repoRoot, 'CHANGELOG.md'), 'utf8').trim() +
|
|
93
|
-
(repo
|
|
94
|
-
? footer(
|
|
95
|
-
repo,
|
|
96
|
-
'**This page was built from the repository CHANGELOG.md because GitHub Releases could not be reached, and may be out of date.** '
|
|
97
|
-
)
|
|
98
|
-
: '')
|
|
99
|
-
} catch {
|
|
100
|
-
body = '# Changelog\n\nNo releases recorded yet.\n'
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
mkdirSync(dirname(target), { recursive: true })
|
|
105
|
-
writeFileSync(target, frontmatter + body)
|
|
106
|
-
console.log(`sync-changelog: wrote ${target}`)
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared @rtorcato Docusaurus design tokens (shipped by @rtorcato/repo-tooling —
|
|
3
|
-
* copy via `repo-tooling copy docusaurus-theme-tokens`).
|
|
4
|
-
*
|
|
5
|
-
* The Geist font + navy-surface design-token base every sibling docs site
|
|
6
|
-
* shares. `@import` this from your `src/css/custom.css`, then override the
|
|
7
|
-
* accent (`--ifm-color-primary*` and `--jt-accent*`) with your brand colour:
|
|
8
|
-
*
|
|
9
|
-
* @import "./_jt-tokens.css";
|
|
10
|
-
* :root { --ifm-color-primary: #F38020; --jt-accent: #F38020; }
|
|
11
|
-
* [data-theme=dark]{ --ifm-color-primary: #ff9a4d; --jt-accent: #ff9a4d; }
|
|
12
|
-
*
|
|
13
|
-
* The default accent below is Docusaurus's neutral green — meant to be replaced.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
/* ---------- Fonts ---------- */
|
|
17
|
-
@import url("https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700;800&family=Geist+Mono:wght@400;500;600&display=swap");
|
|
18
|
-
|
|
19
|
-
/* ---------- Light (default) ---------- */
|
|
20
|
-
:root {
|
|
21
|
-
--ifm-color-primary: #2e8555;
|
|
22
|
-
|
|
23
|
-
--ifm-font-family-base: "Geist", system-ui, -apple-system, sans-serif;
|
|
24
|
-
--ifm-font-family-monospace: "Geist Mono", ui-monospace, SFMono-Regular, monospace;
|
|
25
|
-
--ifm-heading-font-weight: 800;
|
|
26
|
-
--ifm-code-font-size: 92%;
|
|
27
|
-
|
|
28
|
-
--ifm-background-color: #ffffff;
|
|
29
|
-
--ifm-background-surface-color: #ffffff;
|
|
30
|
-
--ifm-navbar-background-color: rgba(255, 255, 255, 0.8);
|
|
31
|
-
--ifm-heading-color: #0a0e16;
|
|
32
|
-
--ifm-font-color-base: #374253;
|
|
33
|
-
--ifm-toc-border-color: rgba(12, 18, 28, 0.1);
|
|
34
|
-
--ifm-code-background: #f3f6f9;
|
|
35
|
-
|
|
36
|
-
/* Design tokens (surfaces/text/borders are shared; accent is per-project). */
|
|
37
|
-
--jt-accent: var(--ifm-color-primary);
|
|
38
|
-
--jt-on-accent: #ffffff;
|
|
39
|
-
--jt-bg: #ffffff;
|
|
40
|
-
--jt-bg2: #f6f8fb;
|
|
41
|
-
--jt-surface: #ffffff;
|
|
42
|
-
--jt-surface2: #f3f6f9;
|
|
43
|
-
--jt-code-bg: #f3f6f9;
|
|
44
|
-
--jt-border: rgba(12, 18, 28, 0.1);
|
|
45
|
-
--jt-border2: rgba(12, 18, 28, 0.16);
|
|
46
|
-
--jt-heading: #0a0e16;
|
|
47
|
-
--jt-text: #374253;
|
|
48
|
-
--jt-muted: #5b6675;
|
|
49
|
-
--jt-faint: #8a95a5;
|
|
50
|
-
--jt-shadow: 0 22px 50px -26px rgba(20, 28, 44, 0.3);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/* ---------- Dark ---------- */
|
|
54
|
-
[data-theme="dark"] {
|
|
55
|
-
--ifm-color-primary: #25c2a0;
|
|
56
|
-
|
|
57
|
-
--ifm-background-color: #0a0e16;
|
|
58
|
-
--ifm-background-surface-color: #111824;
|
|
59
|
-
--ifm-navbar-background-color: #0a0e16;
|
|
60
|
-
--ifm-heading-color: #ffffff;
|
|
61
|
-
--ifm-font-color-base: #dfe5ee;
|
|
62
|
-
--ifm-toc-border-color: rgba(255, 255, 255, 0.08);
|
|
63
|
-
--ifm-code-background: #0d131d;
|
|
64
|
-
|
|
65
|
-
--jt-accent: var(--ifm-color-primary);
|
|
66
|
-
--jt-on-accent: #0a0e16;
|
|
67
|
-
--jt-bg: #0a0e16;
|
|
68
|
-
--jt-bg2: #0b101a;
|
|
69
|
-
--jt-surface: #111824;
|
|
70
|
-
--jt-surface2: #0d131d;
|
|
71
|
-
--jt-code-bg: #0c111b;
|
|
72
|
-
--jt-border: rgba(255, 255, 255, 0.08);
|
|
73
|
-
--jt-border2: rgba(255, 255, 255, 0.14);
|
|
74
|
-
--jt-heading: #ffffff;
|
|
75
|
-
--jt-text: #dfe5ee;
|
|
76
|
-
--jt-muted: #94a1b4;
|
|
77
|
-
--jt-faint: #647184;
|
|
78
|
-
--jt-shadow: 0 30px 70px -30px rgba(0, 0, 0, 0.75);
|
|
79
|
-
}
|
|
@@ -1,390 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared @rtorcato Docusaurus component theme (shipped by @rtorcato/repo-tooling —
|
|
3
|
-
* copy via `repo-tooling copy docusaurus-theme`).
|
|
4
|
-
*
|
|
5
|
-
* The accent-agnostic component-override sheet every sibling docs site shares:
|
|
6
|
-
* navbar, doc cards, sidebar, TOC, pagination, footer, code blocks, markdown
|
|
7
|
-
* tables, buttons, and the hardened navy dark surfaces. Every rule references
|
|
8
|
-
* the `--jt-*` / `--ifm-*` tokens from `_jt-tokens.css` (see
|
|
9
|
-
* `copy docusaurus-theme-tokens`) — it defines NO accent colours.
|
|
10
|
-
*
|
|
11
|
-
* Usage in your `src/css/custom.css`:
|
|
12
|
-
*
|
|
13
|
-
* @import "./_jt-tokens.css"; // shared design tokens
|
|
14
|
-
* @import "./theme.css"; // this file — shared component styling
|
|
15
|
-
* :root { --ifm-color-primary: #YOURHEX; --jt-accent: #YOURHEX; ... }
|
|
16
|
-
* [data-theme=dark]{ --ifm-color-primary: #YOURHEX; --jt-accent: #YOURHEX; ... }
|
|
17
|
-
* ::selection { background: rgba(R, G, B, 0.24); } // accent — keep local
|
|
18
|
-
*
|
|
19
|
-
* The single-flat mobile drawer (the `.navbar-sidebar__items` transform lock +
|
|
20
|
-
* the repo-namespaced `.xx-mobile-menu` rules) is NOT here — it ships with the
|
|
21
|
-
* Navbar/MobileSidebar swizzle files, since its class prefix is per-repo.
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
/* ---------- Navbar ---------- */
|
|
25
|
-
.navbar {
|
|
26
|
-
border-bottom: 1px solid var(--jt-border);
|
|
27
|
-
box-shadow: none;
|
|
28
|
-
}
|
|
29
|
-
.navbar__link--active {
|
|
30
|
-
color: var(--jt-heading);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/* Configuration Reference / index cards (generated-index). Match the clean
|
|
34
|
-
"install box" look — near-page-bg fill + thin border instead of infima's dull
|
|
35
|
-
surface fill — with an accent-border hover. Full description (no one-line
|
|
36
|
-
`text--truncate` clamp) and equal card heights per row. */
|
|
37
|
-
.theme-doc-card-container {
|
|
38
|
-
height: 100%;
|
|
39
|
-
background: var(--jt-code-bg);
|
|
40
|
-
border: 1px solid var(--jt-border);
|
|
41
|
-
border-radius: 14px;
|
|
42
|
-
box-shadow: none;
|
|
43
|
-
transition:
|
|
44
|
-
border-color 0.15s ease,
|
|
45
|
-
background 0.15s ease,
|
|
46
|
-
transform 0.15s ease;
|
|
47
|
-
}
|
|
48
|
-
.theme-doc-card-container:hover {
|
|
49
|
-
background: var(--jt-surface2);
|
|
50
|
-
border-color: var(--jt-accent-border);
|
|
51
|
-
transform: translateY(-2px);
|
|
52
|
-
}
|
|
53
|
-
.theme-doc-card-description.text--truncate {
|
|
54
|
-
white-space: normal;
|
|
55
|
-
overflow: visible;
|
|
56
|
-
text-overflow: unset;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/* ---------- Backgrounds ---------- */
|
|
60
|
-
html,
|
|
61
|
-
body,
|
|
62
|
-
#__docusaurus,
|
|
63
|
-
.main-wrapper {
|
|
64
|
-
background: var(--ifm-background-color);
|
|
65
|
-
}
|
|
66
|
-
/* Sidebar container: match page background, clean 1px right border, and
|
|
67
|
-
ensure a long sidebar list scrolls without clipping the page footer. The
|
|
68
|
-
sticky positioning + bounded height come from Infima defaults; the explicit
|
|
69
|
-
overflow rule here defends against any inner container with overflow: hidden. */
|
|
70
|
-
.theme-doc-sidebar-container {
|
|
71
|
-
background: var(--ifm-background-color) !important;
|
|
72
|
-
border-right: 1px solid var(--jt-border) !important;
|
|
73
|
-
}
|
|
74
|
-
.theme-doc-sidebar-container > div,
|
|
75
|
-
.theme-doc-sidebar-container nav,
|
|
76
|
-
.theme-doc-sidebar-menu,
|
|
77
|
-
.menu,
|
|
78
|
-
.menu__list {
|
|
79
|
-
background: var(--ifm-background-color);
|
|
80
|
-
}
|
|
81
|
-
/* The sticky inner wrapper that holds the scrollable menu list. */
|
|
82
|
-
.theme-doc-sidebar-container > div:first-child {
|
|
83
|
-
height: 100%;
|
|
84
|
-
overflow-y: auto;
|
|
85
|
-
overscroll-behavior: contain;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/* ---------- Sidebar ---------- */
|
|
89
|
-
.menu {
|
|
90
|
-
font-size: 14px;
|
|
91
|
-
background: transparent;
|
|
92
|
-
padding: 16px 12px;
|
|
93
|
-
}
|
|
94
|
-
.menu__list .menu__list {
|
|
95
|
-
padding-left: 8px;
|
|
96
|
-
}
|
|
97
|
-
.menu__link {
|
|
98
|
-
border-radius: 8px;
|
|
99
|
-
color: var(--jt-muted);
|
|
100
|
-
line-height: 1.4;
|
|
101
|
-
}
|
|
102
|
-
.menu__link:hover {
|
|
103
|
-
background: var(--jt-surface2);
|
|
104
|
-
color: var(--jt-heading);
|
|
105
|
-
}
|
|
106
|
-
.menu__link--active:not(.menu__link--sublist) {
|
|
107
|
-
color: var(--jt-accent);
|
|
108
|
-
background: var(--jt-accent-soft);
|
|
109
|
-
font-weight: 600;
|
|
110
|
-
}
|
|
111
|
-
.menu__list-item-collapsible .menu__link {
|
|
112
|
-
font-weight: 600;
|
|
113
|
-
color: var(--jt-heading);
|
|
114
|
-
background: transparent;
|
|
115
|
-
}
|
|
116
|
-
.menu__list-item-collapsible .menu__link--active {
|
|
117
|
-
color: var(--jt-accent);
|
|
118
|
-
background: transparent;
|
|
119
|
-
}
|
|
120
|
-
.menu__list-item-collapsible:hover {
|
|
121
|
-
background: var(--jt-surface2);
|
|
122
|
-
border-radius: 8px;
|
|
123
|
-
}
|
|
124
|
-
.menu__caret:hover {
|
|
125
|
-
background: transparent;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/* ---------- Table of contents ---------- */
|
|
129
|
-
.table-of-contents__link--active {
|
|
130
|
-
color: var(--jt-accent);
|
|
131
|
-
font-weight: 600;
|
|
132
|
-
}
|
|
133
|
-
.table-of-contents .table-of-contents__link:hover {
|
|
134
|
-
color: var(--jt-heading);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/* ---------- Pagination ---------- */
|
|
138
|
-
.pagination-nav__link {
|
|
139
|
-
border: 1px solid var(--jt-border);
|
|
140
|
-
border-radius: 8px;
|
|
141
|
-
background: var(--jt-surface);
|
|
142
|
-
}
|
|
143
|
-
.pagination-nav__link:hover {
|
|
144
|
-
border-color: var(--jt-accent-border);
|
|
145
|
-
background: var(--jt-surface2);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/* ---------- Footer ---------- */
|
|
149
|
-
.footer,
|
|
150
|
-
.footer--dark {
|
|
151
|
-
--ifm-footer-background-color: var(--jt-bg2);
|
|
152
|
-
--ifm-footer-color: var(--jt-text);
|
|
153
|
-
--ifm-footer-link-color: var(--jt-text);
|
|
154
|
-
--ifm-footer-title-color: var(--jt-faint);
|
|
155
|
-
border-top: 1px solid var(--jt-border);
|
|
156
|
-
}
|
|
157
|
-
.footer__title {
|
|
158
|
-
font-size: 12px;
|
|
159
|
-
font-weight: 700;
|
|
160
|
-
letter-spacing: 0.08em;
|
|
161
|
-
text-transform: uppercase;
|
|
162
|
-
color: var(--jt-faint);
|
|
163
|
-
}
|
|
164
|
-
.footer__link-item {
|
|
165
|
-
color: var(--jt-text);
|
|
166
|
-
}
|
|
167
|
-
.footer__link-item:hover {
|
|
168
|
-
color: var(--jt-accent);
|
|
169
|
-
text-decoration: none;
|
|
170
|
-
}
|
|
171
|
-
.footer__copyright {
|
|
172
|
-
color: var(--jt-faint);
|
|
173
|
-
font-size: 13px;
|
|
174
|
-
text-align: left;
|
|
175
|
-
}
|
|
176
|
-
.footer__col {
|
|
177
|
-
font-size: 14px;
|
|
178
|
-
}
|
|
179
|
-
/* Hide the external-link "↗" SVG Docusaurus auto-appends to footer href links —
|
|
180
|
-
the design uses clean text labels only. The class is CSS-module hashed
|
|
181
|
-
(iconExternalLink_<hash>), so we target by attribute prefix. */
|
|
182
|
-
.footer__link-item svg,
|
|
183
|
-
.footer__link-item [class*="iconExternalLink"] {
|
|
184
|
-
display: none;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/* ---------- Code ----------
|
|
188
|
-
Every surface and text colour here comes from the theme tokens, which already
|
|
189
|
-
flip between light and dark — the values that used to be hardcoded (#0c111b,
|
|
190
|
-
#dfe5ee, #94a1b4) were simply the dark side of tokens that existed all along.
|
|
191
|
-
|
|
192
|
-
This pairs with `prism.theme: vsLight` / `prism.darkTheme: vsDark` in
|
|
193
|
-
docusaurus.config.ts. The two must move together (#324): vsDark tokens on a
|
|
194
|
-
light surface are pale and unreadable, which is why the background was pinned
|
|
195
|
-
dark in both modes in the first place. If a fenced block still renders dark in
|
|
196
|
-
light mode, that config is the thing to check. */
|
|
197
|
-
code {
|
|
198
|
-
background: var(--jt-code-bg);
|
|
199
|
-
border: 1px solid var(--jt-border);
|
|
200
|
-
border-radius: 4px;
|
|
201
|
-
padding: 1px 6px;
|
|
202
|
-
font-size: var(--ifm-code-font-size);
|
|
203
|
-
font-family: var(--ifm-font-family-monospace);
|
|
204
|
-
}
|
|
205
|
-
.theme-code-block,
|
|
206
|
-
div[class*="codeBlockContainer"],
|
|
207
|
-
pre[class*="language-"] {
|
|
208
|
-
border: 1px solid var(--jt-border);
|
|
209
|
-
border-radius: 12px;
|
|
210
|
-
/* !important beats the inline background the Prism theme sets on the <pre>. */
|
|
211
|
-
background: var(--jt-code-bg) !important;
|
|
212
|
-
}
|
|
213
|
-
.theme-code-block code,
|
|
214
|
-
pre[class*="language-"] code {
|
|
215
|
-
background: transparent !important;
|
|
216
|
-
border: none !important;
|
|
217
|
-
/* Base colour for anything Prism does not tokenise. */
|
|
218
|
-
color: var(--jt-text);
|
|
219
|
-
}
|
|
220
|
-
div[class*="codeBlockTitle"] {
|
|
221
|
-
background: var(--jt-surface2) !important;
|
|
222
|
-
color: var(--jt-muted) !important;
|
|
223
|
-
border-bottom: 1px solid var(--jt-border);
|
|
224
|
-
}
|
|
225
|
-
/* In dark the title sits a shade *below* the block; in light there is no token
|
|
226
|
-
darker than --jt-code-bg, so the bottom border does the separating instead. */
|
|
227
|
-
[data-theme="dark"] div[class*="codeBlockTitle"] {
|
|
228
|
-
background: var(--jt-bg) !important;
|
|
229
|
-
}
|
|
230
|
-
[data-theme="light"] .theme-code-block,
|
|
231
|
-
[data-theme="light"] div[class*="codeBlockContainer"],
|
|
232
|
-
[data-theme="light"] pre[class*="language-"] {
|
|
233
|
-
border-color: var(--jt-border2);
|
|
234
|
-
box-shadow: 0 8px 24px -18px rgba(12, 18, 28, 0.5);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
/* ---------- Markdown tables ----------
|
|
238
|
-
Rounded container, horizontal row dividers only (no heavy cell gridlines). */
|
|
239
|
-
.markdown table,
|
|
240
|
-
.theme-doc-markdown table,
|
|
241
|
-
article table {
|
|
242
|
-
display: table;
|
|
243
|
-
width: 100%;
|
|
244
|
-
border-collapse: separate;
|
|
245
|
-
border-spacing: 0;
|
|
246
|
-
margin: 22px 0;
|
|
247
|
-
border: 1px solid var(--jt-border);
|
|
248
|
-
border-radius: 12px;
|
|
249
|
-
overflow: hidden;
|
|
250
|
-
font-size: 14px;
|
|
251
|
-
}
|
|
252
|
-
.markdown table thead,
|
|
253
|
-
article table thead {
|
|
254
|
-
background: var(--jt-bg2);
|
|
255
|
-
}
|
|
256
|
-
.markdown table thead tr,
|
|
257
|
-
article table thead tr {
|
|
258
|
-
border: none;
|
|
259
|
-
background: transparent;
|
|
260
|
-
}
|
|
261
|
-
.markdown table th,
|
|
262
|
-
article table th {
|
|
263
|
-
text-align: left;
|
|
264
|
-
font-weight: 700;
|
|
265
|
-
font-size: 12px;
|
|
266
|
-
letter-spacing: 0.06em;
|
|
267
|
-
text-transform: uppercase;
|
|
268
|
-
color: var(--jt-faint);
|
|
269
|
-
border: none;
|
|
270
|
-
border-bottom: 1px solid var(--jt-border);
|
|
271
|
-
padding: 14px 18px;
|
|
272
|
-
}
|
|
273
|
-
.markdown table tbody tr,
|
|
274
|
-
article table tbody tr {
|
|
275
|
-
background: transparent !important;
|
|
276
|
-
border: none;
|
|
277
|
-
}
|
|
278
|
-
.markdown table td,
|
|
279
|
-
article table td {
|
|
280
|
-
border: none;
|
|
281
|
-
border-bottom: 1px solid var(--jt-border);
|
|
282
|
-
padding: 13px 18px;
|
|
283
|
-
vertical-align: middle;
|
|
284
|
-
color: var(--jt-text);
|
|
285
|
-
}
|
|
286
|
-
.markdown table tbody tr:last-child td,
|
|
287
|
-
article table tbody tr:last-child td {
|
|
288
|
-
border-bottom: none;
|
|
289
|
-
}
|
|
290
|
-
.markdown table td:first-child,
|
|
291
|
-
article table td:first-child {
|
|
292
|
-
font-weight: 600;
|
|
293
|
-
color: var(--jt-heading);
|
|
294
|
-
white-space: nowrap;
|
|
295
|
-
}
|
|
296
|
-
.markdown table td code,
|
|
297
|
-
.markdown table th code,
|
|
298
|
-
article table td code {
|
|
299
|
-
background: transparent !important;
|
|
300
|
-
border: none !important;
|
|
301
|
-
padding: 0 !important;
|
|
302
|
-
font-size: 13px;
|
|
303
|
-
}
|
|
304
|
-
.markdown table td:nth-child(2) code,
|
|
305
|
-
article table td:nth-child(2) code {
|
|
306
|
-
color: var(--jt-accent);
|
|
307
|
-
}
|
|
308
|
-
.markdown table td:nth-child(3),
|
|
309
|
-
article table td:nth-child(3) {
|
|
310
|
-
color: var(--jt-muted);
|
|
311
|
-
line-height: 1.9;
|
|
312
|
-
}
|
|
313
|
-
.markdown table td:nth-child(3) code,
|
|
314
|
-
article table td:nth-child(3) code {
|
|
315
|
-
color: var(--jt-muted);
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
/* ---------- Buttons ---------- */
|
|
319
|
-
.button--primary {
|
|
320
|
-
background: var(--jt-accent-fill);
|
|
321
|
-
border-color: var(--jt-accent-fill);
|
|
322
|
-
color: var(--jt-on-accent);
|
|
323
|
-
font-weight: 700;
|
|
324
|
-
}
|
|
325
|
-
.button--primary:hover {
|
|
326
|
-
background: var(--ifm-color-primary-light);
|
|
327
|
-
border-color: var(--ifm-color-primary-light);
|
|
328
|
-
color: var(--jt-on-accent);
|
|
329
|
-
}
|
|
330
|
-
.button--secondary {
|
|
331
|
-
background: transparent;
|
|
332
|
-
border-color: var(--jt-border2);
|
|
333
|
-
color: var(--jt-heading);
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
/* ============================================================
|
|
337
|
-
HARDENED DARK SURFACES
|
|
338
|
-
Infima's dark defaults are grey (#1b1b1d) and the footer is
|
|
339
|
-
slate. These explicit overrides force the navy palette even
|
|
340
|
-
if a default loads after this file.
|
|
341
|
-
============================================================ */
|
|
342
|
-
[data-theme="dark"] {
|
|
343
|
-
--ifm-background-color: #0a0e16;
|
|
344
|
-
--ifm-background-surface-color: #111824;
|
|
345
|
-
--ifm-navbar-background-color: #0a0e16;
|
|
346
|
-
--ifm-footer-background-color: #0b101a;
|
|
347
|
-
}
|
|
348
|
-
[data-theme="dark"],
|
|
349
|
-
[data-theme="dark"] body,
|
|
350
|
-
[data-theme="dark"] #__docusaurus,
|
|
351
|
-
[data-theme="dark"] .main-wrapper,
|
|
352
|
-
[data-theme="dark"] .navbar,
|
|
353
|
-
[data-theme="dark"] main {
|
|
354
|
-
background-color: #0a0e16;
|
|
355
|
-
}
|
|
356
|
-
/* Footer follows the theme: soft grey panel in light mode, page-matching navy
|
|
357
|
-
in dark mode. Selectors are theme-scoped so the config's `style: 'dark'`
|
|
358
|
-
(which adds .footer--dark in BOTH modes) can't drag the light-mode footer
|
|
359
|
-
into a dark slate. */
|
|
360
|
-
html[data-theme="light"] .footer,
|
|
361
|
-
html[data-theme="light"] .footer--dark {
|
|
362
|
-
background-color: var(--jt-bg2) !important;
|
|
363
|
-
border-top: 1px solid var(--jt-border);
|
|
364
|
-
}
|
|
365
|
-
html[data-theme="light"] .footer__link-item {
|
|
366
|
-
color: var(--jt-text) !important;
|
|
367
|
-
}
|
|
368
|
-
html[data-theme="light"] .footer__title {
|
|
369
|
-
color: var(--jt-faint) !important;
|
|
370
|
-
}
|
|
371
|
-
html[data-theme="light"] .footer__copyright {
|
|
372
|
-
color: var(--jt-faint) !important;
|
|
373
|
-
}
|
|
374
|
-
html[data-theme="dark"] .footer,
|
|
375
|
-
html[data-theme="dark"] .footer--dark {
|
|
376
|
-
background-color: #0a0e16 !important;
|
|
377
|
-
border-top: 1px solid var(--jt-border);
|
|
378
|
-
}
|
|
379
|
-
html[data-theme="dark"] .footer__link-item {
|
|
380
|
-
color: var(--jt-text) !important;
|
|
381
|
-
}
|
|
382
|
-
html[data-theme="dark"] .footer__title {
|
|
383
|
-
color: var(--jt-faint) !important;
|
|
384
|
-
}
|
|
385
|
-
html[data-theme="dark"] .footer__copyright {
|
|
386
|
-
color: var(--jt-faint) !important;
|
|
387
|
-
}
|
|
388
|
-
.footer__link-item:hover {
|
|
389
|
-
color: var(--jt-accent) !important;
|
|
390
|
-
}
|