jamdesk 1.1.211 → 1.1.213
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/__tests__/unit/deploy.test.js +13 -0
- package/dist/__tests__/unit/deploy.test.js.map +1 -1
- package/dist/__tests__/unit/docs-config.test.js +26 -0
- package/dist/__tests__/unit/docs-config.test.js.map +1 -1
- package/dist/__tests__/unit/dusk-embargo.test.d.ts +2 -0
- package/dist/__tests__/unit/dusk-embargo.test.d.ts.map +1 -0
- package/dist/__tests__/unit/dusk-embargo.test.js +25 -0
- package/dist/__tests__/unit/dusk-embargo.test.js.map +1 -0
- package/dist/__tests__/unit/migrate-resolve-theme.test.js +11 -0
- package/dist/__tests__/unit/migrate-resolve-theme.test.js.map +1 -1
- package/dist/commands/deploy.js +4 -4
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/migrate/index.d.ts.map +1 -1
- package/dist/commands/migrate/index.js +7 -3
- package/dist/commands/migrate/index.js.map +1 -1
- package/dist/commands/migrate/types.d.ts +4 -1
- package/dist/commands/migrate/types.d.ts.map +1 -1
- package/dist/commands/migrate/types.js +13 -1
- package/dist/commands/migrate/types.js.map +1 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/docs-config.d.ts +1 -1
- package/dist/lib/docs-config.d.ts.map +1 -1
- package/dist/lib/docs-config.js +1 -1
- package/dist/lib/docs-config.js.map +1 -1
- package/dist/lib/dusk-embargo.d.ts +15 -0
- package/dist/lib/dusk-embargo.d.ts.map +1 -0
- package/dist/lib/dusk-embargo.js +15 -0
- package/dist/lib/dusk-embargo.js.map +1 -0
- package/dist/lib/normalize-config.js +1 -1
- package/dist/lib/normalize-config.js.map +1 -1
- package/package.json +1 -1
- package/vendored/app/(unlock)/jd/unlock/page.tsx +2 -2
- package/vendored/components/layout/LayoutWrapper.tsx +7 -3
- package/vendored/components/navigation/DefaultLogo.tsx +25 -18
- package/vendored/components/navigation/Header.tsx +78 -29
- package/vendored/components/navigation/Sidebar.tsx +5 -3
- package/vendored/components/navigation/SocialFooter.tsx +5 -6
- package/vendored/components/navigation/ThemePreviewChips.tsx +3 -2
- package/vendored/lib/branding-url.ts +9 -0
- package/vendored/lib/build/error-parser.ts +1 -1
- package/vendored/lib/docs-types.ts +5 -1
- package/vendored/lib/dusk-embargo.ts +16 -0
- package/vendored/lib/extract-highlights.ts +1 -1
- package/vendored/lib/layout-helpers.tsx +19 -2
- package/vendored/lib/normalize-config.ts +1 -1
- package/vendored/lib/r2-cleanup.ts +14 -10
- package/vendored/lib/static-artifacts.ts +84 -30
- package/vendored/lib/static-file-route.ts +8 -7
- package/vendored/lib/theme-preview.ts +16 -8
- package/vendored/lib/validate-config.ts +4 -4
- package/vendored/schema/docs-schema.json +124 -0
- package/vendored/themes/dusk/variables.css +426 -0
- package/vendored/themes/index.ts +28 -0
- package/vendored/themes/jam/variables.css +6 -5
- package/vendored/themes/nebula/variables.css +1 -1
- package/vendored/themes/pulsar/variables.css +4 -3
- package/vendored/themes/types.ts +8 -0
- package/vendored/workspace-package-lock.json +9 -9
|
@@ -2124,6 +2124,130 @@
|
|
|
2124
2124
|
"navigation"
|
|
2125
2125
|
],
|
|
2126
2126
|
"additionalProperties": false
|
|
2127
|
+
},
|
|
2128
|
+
{
|
|
2129
|
+
"type": "object",
|
|
2130
|
+
"properties": {
|
|
2131
|
+
"theme": {
|
|
2132
|
+
"type": "string",
|
|
2133
|
+
"const": "dusk"
|
|
2134
|
+
},
|
|
2135
|
+
"$schema": {
|
|
2136
|
+
"$ref": "#/anyOf/0/properties/$schema"
|
|
2137
|
+
},
|
|
2138
|
+
"projectId": {
|
|
2139
|
+
"$ref": "#/anyOf/0/properties/projectId"
|
|
2140
|
+
},
|
|
2141
|
+
"name": {
|
|
2142
|
+
"$ref": "#/anyOf/0/properties/name"
|
|
2143
|
+
},
|
|
2144
|
+
"description": {
|
|
2145
|
+
"$ref": "#/anyOf/0/properties/description"
|
|
2146
|
+
},
|
|
2147
|
+
"colors": {
|
|
2148
|
+
"$ref": "#/definitions/colorsSchema"
|
|
2149
|
+
},
|
|
2150
|
+
"logo": {
|
|
2151
|
+
"$ref": "#/anyOf/0/properties/logo"
|
|
2152
|
+
},
|
|
2153
|
+
"favicon": {
|
|
2154
|
+
"$ref": "#/anyOf/0/properties/favicon"
|
|
2155
|
+
},
|
|
2156
|
+
"api": {
|
|
2157
|
+
"$ref": "#/anyOf/0/properties/api"
|
|
2158
|
+
},
|
|
2159
|
+
"appearance": {
|
|
2160
|
+
"$ref": "#/anyOf/0/properties/appearance"
|
|
2161
|
+
},
|
|
2162
|
+
"background": {
|
|
2163
|
+
"$ref": "#/anyOf/0/properties/background"
|
|
2164
|
+
},
|
|
2165
|
+
"navbar": {
|
|
2166
|
+
"$ref": "#/anyOf/0/properties/navbar"
|
|
2167
|
+
},
|
|
2168
|
+
"tabsPosition": {
|
|
2169
|
+
"$ref": "#/anyOf/0/properties/tabsPosition"
|
|
2170
|
+
},
|
|
2171
|
+
"anchors": {
|
|
2172
|
+
"$ref": "#/anyOf/0/properties/anchors"
|
|
2173
|
+
},
|
|
2174
|
+
"navigation": {
|
|
2175
|
+
"$ref": "#/definitions/navigationSchema"
|
|
2176
|
+
},
|
|
2177
|
+
"footer": {
|
|
2178
|
+
"$ref": "#/anyOf/0/properties/footer"
|
|
2179
|
+
},
|
|
2180
|
+
"search": {
|
|
2181
|
+
"$ref": "#/anyOf/0/properties/search"
|
|
2182
|
+
},
|
|
2183
|
+
"seo": {
|
|
2184
|
+
"$ref": "#/anyOf/0/properties/seo"
|
|
2185
|
+
},
|
|
2186
|
+
"fonts": {
|
|
2187
|
+
"$ref": "#/anyOf/0/properties/fonts"
|
|
2188
|
+
},
|
|
2189
|
+
"icons": {
|
|
2190
|
+
"$ref": "#/anyOf/0/properties/icons"
|
|
2191
|
+
},
|
|
2192
|
+
"styling": {
|
|
2193
|
+
"$ref": "#/anyOf/0/properties/styling"
|
|
2194
|
+
},
|
|
2195
|
+
"redirects": {
|
|
2196
|
+
"$ref": "#/anyOf/0/properties/redirects",
|
|
2197
|
+
"description": "URL redirect rules for your documentation site. Each redirect maps a source path to a destination URL"
|
|
2198
|
+
},
|
|
2199
|
+
"integrations": {
|
|
2200
|
+
"$ref": "#/anyOf/0/properties/integrations"
|
|
2201
|
+
},
|
|
2202
|
+
"banner": {
|
|
2203
|
+
"$ref": "#/anyOf/0/properties/banner"
|
|
2204
|
+
},
|
|
2205
|
+
"errors": {
|
|
2206
|
+
"$ref": "#/anyOf/0/properties/errors"
|
|
2207
|
+
},
|
|
2208
|
+
"contextual": {
|
|
2209
|
+
"$ref": "#/anyOf/0/properties/contextual"
|
|
2210
|
+
},
|
|
2211
|
+
"thumbnails": {
|
|
2212
|
+
"$ref": "#/anyOf/0/properties/thumbnails"
|
|
2213
|
+
},
|
|
2214
|
+
"interaction": {
|
|
2215
|
+
"$ref": "#/anyOf/0/properties/interaction"
|
|
2216
|
+
},
|
|
2217
|
+
"metadata": {
|
|
2218
|
+
"$ref": "#/anyOf/0/properties/metadata"
|
|
2219
|
+
},
|
|
2220
|
+
"localization": {
|
|
2221
|
+
"$ref": "#/anyOf/0/properties/localization"
|
|
2222
|
+
},
|
|
2223
|
+
"chat": {
|
|
2224
|
+
"$ref": "#/anyOf/0/properties/chat"
|
|
2225
|
+
},
|
|
2226
|
+
"analytics": {
|
|
2227
|
+
"$ref": "#/anyOf/0/properties/analytics"
|
|
2228
|
+
},
|
|
2229
|
+
"modeToggle": {
|
|
2230
|
+
"$ref": "#/anyOf/0/properties/modeToggle"
|
|
2231
|
+
},
|
|
2232
|
+
"layout": {
|
|
2233
|
+
"$ref": "#/anyOf/0/properties/layout"
|
|
2234
|
+
},
|
|
2235
|
+
"spellcheck": {
|
|
2236
|
+
"$ref": "#/anyOf/0/properties/spellcheck"
|
|
2237
|
+
},
|
|
2238
|
+
"auth": {
|
|
2239
|
+
"$ref": "#/anyOf/0/properties/auth"
|
|
2240
|
+
},
|
|
2241
|
+
"images": {
|
|
2242
|
+
"$ref": "#/anyOf/0/properties/images"
|
|
2243
|
+
}
|
|
2244
|
+
},
|
|
2245
|
+
"required": [
|
|
2246
|
+
"theme",
|
|
2247
|
+
"name",
|
|
2248
|
+
"navigation"
|
|
2249
|
+
],
|
|
2250
|
+
"additionalProperties": false
|
|
2127
2251
|
}
|
|
2128
2252
|
],
|
|
2129
2253
|
"definitions": {
|
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dusk Theme - CSS Variables
|
|
3
|
+
* Quiet and flat: header, sidebar and content share one tinted ground,
|
|
4
|
+
* separated by 1px borders instead of surface steps. Ink blue accent,
|
|
5
|
+
* Inter body, IBM Plex Serif H1.
|
|
6
|
+
*
|
|
7
|
+
* ARCHITECTURE NOTE: app/globals.css unconditionally @imports jam/variables.css,
|
|
8
|
+
* so Dusk inherits jam's :root — the --prose-* size ladder, the nav/code/UI
|
|
9
|
+
* typography tokens and jam's unscoped mobile rules. This file is injected as a
|
|
10
|
+
* <style> AFTER the globals bundle, so these :root rules win on source order at
|
|
11
|
+
* equal specificity.
|
|
12
|
+
*
|
|
13
|
+
* SPACING NOTE: Dusk uses jam's production spacing. Every spacing rule below is
|
|
14
|
+
* copied from jam/variables.css and re-scoped to dusk — jam scopes its own
|
|
15
|
+
* copies to body[data-theme="jam"], so without these the sidebar gaps, group
|
|
16
|
+
* margins and column alignment would fall back to bare base.css. Change color,
|
|
17
|
+
* type, radius and surfaces here; do not tune spacing.
|
|
18
|
+
*
|
|
19
|
+
* FONT NOTE: never write the serif family by name. next/font self-hosts it
|
|
20
|
+
* under a mangled family (__IBM_Plex_Serif_xxx) exposed as --font-serif on
|
|
21
|
+
* <body> (lib/layout-helpers.tsx); a literal name silently misses.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
:root {
|
|
25
|
+
/* Radius — restrained, about half of Halo's. */
|
|
26
|
+
--radius-sm: 0.25rem; /* 4px — badges */
|
|
27
|
+
--radius-md: 0.375rem; /* 6px — nav items, buttons */
|
|
28
|
+
--radius-lg: 0.5rem; /* 8px — cards, tables, callouts, inline code */
|
|
29
|
+
--radius-xl: 0.75rem; /* 12px — code panels, modals */
|
|
30
|
+
--radius-2xl: 1rem; /* 16px */
|
|
31
|
+
--radius-full: 9999px;
|
|
32
|
+
|
|
33
|
+
/* Light — one ground for body, header, sidebar and main. Every text token
|
|
34
|
+
is solved against it for the contrast floors pinned in
|
|
35
|
+
__tests__/dusk-theme-gate.test.ts. */
|
|
36
|
+
--color-bg-primary: #F1F2F3;
|
|
37
|
+
--color-bg-secondary: #EBECEF; /* inline code, table header */
|
|
38
|
+
--color-bg-tertiary: #E5E7EB; /* fenced code */
|
|
39
|
+
--color-bg-hover: #E5E7EB;
|
|
40
|
+
|
|
41
|
+
--color-border: #D4D7DD;
|
|
42
|
+
--color-border-hover: #C6CBD3;
|
|
43
|
+
--border-width: 1px;
|
|
44
|
+
|
|
45
|
+
--color-text-primary: #1A1D22; /* 15.1:1 */
|
|
46
|
+
--color-text-secondary: #3C424C; /* 9.0:1 */
|
|
47
|
+
--color-text-tertiary: #515A67; /* 6.2:1 */
|
|
48
|
+
--color-text-muted: #616B7B; /* 4.8:1 */
|
|
49
|
+
--color-marker: #7D8899; /* 3.2:1 — decorative only */
|
|
50
|
+
|
|
51
|
+
--color-accent: #2158A1; /* white label 7.1:1, 6.3:1 as text */
|
|
52
|
+
--color-accent-hover: #1B4984;
|
|
53
|
+
--color-accent-light: #E4EBF5;
|
|
54
|
+
--color-accent-text: #26528D; /* 7.0:1 */
|
|
55
|
+
|
|
56
|
+
/* Primary is ONLY emitted when a project sets colors.primary — there is no
|
|
57
|
+
global default. Without this alias the TOC scroll thumb, active TOC links,
|
|
58
|
+
step chips, Card icons and li::marker compute to transparent and vanish.
|
|
59
|
+
A project's colors.primary still wins: its style block is injected after
|
|
60
|
+
this file. See halo/variables.css for the full reasoning. */
|
|
61
|
+
--color-primary: var(--color-accent);
|
|
62
|
+
--color-primary-dark: var(--color-accent-hover);
|
|
63
|
+
|
|
64
|
+
--color-code-bg: #E5E7EB;
|
|
65
|
+
--color-code-border: #D4D7DD;
|
|
66
|
+
--color-code-text: #1A1D22;
|
|
67
|
+
|
|
68
|
+
/* Callouts — note carries the accent; info is neutral so the two blues
|
|
69
|
+
never sit side by side. Every text color clears 6:1 on its own tint. */
|
|
70
|
+
--color-note-bg: #E4EBF5;
|
|
71
|
+
--color-note-border: #C9D7EB;
|
|
72
|
+
--color-note-text: #26528D;
|
|
73
|
+
|
|
74
|
+
--color-info-bg: #EBECEF;
|
|
75
|
+
--color-info-border: #D4D7DD;
|
|
76
|
+
--color-info-text: #3C424C;
|
|
77
|
+
|
|
78
|
+
--color-warning-bg: #FFF7C2;
|
|
79
|
+
--color-warning-border: #F3D673;
|
|
80
|
+
--color-warning-text: #895000;
|
|
81
|
+
|
|
82
|
+
--color-error-bg: #FEEBEC;
|
|
83
|
+
--color-error-border: #FDBDBE;
|
|
84
|
+
--color-error-text: #AC2529;
|
|
85
|
+
|
|
86
|
+
--color-success-bg: #E9F6E9;
|
|
87
|
+
--color-success-border: #B2DDB5;
|
|
88
|
+
--color-success-text: #236832;
|
|
89
|
+
|
|
90
|
+
/* Same page box and item rhythm as jam. */
|
|
91
|
+
--layout-max-width: 1472px;
|
|
92
|
+
--sidebar-item-spacing: 4px;
|
|
93
|
+
|
|
94
|
+
/* Active sidebar item. A blue wash rather than --color-accent-light, which
|
|
95
|
+
is a callout tint and sits too close to the ground to read as a state. */
|
|
96
|
+
--dusk-nav-active-bg: #DCE5F2;
|
|
97
|
+
|
|
98
|
+
/* Flat. Restated rather than inherited so the intent is on the page. */
|
|
99
|
+
--shadow-sm: none;
|
|
100
|
+
--shadow-md: none;
|
|
101
|
+
--shadow-lg: none;
|
|
102
|
+
--shadow-xl: none;
|
|
103
|
+
--shadow-2xl: none;
|
|
104
|
+
|
|
105
|
+
/* Weights only — sizes come from jam's ladder. Body is 400, not jam's 300:
|
|
106
|
+
a thin weight undoes the contrast the grays above are tuned for. */
|
|
107
|
+
--prose-h1-weight: 600;
|
|
108
|
+
--prose-h2-weight: 600;
|
|
109
|
+
--prose-h3-weight: 600;
|
|
110
|
+
--prose-h4-weight: 600;
|
|
111
|
+
--prose-body-weight: 400;
|
|
112
|
+
--nav-page-weight: 400;
|
|
113
|
+
--nav-page-active-weight: 500;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.dark {
|
|
117
|
+
--color-bg-primary: #0F1318;
|
|
118
|
+
--color-bg-secondary: #1B1F23;
|
|
119
|
+
--color-bg-tertiary: #22262B;
|
|
120
|
+
--color-bg-hover: #22262B;
|
|
121
|
+
|
|
122
|
+
--color-border: #333942;
|
|
123
|
+
--color-border-hover: #3E444E;
|
|
124
|
+
|
|
125
|
+
--color-text-primary: #E4E7EA; /* 15.0:1 */
|
|
126
|
+
--color-text-secondary: #B8BFC7; /* 10.0:1 */
|
|
127
|
+
--color-text-tertiary: #909AA7; /* 6.5:1 */
|
|
128
|
+
--color-text-muted: #768394; /* 4.8:1 */
|
|
129
|
+
--color-marker: #5C6674; /* 3.2:1 */
|
|
130
|
+
|
|
131
|
+
/* The accent is used as TEXT in ~38 components as well as a fill, so in
|
|
132
|
+
dark it has to read on the ground (5.0:1). White on it lands at 3.7:1,
|
|
133
|
+
the same trade jam's dark #3b82f6 makes. Links use --color-accent-text. */
|
|
134
|
+
--color-accent: #4A86D4;
|
|
135
|
+
--color-accent-hover: #6A9BDB;
|
|
136
|
+
--color-accent-light: #11253F;
|
|
137
|
+
--color-accent-text: #88ADDC; /* 8.0:1 */
|
|
138
|
+
|
|
139
|
+
--color-code-bg: #22262B;
|
|
140
|
+
--color-code-border: #333942;
|
|
141
|
+
--color-code-text: #E4E7EA;
|
|
142
|
+
|
|
143
|
+
--color-note-bg: #11253F;
|
|
144
|
+
--color-note-border: #1F4475;
|
|
145
|
+
--color-note-text: #88ADDC;
|
|
146
|
+
|
|
147
|
+
--color-info-bg: #1B1F23;
|
|
148
|
+
--color-info-border: #333942;
|
|
149
|
+
--color-info-text: #B8BFC7;
|
|
150
|
+
|
|
151
|
+
--color-warning-bg: #302008;
|
|
152
|
+
--color-warning-border: #5C3D05;
|
|
153
|
+
--color-warning-text: #CB9800;
|
|
154
|
+
|
|
155
|
+
--color-error-bg: #3B1219;
|
|
156
|
+
--color-error-border: #72232D;
|
|
157
|
+
--color-error-text: #FF6F6A;
|
|
158
|
+
|
|
159
|
+
--color-success-bg: #1B2A1E;
|
|
160
|
+
--color-success-border: #2D5736;
|
|
161
|
+
--color-success-text: #3EBB53;
|
|
162
|
+
|
|
163
|
+
--dusk-nav-active-bg: #152E4E;
|
|
164
|
+
|
|
165
|
+
--shadow-sm: none;
|
|
166
|
+
--shadow-md: none;
|
|
167
|
+
--shadow-lg: none;
|
|
168
|
+
--shadow-xl: none;
|
|
169
|
+
--shadow-2xl: none;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/* ===== TYPOGRAPHY ===== */
|
|
173
|
+
/* REQUIRED, not polish: base.css hardcodes `.prose h1..h6 { font-weight: 600 }`
|
|
174
|
+
and every --prose-* consumer is scoped to one theme, so without this block
|
|
175
|
+
the ladder is dead CSS and h1 falls back to base.css's raw 2.25rem. */
|
|
176
|
+
body[data-theme="dusk"] .prose {
|
|
177
|
+
font-family: var(--font-sans, var(--font-primary, 'Inter')), sans-serif;
|
|
178
|
+
font-size: var(--prose-body-size);
|
|
179
|
+
line-height: var(--prose-body-line-height);
|
|
180
|
+
font-weight: var(--prose-body-weight);
|
|
181
|
+
letter-spacing: var(--prose-body-tracking);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/* The serif H1. The bare `h1` is required: the page title renders outside
|
|
185
|
+
.prose. A customer heading font (--font-heading, from docs.json fonts)
|
|
186
|
+
still wins; otherwise the theme serif. --font-serif is set on <body> by
|
|
187
|
+
next/font, so this must stay scoped to body, never :root. */
|
|
188
|
+
body[data-theme="dusk"] .prose h1,
|
|
189
|
+
body[data-theme="dusk"] h1 {
|
|
190
|
+
font-family: var(--font-heading, var(--font-serif)), 'Times New Roman', serif;
|
|
191
|
+
font-size: var(--prose-h1-size);
|
|
192
|
+
line-height: var(--prose-h1-line-height);
|
|
193
|
+
font-weight: var(--prose-h1-weight);
|
|
194
|
+
letter-spacing: -0.01em;
|
|
195
|
+
color: var(--color-text-primary);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
body[data-theme="dusk"] .prose h2 {
|
|
199
|
+
font-family: var(--font-heading, var(--font-sans, var(--font-primary, 'Inter'))), sans-serif;
|
|
200
|
+
font-size: var(--prose-h2-size);
|
|
201
|
+
line-height: var(--prose-h2-line-height);
|
|
202
|
+
font-weight: var(--prose-h2-weight);
|
|
203
|
+
letter-spacing: var(--prose-h2-tracking);
|
|
204
|
+
color: var(--color-text-primary);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
body[data-theme="dusk"] .prose h3 {
|
|
208
|
+
font-family: var(--font-heading, var(--font-sans, var(--font-primary, 'Inter'))), sans-serif;
|
|
209
|
+
font-size: var(--prose-h3-size);
|
|
210
|
+
line-height: var(--prose-h3-line-height);
|
|
211
|
+
font-weight: var(--prose-h3-weight);
|
|
212
|
+
letter-spacing: var(--prose-h3-tracking);
|
|
213
|
+
color: var(--color-text-primary);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
body[data-theme="dusk"] .prose h4 {
|
|
217
|
+
font-family: var(--font-heading, var(--font-sans, var(--font-primary, 'Inter'))), sans-serif;
|
|
218
|
+
font-size: var(--prose-h4-size);
|
|
219
|
+
line-height: var(--prose-h4-line-height);
|
|
220
|
+
font-weight: var(--prose-h4-weight);
|
|
221
|
+
letter-spacing: var(--prose-h4-tracking);
|
|
222
|
+
color: var(--color-text-primary);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/* Inline code — jam's padding, Dusk's surface. */
|
|
226
|
+
body[data-theme="dusk"] .prose code:not([class*="language-"]) {
|
|
227
|
+
background-color: var(--color-bg-secondary);
|
|
228
|
+
color: var(--color-code-text);
|
|
229
|
+
padding: 0.125rem 0.375rem;
|
|
230
|
+
border-radius: var(--radius-sm);
|
|
231
|
+
font-size: var(--code-inline-size);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/* Untitled code blocks have no CodePanel border of their own. */
|
|
235
|
+
body[data-theme="dusk"] .prose pre.shiki {
|
|
236
|
+
border: var(--border-width) solid var(--color-code-border);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
body[data-theme="dusk"] .prose table {
|
|
240
|
+
border-radius: var(--radius-lg);
|
|
241
|
+
overflow: hidden;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
body[data-theme="dusk"] .prose hr,
|
|
245
|
+
body[data-theme="dusk"] hr {
|
|
246
|
+
border: none;
|
|
247
|
+
border-top: var(--border-width) solid var(--color-border);
|
|
248
|
+
margin: 2rem 0;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/* ===== HEADER ===== */
|
|
252
|
+
/* The header-logo <header> has no border of its own. Same construction as
|
|
253
|
+
nebula's divider (see its comment for the inset math), at Dusk's 1px. */
|
|
254
|
+
body[data-theme="dusk"] header[data-has-tabs]::after {
|
|
255
|
+
content: '';
|
|
256
|
+
position: absolute;
|
|
257
|
+
left: -1rem;
|
|
258
|
+
right: -1rem;
|
|
259
|
+
bottom: 0;
|
|
260
|
+
height: 1px;
|
|
261
|
+
background-color: var(--color-border);
|
|
262
|
+
pointer-events: none;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
@media (min-width: 1024px) {
|
|
266
|
+
body[data-theme="dusk"] header[data-has-tabs]::after {
|
|
267
|
+
left: -1.5rem;
|
|
268
|
+
right: -1.5rem;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/* ===== SIDEBAR (jam's spacing, re-scoped) ===== */
|
|
273
|
+
/* The sidebar keeps base's border-r — Dusk separates with borders, so unlike
|
|
274
|
+
jam and halo it does not remove it. */
|
|
275
|
+
|
|
276
|
+
body[data-theme="dusk"] [data-nav-anchor] {
|
|
277
|
+
padding: 0 0 16px 0;
|
|
278
|
+
position: relative;
|
|
279
|
+
margin-left: 24px;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
body[data-theme="dusk"] [data-nav-anchor]:first-of-type {
|
|
283
|
+
margin-top: 30px;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
body[data-theme="dusk"] [data-nav-anchor]::before {
|
|
287
|
+
content: '';
|
|
288
|
+
position: absolute;
|
|
289
|
+
top: -8px;
|
|
290
|
+
left: -12px;
|
|
291
|
+
right: 24px;
|
|
292
|
+
bottom: 8px;
|
|
293
|
+
border-radius: var(--radius-md);
|
|
294
|
+
background-color: transparent;
|
|
295
|
+
transition: background-color 0.2s;
|
|
296
|
+
z-index: -1;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
body[data-theme="dusk"] [data-nav-anchor][data-active="false"]:hover::before {
|
|
300
|
+
background-color: var(--color-bg-hover);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
body[data-theme="dusk"] .sidebar-scroll ul li a,
|
|
304
|
+
body[data-theme="dusk"] .sidebar-scroll .nav-group-l1 {
|
|
305
|
+
position: relative;
|
|
306
|
+
font-weight: var(--nav-page-weight) !important;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/* The highlight is a z-index:-1 pseudo-element inset from the link box, so it
|
|
310
|
+
can bleed left of the text without shifting layout — jam's geometry. */
|
|
311
|
+
body[data-theme="dusk"] .sidebar-scroll ul li a::before,
|
|
312
|
+
body[data-theme="dusk"] .sidebar-scroll .nav-group-l1::before {
|
|
313
|
+
content: '';
|
|
314
|
+
position: absolute;
|
|
315
|
+
top: 0;
|
|
316
|
+
left: -12px;
|
|
317
|
+
right: 16px;
|
|
318
|
+
bottom: 0;
|
|
319
|
+
border-radius: var(--radius-md);
|
|
320
|
+
background-color: transparent;
|
|
321
|
+
z-index: -1;
|
|
322
|
+
transition: background-color 0.15s;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
body[data-theme="dusk"] .sidebar-scroll ul li a {
|
|
326
|
+
padding-right: 24px !important;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
body[data-theme="dusk"] .sidebar-scroll ul li a:hover::before,
|
|
330
|
+
body[data-theme="dusk"] .sidebar-scroll .nav-group-l1:hover::before {
|
|
331
|
+
background-color: var(--color-bg-hover);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
body[data-theme="dusk"] .sidebar-scroll ul li a.nav-active::before {
|
|
335
|
+
background-color: var(--dusk-nav-active-bg);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
body[data-theme="dusk"] .sidebar-scroll ul li a.nav-active {
|
|
339
|
+
color: var(--color-text-primary) !important;
|
|
340
|
+
font-weight: var(--nav-page-active-weight) !important;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
body[data-theme="dusk"] .nav-tab-link,
|
|
344
|
+
body[data-theme="dusk"] .toc-link,
|
|
345
|
+
body[data-theme="dusk"] .toc-link-bg {
|
|
346
|
+
border-radius: var(--radius-md) !important;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
@media (min-width: 1024px) {
|
|
350
|
+
body[data-theme="dusk"] .sidebar-tabs {
|
|
351
|
+
padding-top: calc(2rem + 4px) !important;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
body[data-theme="dusk"] .sidebar-scroll .sidebar-nav-groups {
|
|
356
|
+
display: flex !important;
|
|
357
|
+
flex-direction: column !important;
|
|
358
|
+
gap: var(--sidebar-item-spacing) !important;
|
|
359
|
+
padding-top: 16px !important;
|
|
360
|
+
padding-bottom: 2rem !important;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
body[data-theme="dusk"] .sidebar-scroll .sidebar-nav-groups > div {
|
|
364
|
+
display: flex !important;
|
|
365
|
+
flex-direction: column !important;
|
|
366
|
+
gap: var(--sidebar-item-spacing) !important;
|
|
367
|
+
margin-top: 24px !important;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
body[data-theme="dusk"] .sidebar-scroll .sidebar-nav-groups > div:first-child {
|
|
371
|
+
margin-top: 0 !important;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
@media (min-width: 1024px) {
|
|
375
|
+
body[data-theme="dusk"] .sidebar-scroll nav > .sidebar-nav-groups:first-child {
|
|
376
|
+
padding-top: 2.5rem !important;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/* Height cap — REQUIRED for a tall nav to scroll. Fill the layout row rather
|
|
381
|
+
than measuring 100vh minus a hardcoded header (theme-sidebar-height.test.ts
|
|
382
|
+
fails the old calc form). Pairs with `lg:max-h-full` on the <aside>. */
|
|
383
|
+
@media (min-width: 1024px) {
|
|
384
|
+
body[data-theme="dusk"] .sidebar-scroll {
|
|
385
|
+
position: sticky !important;
|
|
386
|
+
top: 0 !important;
|
|
387
|
+
flex: 1 1 auto !important;
|
|
388
|
+
min-height: 0 !important;
|
|
389
|
+
max-height: none !important;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
body[data-theme="dusk"] .sidebar-scroll ul {
|
|
394
|
+
display: flex !important;
|
|
395
|
+
flex-direction: column !important;
|
|
396
|
+
gap: var(--sidebar-item-spacing) !important;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
body[data-theme="dusk"] .sidebar-scroll nav div div {
|
|
400
|
+
display: flex !important;
|
|
401
|
+
flex-direction: column !important;
|
|
402
|
+
gap: var(--sidebar-item-spacing) !important;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/* ===== CODE PANELS ===== */
|
|
406
|
+
/* Every theme must pad this — base.css gives it none (REFERENCE.md
|
|
407
|
+
#per-theme-code-panel-gutter-invariant). jam's value. */
|
|
408
|
+
@media (min-width: 1024px) {
|
|
409
|
+
body[data-theme="dusk"] .code-panels-sidebar {
|
|
410
|
+
padding-right: 16px;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/* ===== MOBILE ===== */
|
|
415
|
+
@media (max-width: 1023px) {
|
|
416
|
+
body[data-theme="dusk"] header[data-has-tabs] > div {
|
|
417
|
+
margin: 0 !important;
|
|
418
|
+
padding-left: 0.5rem;
|
|
419
|
+
padding-right: 0.5rem;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
body[data-theme="dusk"] #main-content article {
|
|
423
|
+
padding-left: 0.5rem !important;
|
|
424
|
+
padding-right: 0.5rem !important;
|
|
425
|
+
}
|
|
426
|
+
}
|
package/vendored/themes/index.ts
CHANGED
|
@@ -100,12 +100,40 @@ const haloTheme: ThemeConfig = {
|
|
|
100
100
|
cssPath: 'halo/variables.css',
|
|
101
101
|
};
|
|
102
102
|
|
|
103
|
+
const duskTheme: ThemeConfig = {
|
|
104
|
+
name: 'dusk',
|
|
105
|
+
displayName: 'Dusk',
|
|
106
|
+
description: 'Quiet and flat — one calm surface, clear borders, high-contrast text and a serif title',
|
|
107
|
+
layout: 'header-logo',
|
|
108
|
+
defaultTabsPosition: 'left',
|
|
109
|
+
fonts: {
|
|
110
|
+
// Matches jam's own Inter config — jam is the source of truth for Inter.
|
|
111
|
+
primary: {
|
|
112
|
+
family: 'Inter',
|
|
113
|
+
googleFontUrl: 'https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap',
|
|
114
|
+
fallback: 'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
115
|
+
},
|
|
116
|
+
mono: {
|
|
117
|
+
family: 'JetBrains Mono',
|
|
118
|
+
googleFontUrl: 'https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&display=swap',
|
|
119
|
+
fallback: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace',
|
|
120
|
+
},
|
|
121
|
+
heading: {
|
|
122
|
+
family: 'IBM Plex Serif',
|
|
123
|
+
googleFontUrl: 'https://fonts.googleapis.com/css2?family=IBM+Plex+Serif:wght@400;600&display=swap',
|
|
124
|
+
fallback: "'Times New Roman', serif",
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
cssPath: 'dusk/variables.css',
|
|
128
|
+
};
|
|
129
|
+
|
|
103
130
|
// Theme registry
|
|
104
131
|
const themes: Record<ThemeName, ThemeConfig> = {
|
|
105
132
|
jam: jamTheme,
|
|
106
133
|
nebula: nebulaTheme,
|
|
107
134
|
pulsar: pulsarTheme,
|
|
108
135
|
halo: haloTheme,
|
|
136
|
+
dusk: duskTheme,
|
|
109
137
|
};
|
|
110
138
|
|
|
111
139
|
/**
|
|
@@ -235,11 +235,12 @@ html:not(.dark) body[data-theme="jam"]:not([data-decoration="none"]):not([data-d
|
|
|
235
235
|
background-color: transparent !important;
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
238
|
+
/* Anchored on [data-jd-layout-root], not a bare `> div`: CodePanelModal
|
|
239
|
+
portals a `div[role="dialog"] > div.flex` into <body>, and the bare form
|
|
240
|
+
stripped the modal panel's own background (a `:not([role="dialog"])` on the
|
|
241
|
+
inner div guarded the wrong level). agent-directive-theme-isolation.test.ts
|
|
242
|
+
keeps body-anchored rules off every other <body> child. */
|
|
243
|
+
html:not(.dark) body[data-theme="jam"]:not([data-decoration="none"]):not([data-decoration="grid"]) > div[data-jd-layout-root] > div.flex:not(:has([data-chat-panel])) {
|
|
243
244
|
background-color: transparent !important;
|
|
244
245
|
}
|
|
245
246
|
|
|
@@ -248,7 +248,7 @@ body[data-theme="nebula"] .sidebar-tabs {
|
|
|
248
248
|
/* Header divider. Targets the nav header by its data-has-tabs attribute, not a
|
|
249
249
|
child-combinator chain from <body>: the old `body > div > header` form broke
|
|
250
250
|
silently when LayoutWrapper nested the header three levels down, and Nebula
|
|
251
|
-
shipped with no divider (
|
|
251
|
+
shipped with no divider (theme-layout-selectors.test.tsx). The header is
|
|
252
252
|
sticky, which already anchors ::after, so it needs no position of its own.
|
|
253
253
|
The -1rem / -1.5rem insets span the layout column's `px-4 lg:px-6`: the line
|
|
254
254
|
runs edge to edge up to --layout-max-width without lifting the column's
|
|
@@ -1019,9 +1019,10 @@ body[data-theme="pulsar"] header [data-theme-toggle] {
|
|
|
1019
1019
|
background-color: var(--color-bg-primary) !important;
|
|
1020
1020
|
}
|
|
1021
1021
|
|
|
1022
|
-
/* Ensure content area starts at top with no gap.
|
|
1023
|
-
|
|
1024
|
-
|
|
1022
|
+
/* Ensure content area starts at top with no gap. [data-jd-layout-root],
|
|
1023
|
+
not a bare `> div`: <body> also holds the sr-only agent directive and
|
|
1024
|
+
modal portals (theme-layout-selectors.test.tsx). */
|
|
1025
|
+
body[data-theme="pulsar"] > div[data-jd-layout-root] {
|
|
1025
1026
|
min-height: 100vh;
|
|
1026
1027
|
min-height: 100dvh; /* Dynamic viewport height for mobile browsers */
|
|
1027
1028
|
}
|
package/vendored/themes/types.ts
CHANGED
|
@@ -67,6 +67,13 @@ export interface ThemeConfig {
|
|
|
67
67
|
googleFontUrl?: string;
|
|
68
68
|
fallback: string;
|
|
69
69
|
};
|
|
70
|
+
/** Optional heading face (Dusk's serif H1). Loaded by next/font in
|
|
71
|
+
* production; the dashboard editor preview links googleFontUrl. */
|
|
72
|
+
heading?: {
|
|
73
|
+
family: string;
|
|
74
|
+
googleFontUrl?: string;
|
|
75
|
+
fallback: string;
|
|
76
|
+
};
|
|
70
77
|
};
|
|
71
78
|
|
|
72
79
|
/** CSS file path relative to themes directory */
|
|
@@ -82,6 +89,7 @@ export type ThemeName =
|
|
|
82
89
|
| 'nebula'
|
|
83
90
|
| 'pulsar'
|
|
84
91
|
| 'halo'
|
|
92
|
+
| 'dusk'
|
|
85
93
|
// Future themes can be added here:
|
|
86
94
|
// | 'linden'
|
|
87
95
|
// | 'willow'
|