radiant-docs 0.1.37 → 0.1.38

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.
Files changed (38) hide show
  1. package/package.json +1 -1
  2. package/template/astro.config.mjs +2 -0
  3. package/template/src/components/Footer.astro +1 -1
  4. package/template/src/components/Header.astro +8 -8
  5. package/template/src/components/OpenApiPage.astro +18 -18
  6. package/template/src/components/Search.astro +18 -18
  7. package/template/src/components/Sidebar.astro +4 -2
  8. package/template/src/components/SidebarDropdown.astro +82 -79
  9. package/template/src/components/SidebarSegmented.astro +5 -5
  10. package/template/src/components/TableOfContents.astro +24 -15
  11. package/template/src/components/ThemeSwitcher.astro +15 -8
  12. package/template/src/components/chat/AskAiWidget.tsx +4 -3
  13. package/template/src/components/endpoint/PlaygroundBar.astro +3 -3
  14. package/template/src/components/endpoint/PlaygroundButton.astro +2 -2
  15. package/template/src/components/endpoint/PlaygroundField.astro +53 -53
  16. package/template/src/components/endpoint/PlaygroundForm.astro +38 -22
  17. package/template/src/components/endpoint/RequestSnippets.astro +54 -21
  18. package/template/src/components/endpoint/ResponseDisplay.astro +24 -24
  19. package/template/src/components/endpoint/ResponseFieldTree.astro +12 -12
  20. package/template/src/components/endpoint/ResponseFields.astro +19 -19
  21. package/template/src/components/endpoint/ResponseSnippets.astro +66 -29
  22. package/template/src/components/ui/CodeTabEdge.astro +6 -4
  23. package/template/src/components/ui/Field.astro +7 -7
  24. package/template/src/components/ui/demo/Demo.astro +1 -1
  25. package/template/src/components/user/Accordion.astro +3 -3
  26. package/template/src/components/user/Callout.astro +8 -8
  27. package/template/src/components/user/CodeBlock.astro +57 -22
  28. package/template/src/components/user/CodeGroup.astro +14 -10
  29. package/template/src/components/user/ComponentPreviewBlock.astro +38 -12
  30. package/template/src/components/user/Image.astro +2 -2
  31. package/template/src/components/user/Step.astro +4 -4
  32. package/template/src/components/user/Tab.astro +1 -1
  33. package/template/src/components/user/Tabs.astro +15 -20
  34. package/template/src/layouts/Layout.astro +1 -1
  35. package/template/src/lib/code/code-block.ts +150 -15
  36. package/template/src/lib/mdx/remark-resolve-internal-links.ts +639 -0
  37. package/template/src/pages/404.astro +44 -0
  38. package/template/src/styles/global.css +28 -19
