@marlinjai/clearify 1.5.1 → 1.5.3

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.
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-SCZZB7OE.js";
9
9
  import {
10
10
  clearifyPlugin
11
- } from "./chunk-NXQNNLGC.js";
11
+ } from "./chunk-UOVBAJMR.js";
12
12
  import {
13
13
  loadUserConfig,
14
14
  resolveConfig,
@@ -368,6 +368,23 @@ ${routeEntries.join(",\n")}
368
368
  server.ws.send({ type: "full-reload" });
369
369
  }
370
370
  });
371
+ return () => {
372
+ server.middlewares.use((req, _res, next) => {
373
+ if (req.method !== "GET" || !req.headers.accept?.includes("text/html")) {
374
+ return next();
375
+ }
376
+ const url = req.url?.split("?")[0] ?? "";
377
+ const sectionMatch = visibleSections.some(
378
+ (s) => s.basePath !== "/" && url.startsWith(s.basePath)
379
+ );
380
+ const apiBasePath = config.openapi?.basePath ?? "/api";
381
+ const apiMatch = config.openapi?.spec && url.startsWith(apiBasePath);
382
+ if (sectionMatch || apiMatch) {
383
+ req.url = "/index.html";
384
+ }
385
+ next();
386
+ });
387
+ };
371
388
  }
372
389
  };
373
390
  const headInjectionPlugin = {
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  buildSite
3
- } from "../chunk-CQ4MNGBE.js";
3
+ } from "../chunk-NY3VVUQ3.js";
4
4
  import "../chunk-PRTER35L.js";
5
5
  import "../chunk-SCZZB7OE.js";
6
- import "../chunk-NXQNNLGC.js";
6
+ import "../chunk-UOVBAJMR.js";
7
7
  import "../chunk-B2Q23JW3.js";
8
8
  import "../chunk-IBK35HZR.js";
9
9
  import "../chunk-V7LLYIRO.js";
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  buildSite
3
- } from "../chunk-CQ4MNGBE.js";
3
+ } from "../chunk-NY3VVUQ3.js";
4
4
  import {
5
5
  remarkMermaidToComponent
6
6
  } from "../chunk-PRTER35L.js";
7
7
  import "../chunk-SCZZB7OE.js";
8
8
  import {
9
9
  clearifyPlugin
10
- } from "../chunk-NXQNNLGC.js";
10
+ } from "../chunk-UOVBAJMR.js";
11
11
  import "../chunk-B2Q23JW3.js";
12
12
  import {
13
13
  init
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  clearifyPlugin
3
- } from "../chunk-NXQNNLGC.js";
3
+ } from "../chunk-UOVBAJMR.js";
4
4
  import "../chunk-B2Q23JW3.js";
5
5
  import "../chunk-IBK35HZR.js";
6
6
  import "../chunk-V7LLYIRO.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marlinjai/clearify",
3
- "version": "1.5.1",
3
+ "version": "1.5.3",
4
4
  "description": "An open-source documentation site generator. Turn markdown into beautiful docs.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -38,6 +38,14 @@ function findActiveSection(pathname: string, sections: SectionNavigation[]): str
38
38
  return bestMatch;
39
39
  }
40
40
 
41
+ function collectGroupKeys(items: NavigationItem[], prefix = ''): string[] {
42
+ return items.flatMap((item) => {
43
+ if (!item.children) return [];
44
+ const key = prefix ? `${prefix}/${item.label}` : item.label;
45
+ return [key, ...collectGroupKeys(item.children, key)];
46
+ });
47
+ }
48
+
41
49
  function SectionSwitcher({
42
50
  sections,
43
51
  activeId,
@@ -121,6 +129,32 @@ export function Sidebar({ sections, open, onClose }: SidebarProps) {
121
129
  const navigation = legacyNavigation ?? activeSection?.navigation ?? [];
122
130
  const showSwitcher = isSectionData && sections.length > 1;
123
131
 
132
+ // Centralized expansion state
133
+ const [expandedGroups, setExpandedGroups] = useState<Set<string>>(() => new Set(collectGroupKeys(navigation)));
134
+
135
+ // Re-expand all when section changes
136
+ useEffect(() => {
137
+ setExpandedGroups(new Set(collectGroupKeys(navigation)));
138
+ }, [selectedSectionId]);
139
+
140
+ const allGroupKeys = collectGroupKeys(navigation);
141
+ const hasCollapsibleGroups = allGroupKeys.length >= 2;
142
+
143
+ const handleToggleGroup = (key: string) => {
144
+ setExpandedGroups((prev) => {
145
+ const next = new Set(prev);
146
+ if (next.has(key)) {
147
+ next.delete(key);
148
+ } else {
149
+ next.add(key);
150
+ }
151
+ return next;
152
+ });
153
+ };
154
+
155
+ const handleExpandAll = () => setExpandedGroups(new Set(allGroupKeys));
156
+ const handleCollapseAll = () => setExpandedGroups(new Set());
157
+
124
158
  return (
125
159
  <>
126
160
  {/* Mobile overlay */}
@@ -163,9 +197,86 @@ export function Sidebar({ sections, open, onClose }: SidebarProps) {
163
197
  onSelect={setSelectedSectionId}
164
198
  />
165
199
  )}
200
+ {hasCollapsibleGroups && (
201
+ <div style={{
202
+ display: 'flex',
203
+ justifyContent: 'flex-end',
204
+ gap: '0.25rem',
205
+ padding: '0.25rem 0.75rem',
206
+ }}>
207
+ <button
208
+ onClick={handleExpandAll}
209
+ title="Expand all groups"
210
+ style={{
211
+ display: 'flex',
212
+ alignItems: 'center',
213
+ justifyContent: 'center',
214
+ width: 24,
215
+ height: 24,
216
+ background: 'none',
217
+ border: 'none',
218
+ cursor: 'pointer',
219
+ color: 'var(--clearify-text-tertiary)',
220
+ borderRadius: 'var(--clearify-radius-sm)',
221
+ transition: 'color 0.15s, background-color 0.15s',
222
+ }}
223
+ onMouseEnter={(e) => {
224
+ e.currentTarget.style.color = 'var(--clearify-text-secondary)';
225
+ e.currentTarget.style.backgroundColor = 'var(--clearify-bg-secondary)';
226
+ }}
227
+ onMouseLeave={(e) => {
228
+ e.currentTarget.style.color = 'var(--clearify-text-tertiary)';
229
+ e.currentTarget.style.backgroundColor = 'transparent';
230
+ }}
231
+ >
232
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
233
+ <polyline points="7 8 12 3 17 8" />
234
+ <polyline points="7 16 12 21 17 16" />
235
+ </svg>
236
+ </button>
237
+ <button
238
+ onClick={handleCollapseAll}
239
+ title="Collapse all groups"
240
+ style={{
241
+ display: 'flex',
242
+ alignItems: 'center',
243
+ justifyContent: 'center',
244
+ width: 24,
245
+ height: 24,
246
+ background: 'none',
247
+ border: 'none',
248
+ cursor: 'pointer',
249
+ color: 'var(--clearify-text-tertiary)',
250
+ borderRadius: 'var(--clearify-radius-sm)',
251
+ transition: 'color 0.15s, background-color 0.15s',
252
+ }}
253
+ onMouseEnter={(e) => {
254
+ e.currentTarget.style.color = 'var(--clearify-text-secondary)';
255
+ e.currentTarget.style.backgroundColor = 'var(--clearify-bg-secondary)';
256
+ }}
257
+ onMouseLeave={(e) => {
258
+ e.currentTarget.style.color = 'var(--clearify-text-tertiary)';
259
+ e.currentTarget.style.backgroundColor = 'transparent';
260
+ }}
261
+ >
262
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
263
+ <polyline points="7 3 12 8 17 3" />
264
+ <polyline points="7 21 12 16 17 21" />
265
+ </svg>
266
+ </button>
267
+ </div>
268
+ )}
166
269
  <nav style={{ padding: '0 0.5rem' }}>
167
270
  {navigation.map((item, i) => (
168
- <NavItem key={i} item={item} depth={0} onNavigate={onClose} />
271
+ <NavItem
272
+ key={i}
273
+ item={item}
274
+ depth={0}
275
+ onNavigate={onClose}
276
+ expandedGroups={expandedGroups}
277
+ onToggleGroup={handleToggleGroup}
278
+ groupKeyPrefix=""
279
+ />
169
280
  ))}
170
281
  </nav>
171
282
  </aside>
@@ -193,16 +304,27 @@ export function Sidebar({ sections, open, onClose }: SidebarProps) {
193
304
  );
194
305
  }
195
306
 
196
- function NavItem({ item, depth, onNavigate }: { item: NavigationItem; depth: number; onNavigate: () => void }) {
307
+ interface NavItemProps {
308
+ item: NavigationItem;
309
+ depth: number;
310
+ onNavigate: () => void;
311
+ expandedGroups: Set<string>;
312
+ onToggleGroup: (key: string) => void;
313
+ groupKeyPrefix: string;
314
+ }
315
+
316
+ function NavItem({ item, depth, onNavigate, expandedGroups, onToggleGroup, groupKeyPrefix }: NavItemProps) {
197
317
  const location = useLocation();
198
- const [expanded, setExpanded] = useState(true);
199
318
  const isActive = item.path === location.pathname;
200
319
 
201
320
  if (item.children) {
321
+ const groupKey = groupKeyPrefix ? `${groupKeyPrefix}/${item.label}` : item.label;
322
+ const expanded = expandedGroups.has(groupKey);
323
+
202
324
  return (
203
325
  <div style={{ marginBottom: '0.125rem' }}>
204
326
  <button
205
- onClick={() => setExpanded(!expanded)}
327
+ onClick={() => onToggleGroup(groupKey)}
206
328
  style={{
207
329
  display: 'flex',
208
330
  alignItems: 'center',
@@ -246,7 +368,15 @@ function NavItem({ item, depth, onNavigate }: { item: NavigationItem; depth: num
246
368
  {expanded && (
247
369
  <div style={{ animation: 'clearify-fade-in 0.15s ease-out' }}>
248
370
  {item.children.map((child, i) => (
249
- <NavItem key={i} item={child} depth={depth + 1} onNavigate={onNavigate} />
371
+ <NavItem
372
+ key={i}
373
+ item={child}
374
+ depth={depth + 1}
375
+ onNavigate={onNavigate}
376
+ expandedGroups={expandedGroups}
377
+ onToggleGroup={onToggleGroup}
378
+ groupKeyPrefix={groupKey}
379
+ />
250
380
  ))}
251
381
  </div>
252
382
  )}
@@ -42,8 +42,7 @@ export function OpenAPI({
42
42
 
43
43
  const configuration = useMemo(() => {
44
44
  const config: Record<string, unknown> = {
45
- // Use 'none' theme so Clearify's CSS variable bridge takes full control
46
- theme: 'none',
45
+ theme: 'default',
47
46
  forceDarkModeState: theme === 'dark' ? 'dark' : 'light',
48
47
  hideDarkModeToggle,
49
48
  showSidebar: !hideSidebar,
@@ -130,6 +129,7 @@ export function OpenAPI({
130
129
 
131
130
  /** Custom CSS to integrate Scalar with Clearify's design tokens */
132
131
  const SCALAR_CUSTOM_CSS = `
132
+ /* ── Design Token Bridge ── */
133
133
  .scalar-app {
134
134
  --scalar-font: var(--font-sans);
135
135
  --scalar-font-code: var(--font-mono);
@@ -139,22 +139,335 @@ const SCALAR_CUSTOM_CSS = `
139
139
  --scalar-color-3: var(--clearify-text-tertiary);
140
140
 
141
141
  --scalar-color-accent: var(--clearify-primary);
142
+ --scalar-background-accent: rgba(99, 102, 241, 0.08);
142
143
 
143
144
  --scalar-background-1: var(--clearify-bg);
144
145
  --scalar-background-2: var(--clearify-bg-secondary);
145
146
  --scalar-background-3: var(--clearify-bg-tertiary);
147
+ --scalar-background-4: var(--clearify-bg-tertiary);
146
148
 
147
149
  --scalar-border-color: var(--clearify-border-strong);
150
+ --scalar-border-width: 1px;
148
151
 
149
152
  --scalar-radius: var(--clearify-radius-sm);
150
153
  --scalar-radius-lg: var(--clearify-radius);
154
+ --scalar-radius-xl: var(--clearify-radius-lg);
151
155
 
152
156
  --scalar-shadow-1: var(--clearify-shadow-sm);
153
157
  --scalar-shadow-2: var(--clearify-shadow);
158
+
159
+ --scalar-link-color: var(--clearify-primary);
160
+ --scalar-link-color-hover: var(--clearify-primary-hover);
161
+ --scalar-text-decoration: none;
162
+ --scalar-text-decoration-hover: underline;
163
+
164
+ --scalar-scrollbar-color: var(--clearify-border-strong);
165
+ --scalar-scrollbar-color-active: var(--clearify-text-tertiary);
166
+
167
+ --scalar-color-green: #059669;
168
+ --scalar-color-blue: #2563eb;
169
+ --scalar-color-orange: #d97706;
170
+ --scalar-color-red: #dc2626;
171
+ --scalar-color-purple: #7c3aed;
172
+ --scalar-color-yellow: #ca8a04;
154
173
  }
155
174
 
175
+ .dark-mode .scalar-app,
176
+ .dark .scalar-app {
177
+ --scalar-background-accent: rgba(129, 140, 248, 0.1);
178
+ --scalar-color-green: #34d399;
179
+ --scalar-color-blue: #60a5fa;
180
+ --scalar-color-orange: #fbbf24;
181
+ --scalar-color-red: #f87171;
182
+ --scalar-color-purple: #a78bfa;
183
+ --scalar-color-yellow: #facc15;
184
+ }
185
+
186
+ /* ── Layout ── */
156
187
  .scalar-app .section {
157
188
  padding-left: 0;
158
189
  padding-right: 0;
159
190
  }
191
+
192
+ .scalar-app .references-layout {
193
+ --refs-content-max-width: 100%;
194
+ }
195
+
196
+ /* ── Introduction Card ── */
197
+ .scalar-app .introduction-card {
198
+ border: 1px solid var(--clearify-border);
199
+ border-radius: var(--clearify-radius);
200
+ background: var(--clearify-bg-secondary);
201
+ overflow: hidden;
202
+ }
203
+
204
+ /* ── Section Headers ── */
205
+ .scalar-app .section-header {
206
+ font-family: var(--font-sans);
207
+ letter-spacing: -0.01em;
208
+ }
209
+
210
+ /* ── Endpoint Cards ── */
211
+ .scalar-app .section-accordion {
212
+ border: 1px solid var(--clearify-border);
213
+ border-radius: var(--clearify-radius);
214
+ overflow: hidden;
215
+ transition: border-color 0.2s ease, box-shadow 0.2s ease;
216
+ }
217
+
218
+ .scalar-app .section-accordion:hover {
219
+ border-color: var(--clearify-border-strong);
220
+ box-shadow: var(--clearify-shadow-sm);
221
+ }
222
+
223
+ .scalar-app .section-accordion-content-card {
224
+ border-radius: var(--clearify-radius);
225
+ }
226
+
227
+ /* ── Method Badges ── */
228
+ .scalar-app .endpoint-method {
229
+ font-family: var(--font-mono);
230
+ font-size: 0.6875rem;
231
+ font-weight: 700;
232
+ letter-spacing: 0.04em;
233
+ text-transform: uppercase;
234
+ padding: 0.15rem 0.5rem;
235
+ border-radius: 4px;
236
+ line-height: 1.5;
237
+ }
238
+
239
+ .scalar-app .endpoint-method.get {
240
+ background: rgba(5, 150, 105, 0.12);
241
+ color: var(--scalar-color-green);
242
+ }
243
+ .scalar-app .endpoint-method.post {
244
+ background: rgba(37, 99, 235, 0.12);
245
+ color: var(--scalar-color-blue);
246
+ }
247
+ .scalar-app .endpoint-method.put {
248
+ background: rgba(217, 119, 6, 0.12);
249
+ color: var(--scalar-color-orange);
250
+ }
251
+ .scalar-app .endpoint-method.delete {
252
+ background: rgba(220, 38, 38, 0.12);
253
+ color: var(--scalar-color-red);
254
+ }
255
+ .scalar-app .endpoint-method.patch {
256
+ background: rgba(124, 58, 237, 0.12);
257
+ color: var(--scalar-color-purple);
258
+ }
259
+
260
+ /* ── Endpoint Paths ── */
261
+ .scalar-app .endpoint-path,
262
+ .scalar-app .endpoint-label-path {
263
+ font-family: var(--font-mono);
264
+ font-size: 0.8125rem;
265
+ letter-spacing: -0.01em;
266
+ }
267
+
268
+ /* ── Request / Response Cards ── */
269
+ .scalar-app .scalar-card {
270
+ border: 1px solid var(--clearify-border);
271
+ border-radius: var(--clearify-radius);
272
+ overflow: hidden;
273
+ }
274
+
275
+ .scalar-app .scalar-card-header {
276
+ background: var(--clearify-bg-secondary);
277
+ border-bottom: 1px solid var(--clearify-border);
278
+ }
279
+
280
+ .scalar-app .scalar-card-header-tabs button {
281
+ font-family: var(--font-mono);
282
+ font-size: 0.75rem;
283
+ font-weight: 500;
284
+ letter-spacing: 0.02em;
285
+ transition: color 0.15s ease, background-color 0.15s ease;
286
+ border-radius: var(--clearify-radius-sm);
287
+ }
288
+
289
+ /* ── Code Blocks ── */
290
+ .scalar-app .scalar-codeblock-pre,
291
+ .scalar-app .cm-editor {
292
+ font-family: var(--font-mono);
293
+ font-size: 0.8125rem;
294
+ line-height: 1.7;
295
+ border-radius: var(--clearify-radius);
296
+ }
297
+
298
+ .scalar-app .scalar-code-block {
299
+ border: 1px solid var(--clearify-border);
300
+ border-radius: var(--clearify-radius);
301
+ overflow: hidden;
302
+ }
303
+
304
+ .scalar-app .scalar-code-copy {
305
+ border-radius: var(--clearify-radius-sm);
306
+ opacity: 0;
307
+ transition: opacity 0.15s ease;
308
+ }
309
+
310
+ .scalar-app .scalar-code-block:hover .scalar-code-copy {
311
+ opacity: 1;
312
+ }
313
+
314
+ /* ── Parameters ── */
315
+ .scalar-app .parameter-item {
316
+ border-bottom: 1px solid var(--clearify-border);
317
+ transition: background-color 0.15s ease;
318
+ }
319
+
320
+ .scalar-app .parameter-item:last-child {
321
+ border-bottom: none;
322
+ }
323
+
324
+ .scalar-app .parameter-item:hover {
325
+ background-color: var(--clearify-bg-secondary);
326
+ }
327
+
328
+ .scalar-app .parameter-item-name {
329
+ font-family: var(--font-mono);
330
+ font-size: 0.8125rem;
331
+ font-weight: 600;
332
+ }
333
+
334
+ .scalar-app .parameter-item--required .parameter-item-required-optional {
335
+ color: var(--scalar-color-orange);
336
+ font-size: 0.6875rem;
337
+ font-weight: 600;
338
+ text-transform: uppercase;
339
+ letter-spacing: 0.04em;
340
+ }
341
+
342
+ /* ── Schema / Properties ── */
343
+ .scalar-app .schema-card {
344
+ border: 1px solid var(--clearify-border);
345
+ border-radius: var(--clearify-radius);
346
+ overflow: hidden;
347
+ }
348
+
349
+ .scalar-app .property-name {
350
+ font-family: var(--font-mono);
351
+ font-size: 0.8125rem;
352
+ font-weight: 500;
353
+ }
354
+
355
+ .scalar-app .property-required {
356
+ color: var(--scalar-color-orange);
357
+ font-size: 0.6875rem;
358
+ font-weight: 600;
359
+ }
360
+
361
+ .scalar-app .property-read-only {
362
+ color: var(--scalar-color-blue);
363
+ font-size: 0.6875rem;
364
+ }
365
+
366
+ .scalar-app .property-write-only {
367
+ color: var(--scalar-color-green);
368
+ font-size: 0.6875rem;
369
+ }
370
+
371
+ .scalar-app .schema-type {
372
+ font-family: var(--font-mono);
373
+ font-size: 0.75rem;
374
+ color: var(--clearify-text-tertiary);
375
+ }
376
+
377
+ .scalar-app .property-enum-value {
378
+ font-family: var(--font-mono);
379
+ font-size: 0.75rem;
380
+ background: var(--clearify-bg-secondary);
381
+ border: 1px solid var(--clearify-border);
382
+ border-radius: 4px;
383
+ padding: 0.1rem 0.4rem;
384
+ }
385
+
386
+ /* ── Client Libraries ── */
387
+ .scalar-app .client-libraries-icon {
388
+ max-width: 48px;
389
+ max-height: 48px;
390
+ }
391
+
392
+ .scalar-app .client-libraries {
393
+ border: 1px solid var(--clearify-border);
394
+ border-radius: var(--clearify-radius);
395
+ }
396
+
397
+ /* ── Buttons ── */
398
+ .scalar-app .scalar-button {
399
+ border-radius: var(--clearify-radius-sm);
400
+ font-weight: 500;
401
+ font-size: 0.8125rem;
402
+ transition: all 0.15s ease;
403
+ }
404
+
405
+ /* ── Tooltips ── */
406
+ .scalar-app .scalar-tooltip {
407
+ font-size: 0.75rem;
408
+ border-radius: var(--clearify-radius-sm);
409
+ }
410
+
411
+ /* ── Auth Section ── */
412
+ .scalar-app .security-scheme-label {
413
+ font-family: var(--font-mono);
414
+ font-size: 0.75rem;
415
+ border-radius: 4px;
416
+ }
417
+
418
+ /* ── Smooth Transitions ── */
419
+ .scalar-app .section-accordion-content {
420
+ animation: clearify-fade-in 0.2s ease-out;
421
+ }
422
+
423
+ .scalar-app .section-accordion-chevron {
424
+ transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
425
+ }
426
+
427
+ /* ── Server & Auth Intro Cards ── */
428
+ .scalar-app .introduction-card-item {
429
+ border-bottom: 1px solid var(--clearify-border);
430
+ }
431
+
432
+ .scalar-app .introduction-card-item:last-child {
433
+ border-bottom: none;
434
+ }
435
+
436
+ /* ── Operation Details ── */
437
+ .scalar-app .operation-details-card {
438
+ border: 1px solid var(--clearify-border);
439
+ border-radius: var(--clearify-radius);
440
+ overflow: hidden;
441
+ }
442
+
443
+ /* ── Try It / Request Editor ── */
444
+ .scalar-app .request-card {
445
+ border: 1px solid var(--clearify-border);
446
+ border-radius: var(--clearify-radius);
447
+ overflow: hidden;
448
+ }
449
+
450
+ .scalar-app .response-card {
451
+ border: 1px solid var(--clearify-border);
452
+ border-radius: var(--clearify-radius);
453
+ overflow: hidden;
454
+ }
455
+
456
+ /* ── Sidebar (when visible) ── */
457
+ .scalar-app {
458
+ --scalar-sidebar-background-1: var(--clearify-bg);
459
+ --scalar-sidebar-color-1: var(--clearify-text);
460
+ --scalar-sidebar-color-2: var(--clearify-text-secondary);
461
+ --scalar-sidebar-color-active: var(--clearify-primary);
462
+ --scalar-sidebar-border-color: var(--clearify-border);
463
+ --scalar-sidebar-item-hover-background: var(--clearify-bg-secondary);
464
+ --scalar-sidebar-item-active-background: var(--clearify-primary-soft);
465
+ }
466
+
467
+ /* ── Syntax Highlighting ── */
468
+ .scalar-app .hljs-keyword { color: var(--clearify-primary); }
469
+ .scalar-app .hljs-string { color: var(--scalar-color-green); }
470
+ .scalar-app .hljs-number { color: var(--scalar-color-orange); }
471
+ .scalar-app .hljs-attr { color: var(--scalar-color-blue); }
472
+ .scalar-app .hljs-comment { color: var(--clearify-text-tertiary); font-style: italic; }
160
473
  `;
@@ -7,7 +7,7 @@ import openapiSpec from 'virtual:clearify/openapi-spec';
7
7
  export default function OpenAPIPage() {
8
8
  const basePath = config.openapi?.basePath ?? '/api';
9
9
  return (
10
- <div className="clearify-openapi-page" style={{ margin: '0 -1.5rem', maxWidth: 'none' }}>
10
+ <div className="clearify-openapi-page" style={{ maxWidth: 'none' }}>
11
11
  <OpenAPI spec={openapiSpec} hideSidebar={true} pathRouting={{ basePath }} />
12
12
  </div>
13
13
  );
@@ -361,3 +361,131 @@ a:hover {
361
361
  0% { background-position: -200% 0; }
362
362
  100% { background-position: 200% 0; }
363
363
  }
364
+
365
+ /* ─── OpenAPI container isolation ─── */
366
+ /* Remove Content wrapper constraints when rendering API reference */
367
+ .clearify-prose:has(.clearify-openapi-page) {
368
+ max-width: none !important;
369
+ padding-left: 0 !important;
370
+ padding-right: 0 !important;
371
+ }
372
+
373
+ /* Prevent clearify-prose typography and global styles from bleeding into Scalar */
374
+ .clearify-openapi-container h1,
375
+ .clearify-openapi-container h2,
376
+ .clearify-openapi-container h3,
377
+ .clearify-openapi-container h4 {
378
+ font-size: inherit;
379
+ font-weight: inherit;
380
+ margin: initial;
381
+ padding: initial;
382
+ line-height: inherit;
383
+ letter-spacing: normal;
384
+ color: inherit;
385
+ border-bottom: none;
386
+ text-transform: none;
387
+ }
388
+
389
+ .clearify-openapi-container p {
390
+ margin: initial;
391
+ color: inherit;
392
+ }
393
+
394
+ .clearify-openapi-container ul,
395
+ .clearify-openapi-container ol {
396
+ margin: initial;
397
+ padding: initial;
398
+ color: inherit;
399
+ }
400
+
401
+ .clearify-openapi-container li {
402
+ margin: initial;
403
+ }
404
+
405
+ .clearify-openapi-container img {
406
+ max-width: initial;
407
+ border-radius: initial;
408
+ border: initial;
409
+ }
410
+
411
+ .clearify-openapi-container code {
412
+ background-color: initial;
413
+ padding: initial;
414
+ border-radius: initial;
415
+ font-size: inherit;
416
+ font-family: inherit;
417
+ font-weight: inherit;
418
+ color: inherit;
419
+ border: initial;
420
+ }
421
+
422
+ .clearify-openapi-container pre {
423
+ background-color: initial;
424
+ border: initial;
425
+ border-radius: initial;
426
+ padding: initial;
427
+ overflow-x: initial;
428
+ margin: initial;
429
+ font-size: inherit;
430
+ line-height: inherit;
431
+ font-family: inherit;
432
+ }
433
+
434
+ .clearify-openapi-container table {
435
+ width: initial;
436
+ border-collapse: initial;
437
+ border-spacing: initial;
438
+ margin: initial;
439
+ font-size: inherit;
440
+ border-radius: initial;
441
+ overflow: initial;
442
+ border: initial;
443
+ }
444
+
445
+ .clearify-openapi-container th,
446
+ .clearify-openapi-container td {
447
+ padding: initial;
448
+ text-align: initial;
449
+ border-bottom: initial;
450
+ }
451
+
452
+ .clearify-openapi-container th {
453
+ background-color: initial;
454
+ font-weight: inherit;
455
+ font-size: inherit;
456
+ text-transform: initial;
457
+ letter-spacing: initial;
458
+ color: inherit;
459
+ }
460
+
461
+ .clearify-openapi-container strong {
462
+ font-weight: inherit;
463
+ color: inherit;
464
+ }
465
+
466
+ .clearify-openapi-container blockquote {
467
+ border-left: initial;
468
+ padding: initial;
469
+ color: inherit;
470
+ margin: initial;
471
+ background: initial;
472
+ border-radius: initial;
473
+ font-style: initial;
474
+ }
475
+
476
+ .clearify-openapi-container hr {
477
+ border: initial;
478
+ border-top: initial;
479
+ margin: initial;
480
+ }
481
+
482
+ .clearify-openapi-container a {
483
+ color: inherit;
484
+ text-decoration: initial;
485
+ transition: initial;
486
+ }
487
+
488
+ .clearify-openapi-container a:hover {
489
+ color: inherit;
490
+ text-decoration: initial;
491
+ }