@@ -540,7 +540,7 @@ const sectionVariantFieldNames = Object.fromEntries(
540
540
  <button
541
541
  @click="sendRequest($event)"
542
542
  :disabled="loading"
543
- class="m-px font-[350] relative flex h-8 items-center gap-2 rounded-lg [corner-shape:superellipse(1.2)] bg-linear-to-b from-neutral-900/85 to-neutral-900 px-3 text-[13px] text-white shadow-sm dark:bg-white dark:text-neutral-900 transition-all duration-200 whitespace-nowrap cursor-pointer disabled:opacity-70 disabled:cursor-not-allowed"
543
+ class="font-[350] dark:font-[450] relative flex h-8 items-center gap-2 rounded-lg [corner-shape:superellipse(1.2)] bg-linear-to-b from-neutral-900/85 to-neutral-900 dark:from-neutral-100 dark:to-neutral-200 px-3 text-[13px] text-white dark:text-neutral-950 shadow-sm transition-all duration-200 whitespace-nowrap cursor-pointer disabled:opacity-70 disabled:cursor-not-allowed"
544
544
  >
545
545
  <span class="flex items-center gap-2">
546
546
  <Icon
@@ -565,8 +565,8 @@ const sectionVariantFieldNames = Object.fromEntries(
565
565
  <ResponseDisplay />
566
566
  </div>
567
567
  <div class="lg:flex-1 relative">
568
- <div class="flex-3 min-h-0 max-h-[calc(60dvh-2rem-23px-12px)] lg:max-h-[calc(100dvh-4rem-46px-24px)] overflow-y-auto overscroll-contain [scrollbar-width:thin] [scrollbar-color:var(--color-neutral-300)_transparent] [&::-webkit-scrollbar]:h-1.5 [&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-neutral-300/70 hover:[&::-webkit-scrollbar-thumb]:bg-neutral-300/90">
569
- <div class="pointer-events-none sticky top-0 z-10 -mb-4 h-4 bg-linear-to-b from-background via-white/60 to-transparent"></div>
568
+ <div class="flex-3 min-h-0 max-h-[calc(60dvh-2rem-23px-12px)] lg:max-h-[calc(100dvh-4rem-46px-24px)] overflow-y-auto overscroll-contain [scrollbar-width:thin] [scrollbar-color:var(--color-neutral-300)_transparent] [&::-webkit-scrollbar]:h-1.5 [&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-neutral-300/70 hover:[&::-webkit-scrollbar-thumb]:bg-neutral-300/90 dark:[scrollbar-color:var(--color-neutral-700)_transparent] dark:[&::-webkit-scrollbar-thumb]:bg-neutral-700/70 dark:hover:[&::-webkit-scrollbar-thumb]:bg-neutral-700/90">
569
+ <div class="pointer-events-none sticky top-0 z-10 -mb-4 h-4 bg-linear-to-b from-background via-white/60 to-transparent dark:via-neutral-900/70"></div>
570
570
  <div class="space-y-4 lg:pr-4 pt-4 pb-6">
571
571
  {
572
572
  Object.keys(requestFields).map(
@@ -582,16 +582,16 @@ const sectionVariantFieldNames = Object.fromEntries(
582
582
  }
583
583
 
584
584
  return (
585
- <div class="border border-neutral-200 shadow-xs rounded-xl p-4 pb-0 [&_[role='region']]:border-b-0">
585
+ <div class="border border-neutral-200 bg-white shadow-xs rounded-xl p-4 pb-0 dark:border-neutral-800 dark:bg-(--rd-code-surface) [&_[role='region']]:border-b-0">
586
586
  <Accordion title={headers[key]} defaultOpen titleSize="xl">
587
587
  {key === "body" && formattedBodyDescription && (
588
588
  <div
589
- class="mb-4 prose-rules prose-sm! text-neutral-500 **:text-neutral-500"
589
+ class="mb-4 prose-rules prose-sm! text-neutral-500 **:text-neutral-500 dark:text-neutral-400 dark:**:text-neutral-400"
590
590
  set:html={formattedBodyDescription}
591
591
  />
592
592
  )}
593
593
  {sectionFields.map((field) => (
594
- <div class="border-b border-b-neutral-100 last:border-none pb-4 mb-4 last:pb-0 last:mb-0 first:pt-2">
594
+ <div class="border-b border-b-neutral-100 dark:border-b-neutral-800 last:border-none pb-4 mb-4 last:pb-0 last:mb-0 first:pt-2">
595
595
  <PlaygroundField field={field} requestPart={key} />
596
596
  </div>
597
597
  ))}
@@ -599,19 +599,19 @@ const sectionVariantFieldNames = Object.fromEntries(
599
599
  <div class:list={["space-y-2", sectionFields.length > 0 && "pt-1"]}>
600
600
  {sectionVariantData?.variantType === "oneOf" ? (
601
601
  <>
602
- <p class="text-xs text-neutral-500">
602
+ <p class="text-xs text-neutral-500 dark:text-neutral-400">
603
603
  Select one variant.
604
604
  </p>
605
- <div class="inline-flex max-w-full flex-wrap items-center gap-1 rounded-lg bg-neutral-100 p-1">
605
+ <div class="inline-flex max-w-full flex-wrap items-center gap-1 rounded-lg bg-neutral-100 p-1 dark:bg-neutral-900/60">
606
606
  {sectionVariants.map((variant, variantIndex) => (
607
607
  <button
608
608
  type="button"
609
609
  @click={`selectSectionVariant(${keyLiteral}, ${variantIndex})`}
610
610
  :class={`{
611
- 'bg-white text-neutral-900 shadow-xs ring-1 ring-neutral-200': getSelectedSectionVariant(${keyLiteral}) === ${variantIndex},
612
- 'text-neutral-600 hover:bg-neutral-50 hover:text-neutral-800': getSelectedSectionVariant(${keyLiteral}) !== ${variantIndex}
611
+ 'bg-white text-neutral-900 shadow-xs ring-1 ring-neutral-200 dark:bg-(--rd-code-surface) dark:text-neutral-100 dark:ring-neutral-700/70': getSelectedSectionVariant(${keyLiteral}) === ${variantIndex},
612
+ 'text-neutral-600 hover:bg-neutral-50 hover:text-neutral-800 dark:text-neutral-400 dark:hover:bg-neutral-800/70 dark:hover:text-neutral-200': getSelectedSectionVariant(${keyLiteral}) !== ${variantIndex}
613
613
  }`}
614
- class="inline-flex h-7 items-center justify-center whitespace-nowrap rounded-md px-2.5 text-[11px] font-medium transition-all duration-200 cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-300"
614
+ class="inline-flex h-7 items-center justify-center whitespace-nowrap rounded-md px-2.5 text-[11px] font-medium transition-all duration-200 cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-300 dark:focus-visible:ring-neutral-700"
615
615
  >
616
616
  {variant.label}
617
617
  </button>
@@ -622,13 +622,13 @@ const sectionVariantFieldNames = Object.fromEntries(
622
622
  x-show={`getSelectedSectionVariant(${keyLiteral}) === ${variantIndex}`}
623
623
  x-cloak
624
624
  >
625
- <div class="rounded-md border border-neutral-200 bg-white p-2.5">
626
- <div class="mb-2 text-xs font-medium text-neutral-600">
625
+ <div class="rounded-md border border-neutral-200 bg-white p-2.5 dark:border-neutral-800 dark:bg-neutral-900/60">
626
+ <div class="mb-2 text-xs font-medium text-neutral-600 dark:text-neutral-400">
627
627
  {variant.label}
628
628
  </div>
629
629
  <div class="space-y-3">
630
630
  {variant.fields.map((field) => (
631
- <div class="border-b border-b-neutral-100 last:border-none pb-3 last:pb-0">
631
+ <div class="border-b border-b-neutral-100 dark:border-b-neutral-800 last:border-none pb-3 last:pb-0">
632
632
  <PlaygroundField
633
633
  field={field}
634
634
  requestPart={key}
@@ -643,17 +643,17 @@ const sectionVariantFieldNames = Object.fromEntries(
643
643
  </>
644
644
  ) : (
645
645
  <>
646
- <p class="text-xs text-neutral-500">
646
+ <p class="text-xs text-neutral-500 dark:text-neutral-400">
647
647
  One or more variants may apply.
648
648
  </p>
649
649
  {sectionVariants.map((variant) => (
650
- <div class="rounded-md border border-neutral-200 bg-white p-2.5">
651
- <div class="mb-2 text-xs font-medium text-neutral-600">
650
+ <div class="rounded-md border border-neutral-200 bg-white p-2.5 dark:border-neutral-800 dark:bg-neutral-900/60">
651
+ <div class="mb-2 text-xs font-medium text-neutral-600 dark:text-neutral-400">
652
652
  {variant.label}
653
653
  </div>
654
654
  <div class="space-y-3">
655
655
  {variant.fields.map((field) => (
656
- <div class="border-b border-b-neutral-100 last:border-none pb-3 last:pb-0">
656
+ <div class="border-b border-b-neutral-100 dark:border-b-neutral-800 last:border-none pb-3 last:pb-0">
657
657
  <PlaygroundField field={field} requestPart={key} />
658
658
  </div>
659
659
  ))}
@@ -689,17 +689,33 @@ const sectionVariantFieldNames = Object.fromEntries(
689
689
  @reference "../../styles/global.css";
690
690
 
691
691
  :global(pre code span.token.punctuation) {
692
- @apply text-[#24292E];
692
+ color: #24292e;
693
693
  }
694
694
 
695
695
  :global(pre code span.token.operator) {
696
- @apply text-[#24292E];
696
+ color: #24292e;
697
697
  }
698
698
 
699
699
  :global(pre code span.token.property) {
700
- @apply text-[#C62C2C];
700
+ color: #c62c2c;
701
701
  }
702
702
  :global(pre code span.token.string) {
703
- @apply text-[#1E7734];
703
+ color: #1e7734;
704
+ }
705
+
706
+ :global(.dark pre code span.token.punctuation) {
707
+ color: #c9d1d9;
708
+ }
709
+
710
+ :global(.dark pre code span.token.operator) {
711
+ color: #c9d1d9;
712
+ }
713
+
714
+ :global(.dark pre code span.token.property) {
715
+ color: #ff7b72;
716
+ }
717
+
718
+ :global(.dark pre code span.token.string) {
719
+ color: #a5d6ff;
704
720
  }
705
721
  </style>
@@ -131,25 +131,58 @@ const CURL_ICON_SVG = `<svg stroke="currentColor" fill="currentColor" stroke-wid
131
131
 
132
132
  function buildTokenStyle(token: {
133
133
  color?: string;
134
+ darkColor?: string;
134
135
  bgColor?: string;
136
+ darkBgColor?: string;
135
137
  fontStyle?: number;
136
138
  htmlStyle?: Record<string, string>;
139
+ darkHtmlStyle?: Record<string, string>;
137
140
  }): string | undefined {
138
141
  const styleSegments: string[] = [];
139
142
 
140
- if (token.color) styleSegments.push(`color:${token.color}`);
141
- if (token.bgColor) styleSegments.push(`background-color:${token.bgColor}`);
143
+ const pushStyleVariable = (property: string, value?: string) => {
144
+ if (value) styleSegments.push(`${property}:${value}`);
145
+ };
146
+
147
+ pushStyleVariable("--rd-token-color", token.color);
148
+ pushStyleVariable("--rd-token-color-dark", token.darkColor);
149
+ pushStyleVariable("--rd-token-bg", token.bgColor);
150
+ pushStyleVariable("--rd-token-bg-dark", token.darkBgColor);
142
151
 
143
152
  const fontStyle = typeof token.fontStyle === "number" ? token.fontStyle : 0;
144
153
  if ((fontStyle & 1) === 1) styleSegments.push("font-style:italic");
145
154
  if ((fontStyle & 2) === 2) styleSegments.push("font-weight:600");
146
155
  if ((fontStyle & 4) === 4) styleSegments.push("text-decoration:underline");
147
156
 
148
- if (token.htmlStyle && typeof token.htmlStyle === "object") {
149
- for (const [property, value] of Object.entries(token.htmlStyle)) {
157
+ const pushHtmlStyle = (
158
+ styleObject: Record<string, string> | undefined,
159
+ isDarkStyle: boolean,
160
+ ) => {
161
+ if (!styleObject || typeof styleObject !== "object") return;
162
+
163
+ for (const [property, value] of Object.entries(styleObject)) {
164
+ const normalizedProperty = property.trim().toLowerCase();
165
+ if (normalizedProperty === "color") {
166
+ pushStyleVariable(
167
+ isDarkStyle ? "--rd-token-color-dark" : "--rd-token-color",
168
+ value,
169
+ );
170
+ continue;
171
+ }
172
+ if (normalizedProperty === "background-color") {
173
+ pushStyleVariable(
174
+ isDarkStyle ? "--rd-token-bg-dark" : "--rd-token-bg",
175
+ value,
176
+ );
177
+ continue;
178
+ }
179
+
150
180
  styleSegments.push(`${property}:${value}`);
151
181
  }
152
- }
182
+ };
183
+
184
+ pushHtmlStyle(token.htmlStyle, false);
185
+ pushHtmlStyle(token.darkHtmlStyle, true);
153
186
 
154
187
  if (!styleSegments.length) return undefined;
155
188
  return styleSegments.join(";");
@@ -194,7 +227,7 @@ async function renderCodeLinesHtml(
194
227
  const tokenStyleAttribute = tokenStyle
195
228
  ? ` style="${escapeAttribute(tokenStyle)}"`
196
229
  : "";
197
- return `<span${tokenStyleAttribute}>${escapeHtml(token.content)}</span>`;
230
+ return `<span data-rd-token${tokenStyleAttribute}>${escapeHtml(token.content)}</span>`;
198
231
  })
199
232
  .join("")
200
233
  : fallbackLineContent.length > 0
@@ -350,10 +383,10 @@ const hasMultipleRequests = requestSnippetItems.length > 1;
350
383
  >
351
384
  <div class="group/prose-code not-prose relative h-full min-h-0 w-full max-w-full min-w-0">
352
385
  <div
353
- class="flex h-full min-h-0 w-full max-w-full min-w-0 flex-col overflow-hidden rounded-xl border border-neutral-200 bg-white shadow-xs"
386
+ class="flex h-full min-h-0 w-full max-w-full min-w-0 flex-col overflow-hidden rounded-xl border border-neutral-200 bg-white shadow-xs dark:border-neutral-800 dark:bg-(--rd-code-surface)"
354
387
  >
355
388
  <div
356
- class="flex items-center justify-between gap-2 border-b border-neutral-200 bg-neutral-50 rounded-t-xl inset-shadow-sm inset-shadow-neutral-100/80"
389
+ class="flex items-center justify-between gap-2 border-b border-neutral-200 bg-neutral-50 rounded-t-xl inset-shadow-sm inset-shadow-neutral-100/80 dark:border-neutral-800 dark:bg-neutral-900/60 dark:inset-shadow-neutral-900/80"
357
390
  >
358
391
  {
359
392
  hasMultipleRequests ? (
@@ -364,7 +397,7 @@ const hasMultipleRequests = requestSnippetItems.length > 1;
364
397
  >
365
398
  <div
366
399
  aria-hidden="true"
367
- class="pointer-events-none absolute top-1/2 z-0 h-[28px] -translate-y-1/2 rounded-lg border-[0.5px] border-neutral-200 bg-white shadow-xs transition-[left,width,opacity] duration-200 ease-out"
400
+ class="pointer-events-none absolute top-1/2 z-0 h-[28px] -translate-y-1/2 rounded-lg border-[0.5px] border-neutral-200 bg-white shadow-xs transition-[left,width,opacity] duration-200 ease-out dark:border-neutral-700/70 dark:bg-(--rd-code-surface)"
368
401
  x-bind:class="pillVisible ? 'opacity-100' : 'opacity-0'"
369
402
  x-bind:style="'left:' + pillLeft + 'px;width:' + pillWidth + 'px;'"
370
403
  />
@@ -378,7 +411,7 @@ const hasMultipleRequests = requestSnippetItems.length > 1;
378
411
  x-bind:data-rd-snippet-tab="index"
379
412
  x-on:click="select(index)"
380
413
  class="relative z-10 inline-flex h-9 items-center gap-2 border-0 bg-transparent px-3 py-1.5 text-xs font-medium transition-colors duration-150 focus:outline-none focus-visible:outline-none cursor-pointer"
381
- x-bind:class="selected === index ? 'text-neutral-900' : 'text-neutral-600'"
414
+ x-bind:class="selected === index ? 'text-foreground' : 'text-muted-foreground'"
382
415
  >
383
416
  <span
384
417
  x-show="snippet.iconSvg"
@@ -392,13 +425,13 @@ const hasMultipleRequests = requestSnippetItems.length > 1;
392
425
  </div>
393
426
  ) : (
394
427
  <div class="min-w-0 flex-1">
395
- <div class="relative h-9 w-fit max-w-full rounded-tl-xl bg-white">
396
- <div class="absolute inset-x-0 -bottom-px h-px bg-white"></div>
428
+ <div class="relative h-9 w-fit max-w-full rounded-tl-xl bg-white dark:bg-(--rd-code-surface)">
429
+ <div class="absolute inset-x-0 -bottom-px h-px bg-white dark:bg-(--rd-code-surface)"></div>
397
430
  <CodeTabEdge
398
431
  className="pointer-events-none absolute -top-px left-full z-10 h-[calc(100%+2px)]"
399
432
  />
400
433
 
401
- <div class="relative z-20 inline-flex h-9 max-w-full items-center gap-2 pl-5 pr-3 py-1.5 text-xs font-medium text-neutral-700">
434
+ <div class="relative z-20 inline-flex h-9 max-w-full items-center gap-2 pl-5 pr-3 py-1.5 text-xs font-medium text-neutral-700 dark:text-neutral-300">
402
435
  <span
403
436
  class="size-3.5 shrink-0 self-center rounded-[4px]"
404
437
  set:html={firstSnippet.iconSvg}
@@ -410,15 +443,15 @@ const hasMultipleRequests = requestSnippetItems.length > 1;
410
443
  )
411
444
  }
412
445
 
413
- <div class="relative h-9 w-5 shrink-0 rounded-tr-xl bg-white">
414
- <div class="absolute inset-x-0 -bottom-px h-px bg-white"></div>
446
+ <div class="relative h-9 w-5 shrink-0 rounded-tr-xl bg-white dark:bg-(--rd-code-surface)">
447
+ <div class="absolute inset-x-0 -bottom-px h-px bg-white dark:bg-(--rd-code-surface)"></div>
415
448
  <CodeTabEdge
416
449
  className="pointer-events-none absolute -top-px right-full z-10 h-[calc(100%+2px)] rotate-y-180"
417
450
  />
418
451
  <button
419
452
  x-on:click="copySelected()"
420
453
  type="button"
421
- class="absolute right-2 top-1/2 z-20 inline-flex size-7 -translate-y-1/2 appearance-none items-center justify-center rounded-md border-0 bg-transparent text-neutral-500/80 shadow-none outline-none ring-0 transition-colors duration-150 hover:bg-neutral-50 hover:text-neutral-600 focus:outline-none focus-visible:outline-none focus:ring-0 focus-visible:ring-0 cursor-pointer"
454
+ class="absolute right-2 top-1/2 z-20 inline-flex size-7 -translate-y-1/2 appearance-none items-center justify-center rounded-md border-0 bg-transparent text-neutral-500/80 shadow-none outline-none ring-0 transition-colors duration-150 hover:bg-neutral-50 hover:text-neutral-600 focus:outline-none focus-visible:outline-none focus:ring-0 focus-visible:ring-0 cursor-pointer dark:text-neutral-400 dark:hover:bg-neutral-800 dark:hover:text-neutral-200"
422
455
  aria-label="Copy code"
423
456
  >
424
457
  <Icon
@@ -429,7 +462,7 @@ const hasMultipleRequests = requestSnippetItems.length > 1;
429
462
  />
430
463
  <Icon
431
464
  name="lucide:check"
432
- class="absolute size-3.5 stroke-3 origin-center text-green-700/80 transition-all duration-250 ease-[cubic-bezier(0.22,1,0.36,1)] will-change-transform motion-reduce:transition-none"
465
+ class="absolute size-3.5 stroke-3 origin-center text-green-700/80 transition-all duration-250 ease-[cubic-bezier(0.22,1,0.36,1)] will-change-transform motion-reduce:transition-none dark:text-green-400/90"
433
466
  x-bind:class="copied ? 'scale-110 opacity-100 rotate-0' : 'scale-25 opacity-0 rotate-6'"
434
467
  aria-hidden="true"
435
468
  />
@@ -438,16 +471,16 @@ const hasMultipleRequests = requestSnippetItems.length > 1;
438
471
  </div>
439
472
 
440
473
  <div class="relative min-h-0 min-w-0 flex-1 overflow-hidden rounded-b-xl">
441
- <div class="relative h-full overflow-auto [scrollbar-width:thin] [scrollbar-color:var(--color-neutral-300)_transparent] [&::-webkit-scrollbar]:h-1.5 [&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-neutral-300/70 hover:[&::-webkit-scrollbar-thumb]:bg-neutral-300/90">
442
- <div class="pointer-events-none sticky top-0 z-10 -mb-4 h-4 w-full bg-linear-to-b from-white to-transparent"></div>
474
+ <div class="relative h-full overflow-auto [scrollbar-width:thin] [scrollbar-color:var(--color-neutral-300)_transparent] [&::-webkit-scrollbar]:h-1.5 [&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-neutral-300/70 hover:[&::-webkit-scrollbar-thumb]:bg-neutral-300/90 dark:[scrollbar-color:var(--color-neutral-700)_transparent] dark:[&::-webkit-scrollbar-thumb]:bg-neutral-700/70 dark:hover:[&::-webkit-scrollbar-thumb]:bg-neutral-700/90">
475
+ <div class="pointer-events-none sticky top-0 z-10 -mb-4 h-4 w-full bg-linear-to-b from-white to-transparent dark:from-(--rd-code-surface)"></div>
443
476
  {
444
477
  requestSnippetItems.map((snippet, index) => (
445
478
  <pre
446
- class="relative m-0 min-w-full bg-white p-0 text-[13px] leading-6"
479
+ class="relative m-0 min-w-full bg-white p-0 text-[13px] leading-6 dark:bg-(--rd-code-surface)"
447
480
  x-show={`selected === ${index}`}
448
481
  {...(index !== 0 ? { "x-cloak": true } : {})}
449
482
  data-snippet-index={index}
450
- ><code class="block min-w-full py-2.5 font-mono text-neutral-800"><Fragment set:html={snippet.renderedCodeLinesHtml} /></code></pre>
483
+ ><code data-rd-code-theme class="block min-w-full py-2.5 font-mono text-neutral-800 dark:text-neutral-200"><Fragment set:html={snippet.renderedCodeLinesHtml} /></code></pre>
451
484
  ))
452
485
  }
453
486
  </div>
@@ -72,10 +72,10 @@ import { Icon } from "astro-icon/components";
72
72
  class="group/prose-code not-prose relative h-full min-h-0 w-full max-w-full min-w-0"
73
73
  >
74
74
  <div
75
- class="flex h-full min-h-0 w-full max-w-full min-w-0 flex-col overflow-hidden rounded-xl border border-neutral-200 bg-white shadow-xs"
75
+ class="flex h-full min-h-0 w-full max-w-full min-w-0 flex-col overflow-hidden rounded-xl border border-neutral-200 bg-white shadow-xs dark:border-neutral-800 dark:bg-(--rd-code-surface)"
76
76
  >
77
77
  <div
78
- class="flex items-center justify-between gap-2 border-b border-neutral-200 rounded-t-xl bg-neutral-50 inset-shadow-sm inset-shadow-neutral-100/80"
78
+ class="flex items-center justify-between gap-2 border-b border-neutral-200 rounded-t-xl bg-neutral-50 inset-shadow-sm inset-shadow-neutral-100/80 dark:border-neutral-800 dark:bg-neutral-900/60 dark:inset-shadow-neutral-900/80"
79
79
  >
80
80
  <div class="min-w-0 flex-1 overflow-hidden rounded-t-xl">
81
81
  <div
@@ -84,7 +84,7 @@ import { Icon } from "astro-icon/components";
84
84
  >
85
85
  <div
86
86
  aria-hidden="true"
87
- class="pointer-events-none absolute top-1/2 z-0 h-[28px] -translate-y-1/2 rounded-lg border-[0.5px] border-neutral-200 bg-white shadow-xs transition-[left,width,opacity] duration-200 ease-out"
87
+ class="pointer-events-none absolute top-1/2 z-0 h-[28px] -translate-y-1/2 rounded-lg border-[0.5px] border-neutral-200 bg-white shadow-xs transition-[left,width,opacity] duration-200 ease-out dark:border-neutral-700/70 dark:bg-(--rd-code-surface)"
88
88
  x-bind:class="pillVisible ? 'opacity-100' : 'opacity-0'"
89
89
  x-bind:style="'left:' + pillLeft + 'px;width:' + pillWidth + 'px;'"
90
90
  >
@@ -96,7 +96,7 @@ import { Icon } from "astro-icon/components";
96
96
  x-bind:data-rd-response-tab="tab.id"
97
97
  x-on:click="select(tab.id)"
98
98
  class="relative z-10 inline-flex h-9 items-center gap-2 border-0 bg-transparent px-3 py-1.5 text-xs font-medium transition-colors duration-150 focus:outline-none focus-visible:outline-none cursor-pointer"
99
- x-bind:class="selected === tab.id ? 'text-neutral-900' : 'text-neutral-600'"
99
+ x-bind:class="selected === tab.id ? 'text-foreground' : 'text-muted-foreground'"
100
100
  >
101
101
  <span class="whitespace-pre leading-none" x-text="tab.label"
102
102
  ></span>
@@ -106,9 +106,9 @@ import { Icon } from "astro-icon/components";
106
106
  </div>
107
107
 
108
108
  <div
109
- class="relative h-9 w-fit max-w-full shrink-0 rounded-tr-xl bg-white"
109
+ class="relative h-9 w-fit max-w-full shrink-0 rounded-tr-xl bg-white dark:bg-(--rd-code-surface)"
110
110
  >
111
- <div class="absolute inset-x-0 -bottom-px h-px bg-white"></div>
111
+ <div class="absolute inset-x-0 -bottom-px h-px bg-white dark:bg-(--rd-code-surface)"></div>
112
112
  <CodeTabEdge
113
113
  className="pointer-events-none absolute -top-px right-full z-10 h-[calc(100%+2px)] rotate-y-180"
114
114
  />
@@ -118,16 +118,16 @@ import { Icon } from "astro-icon/components";
118
118
  <span
119
119
  class="size-[7px] shrink-0 rounded-full"
120
120
  x-bind:class="{
121
- 'bg-green-700/70': Math.floor((response?.status || 0) / 100) === 2,
122
- 'bg-blue-700/70': Math.floor((response?.status || 0) / 100) === 3,
123
- 'bg-yellow-500/80': Math.floor((response?.status || 0) / 100) === 4,
124
- 'bg-red-700/70': Math.floor((response?.status || 0) / 100) === 5,
125
- 'bg-neutral-300': !response?.status || Math.floor((response?.status || 0) / 100) < 2
121
+ 'bg-green-700/70 dark:bg-green-400/80': Math.floor((response?.status || 0) / 100) === 2,
122
+ 'bg-blue-700/70 dark:bg-blue-400/80': Math.floor((response?.status || 0) / 100) === 3,
123
+ 'bg-yellow-500/80 dark:bg-yellow-400/90': Math.floor((response?.status || 0) / 100) === 4,
124
+ 'bg-red-700/70 dark:bg-red-400/80': Math.floor((response?.status || 0) / 100) === 5,
125
+ 'bg-neutral-300 dark:bg-neutral-600': !response?.status || Math.floor((response?.status || 0) / 100) < 2
126
126
  }"
127
127
  ></span>
128
128
  <span
129
129
  class="leading-none"
130
- x-bind:class="response?.status ? 'text-neutral-700' : 'text-neutral-300'"
130
+ x-bind:class="response?.status ? 'text-foreground' : 'text-muted-foreground'"
131
131
  x-text="response?.status ?? '---'"></span>
132
132
  </div>
133
133
  </div>
@@ -135,53 +135,53 @@ import { Icon } from "astro-icon/components";
135
135
 
136
136
  <div class="relative min-h-0 min-w-0 flex-1 overflow-hidden rounded-b-xl">
137
137
  <div
138
- class="relative h-full overflow-auto [scrollbar-width:thin] [scrollbar-color:var(--color-neutral-300)_transparent] [&::-webkit-scrollbar]:h-1.5 [&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-neutral-300/70 hover:[&::-webkit-scrollbar-thumb]:bg-neutral-300/90"
138
+ class="relative h-full overflow-auto [scrollbar-width:thin] [scrollbar-color:var(--color-neutral-300)_transparent] [&::-webkit-scrollbar]:h-1.5 [&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-neutral-300/70 hover:[&::-webkit-scrollbar-thumb]:bg-neutral-300/90 dark:[scrollbar-color:var(--color-neutral-700)_transparent] dark:[&::-webkit-scrollbar-thumb]:bg-neutral-700/70 dark:hover:[&::-webkit-scrollbar-thumb]:bg-neutral-700/90"
139
139
  >
140
140
  <div
141
- class="pointer-events-none sticky top-0 z-10 -mb-4 h-4 w-full bg-linear-to-b from-white to-transparent"
141
+ class="pointer-events-none sticky top-0 z-10 -mb-4 h-4 w-full bg-linear-to-b from-white to-transparent dark:from-(--rd-code-surface)"
142
142
  >
143
143
  </div>
144
144
  <div x-show="selected === 'body'" class="h-full">
145
145
  <div
146
146
  x-show="!response || !response.highlightedData"
147
- class="text-sm px-4 py-4 xs:py-8 flex flex-col items-center justify-center h-full"
147
+ class="text-sm px-4 py-4 xs:py-8 flex flex-col items-center justify-center h-full text-foreground"
148
148
  >
149
- <div class="bg-neutral-50 p-2 rounded-xl mb-1">
149
+ <div class="bg-neutral-50 p-2 rounded-xl mb-1 dark:bg-(--rd-code-surface)">
150
150
  <Icon
151
- class="size-6 text-neutral-300"
151
+ class="size-6 text-neutral-300 dark:text-neutral-600"
152
152
  name="lucide:square-arrow-up-right"
153
153
  />
154
154
  </div>
155
155
  <div class="text-lg font-medium text-center">Send request</div>
156
- <p class="text-sm text-neutral-500 text-center">
156
+ <p class="text-sm text-neutral-500 text-center dark:text-neutral-400">
157
157
  Send a request to see the response body.
158
158
  </p>
159
159
  </div>
160
160
  <div x-show="response && response.highlightedData">
161
161
  <pre
162
- class="relative m-0 min-w-full bg-white p-0 text-[13px] leading-6"><code class="block min-w-full px-4 py-2.5 font-mono text-neutral-800" x-html="response?.highlightedData" /></pre>
162
+ class="relative m-0 min-w-full bg-white p-0 text-[13px] leading-6 dark:bg-(--rd-code-surface)"><code data-rd-code-theme class="block min-w-full px-4 py-2.5 font-mono text-neutral-800 dark:text-neutral-200" x-html="response?.highlightedData" /></pre>
163
163
  </div>
164
164
  </div>
165
165
 
166
166
  <div x-show="selected === 'header'" x-cloak class="h-full">
167
167
  <div
168
168
  x-show="!response || !response.highlightedHeaders"
169
- class="text-sm px-4 py-4 xs:py-8 flex flex-col items-center justify-center h-full"
169
+ class="text-sm px-4 py-4 xs:py-8 flex flex-col items-center justify-center h-full text-foreground"
170
170
  >
171
- <div class="bg-neutral-50 p-2 rounded-xl mb-1">
171
+ <div class="bg-neutral-50 p-2 rounded-xl mb-1 dark:bg-(--rd-code-surface)">
172
172
  <Icon
173
- class="size-6 text-neutral-300"
173
+ class="size-6 text-neutral-300 dark:text-neutral-600"
174
174
  name="lucide:square-arrow-up-right"
175
175
  />
176
176
  </div>
177
177
  <div class="text-lg font-medium text-center">Send request</div>
178
- <p class="text-sm text-neutral-500 text-center">
178
+ <p class="text-sm text-neutral-500 text-center dark:text-neutral-400">
179
179
  Send a request to see the response header.
180
180
  </p>
181
181
  </div>
182
182
  <div x-show="response && response.highlightedHeaders">
183
183
  <pre
184
- class="relative m-0 min-w-full bg-white p-0 text-[13px] leading-6"><code class="block min-w-full px-4 py-2.5 font-mono text-neutral-800" x-html="response?.highlightedHeaders" /></pre>
184
+ class="relative m-0 min-w-full bg-white p-0 text-[13px] leading-6 dark:bg-(--rd-code-surface)"><code data-rd-code-theme class="block min-w-full px-4 py-2.5 font-mono text-neutral-800 dark:text-neutral-200" x-html="response?.highlightedHeaders" /></pre>
185
185
  </div>
186
186
  </div>
187
187
  </div>
@@ -46,7 +46,7 @@ function countImmediateChildren(field: ResponseField): number {
46
46
  }
47
47
  ---
48
48
 
49
- <div class="flex flex-col gap-4 divide-y divide-neutral-100 *:pb-3 *:last:pb-0">
49
+ <div class="flex flex-col gap-4 divide-y divide-neutral-100 dark:divide-neutral-800 *:pb-3 *:last:pb-0">
50
50
  {
51
51
  fields.map((field) => {
52
52
  const revealedFieldCount = countImmediateChildren(field);
@@ -70,17 +70,17 @@ function countImmediateChildren(field: ResponseField): number {
70
70
  />
71
71
  {hasExpandableContent && (
72
72
  <div
73
- class="mt-2 w-full overflow-hidden rounded-lg border border-neutral-200 bg-white transition-colors duration-200"
74
- x-bind:class="expanded ? 'border-neutral-300' : 'border-neutral-200'"
73
+ class="mt-2 w-full overflow-hidden rounded-lg border border-neutral-200 bg-white transition-colors duration-200 dark:border-neutral-800 dark:bg-(--rd-code-surface)"
74
+ x-bind:class="expanded ? 'border-neutral-300 dark:border-neutral-700' : 'border-neutral-200 dark:border-neutral-800'"
75
75
  >
76
76
  <button
77
77
  type="button"
78
78
  x-on:click="expanded = !expanded"
79
79
  x-bind:aria-expanded="expanded"
80
- class="group flex w-full items-center justify-between gap-3 px-3 py-2 text-left text-xs font-medium text-neutral-700 hover:bg-neutral-50 cursor-pointer transition-colors duration-200"
80
+ class="group flex w-full items-center justify-between gap-3 px-3 py-2 text-left text-xs font-medium text-neutral-700 hover:bg-neutral-50 cursor-pointer transition-colors duration-200 dark:text-neutral-300 dark:hover:bg-neutral-800/60"
81
81
  >
82
82
  <span class="inline-flex items-center gap-2">
83
- <ListChevronsToggle class="size-4 shrink-0 text-neutral-400 group-hover:text-neutral-600 transition duration-200" />
83
+ <ListChevronsToggle class="size-4 shrink-0 text-neutral-400 group-hover:text-neutral-600 transition duration-200 dark:text-neutral-500 dark:group-hover:text-neutral-300" />
84
84
  <span>
85
85
  {revealedFieldCount}{" "}
86
86
  {revealedFieldCount === 1
@@ -90,21 +90,21 @@ function countImmediateChildren(field: ResponseField): number {
90
90
  </span>
91
91
  </button>
92
92
  <div x-show="expanded" x-collapse x-cloak>
93
- <div class="border-t border-neutral-100 px-3 py-3">
93
+ <div class="border-t border-neutral-100 px-3 py-3 dark:border-neutral-800">
94
94
  {field.nested && field.nested.length > 0 && nestedFieldCount > 0 && (
95
95
  <Astro.self fields={field.nested} depth={depth + 1} />
96
96
  )}
97
97
  {field.variants && field.variants.length > 0 && (
98
98
  <div class:list={["space-y-2", nestedFieldCount > 0 && "mt-3"]}>
99
- <p class="text-xs text-neutral-500">
99
+ <p class="text-xs text-neutral-500 dark:text-neutral-400">
100
100
  {field.variantType === "anyOf"
101
101
  ? "One or more variants may apply."
102
102
  : "One of these variants applies."}
103
103
  </p>
104
104
  {field.variants.map((variant, index) => (
105
105
  <>
106
- <div class="rounded-lg border border-neutral-200 bg-white p-3">
107
- <div class="mb-2 text-xs font-medium text-neutral-600">
106
+ <div class="rounded-lg border border-neutral-200 bg-white p-3 dark:border-neutral-800 dark:bg-neutral-900/60">
107
+ <div class="mb-2 text-xs font-medium text-neutral-600 dark:text-neutral-400">
108
108
  {variant.label}
109
109
  </div>
110
110
  <Astro.self fields={variant.fields} depth={depth + 1} />
@@ -112,11 +112,11 @@ function countImmediateChildren(field: ResponseField): number {
112
112
  {field.variantType === "oneOf" &&
113
113
  index < field.variants.length - 1 && (
114
114
  <div class="flex items-center gap-2 py-0">
115
- <div class="h-px flex-1 bg-neutral-200" />
116
- <span class="px-1 text-[10px] uppercase tracking-wide text-neutral-500">
115
+ <div class="h-px flex-1 bg-neutral-200 dark:bg-neutral-800" />
116
+ <span class="px-1 text-[10px] uppercase tracking-wide text-neutral-500 dark:text-neutral-400">
117
117
  OR
118
118
  </span>
119
- <div class="h-px flex-1 bg-neutral-200" />
119
+ <div class="h-px flex-1 bg-neutral-200 dark:bg-neutral-800" />
120
120
  </div>
121
121
  )}
122
122
  </>