boltdocs 1.0.4 → 1.3.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.
Files changed (121) hide show
  1. package/dist/{SearchDialog-R36WKAQ7.mjs → SearchDialog-5EDRACEG.mjs} +1 -1
  2. package/dist/{SearchDialog-PYF3QMYG.css → SearchDialog-X57WPTNN.css} +54 -126
  3. package/dist/cache-EHR7SXRU.mjs +12 -0
  4. package/dist/chunk-GSYECEZY.mjs +381 -0
  5. package/dist/{chunk-TWSRXUFF.mjs → chunk-NS7WHDYA.mjs} +229 -418
  6. package/dist/client/index.css +54 -126
  7. package/dist/client/index.d.mts +5 -4
  8. package/dist/client/index.d.ts +5 -4
  9. package/dist/client/index.js +555 -580
  10. package/dist/client/index.mjs +304 -16
  11. package/dist/client/ssr.css +54 -126
  12. package/dist/client/ssr.js +257 -580
  13. package/dist/client/ssr.mjs +1 -1
  14. package/dist/{config-D2XmHJYe.d.mts → config-BD5ZHz15.d.mts} +7 -0
  15. package/dist/{config-D2XmHJYe.d.ts → config-BD5ZHz15.d.ts} +7 -0
  16. package/dist/node/index.d.mts +2 -2
  17. package/dist/node/index.d.ts +2 -2
  18. package/dist/node/index.js +477 -123
  19. package/dist/node/index.mjs +114 -142
  20. package/package.json +2 -2
  21. package/src/client/app/index.tsx +344 -373
  22. package/src/client/app/preload.tsx +56 -56
  23. package/src/client/index.ts +40 -40
  24. package/src/client/ssr.tsx +51 -51
  25. package/src/client/theme/components/CodeBlock/CodeBlock.tsx +76 -76
  26. package/src/client/theme/components/CodeBlock/index.ts +1 -1
  27. package/src/client/theme/components/PackageManagerTabs/PackageManagerTabs.tsx +154 -154
  28. package/src/client/theme/components/PackageManagerTabs/index.ts +1 -1
  29. package/src/client/theme/components/PackageManagerTabs/pkg-tabs.css +64 -64
  30. package/src/client/theme/components/Playground/Playground.tsx +124 -124
  31. package/src/client/theme/components/Playground/index.ts +1 -1
  32. package/src/client/theme/components/Playground/playground.css +168 -168
  33. package/src/client/theme/components/Video/Video.tsx +84 -84
  34. package/src/client/theme/components/Video/index.ts +1 -1
  35. package/src/client/theme/components/Video/video.css +41 -41
  36. package/src/client/theme/components/mdx/Admonition.tsx +80 -80
  37. package/src/client/theme/components/mdx/Badge.tsx +31 -31
  38. package/src/client/theme/components/mdx/Button.tsx +50 -50
  39. package/src/client/theme/components/mdx/Card.tsx +80 -80
  40. package/src/client/theme/components/mdx/List.tsx +57 -57
  41. package/src/client/theme/components/mdx/Tabs.tsx +94 -94
  42. package/src/client/theme/components/mdx/index.ts +18 -18
  43. package/src/client/theme/components/mdx/mdx-components.css +424 -405
  44. package/src/client/theme/icons/bun.tsx +62 -62
  45. package/src/client/theme/icons/deno.tsx +20 -20
  46. package/src/client/theme/icons/discord.tsx +12 -12
  47. package/src/client/theme/icons/github.tsx +15 -15
  48. package/src/client/theme/icons/npm.tsx +13 -13
  49. package/src/client/theme/icons/pnpm.tsx +72 -72
  50. package/src/client/theme/icons/twitter.tsx +12 -12
  51. package/src/client/theme/styles/markdown.css +343 -343
  52. package/src/client/theme/styles/variables.css +162 -162
  53. package/src/client/theme/styles.css +37 -38
  54. package/src/client/theme/ui/BackgroundGradient/BackgroundGradient.tsx +10 -10
  55. package/src/client/theme/ui/BackgroundGradient/index.ts +1 -1
  56. package/src/client/theme/ui/Breadcrumbs/Breadcrumbs.tsx +68 -68
  57. package/src/client/theme/ui/Breadcrumbs/index.ts +1 -1
  58. package/src/client/theme/ui/Footer/footer.css +32 -32
  59. package/src/client/theme/ui/Head/Head.tsx +69 -69
  60. package/src/client/theme/ui/Head/index.ts +1 -1
  61. package/src/client/theme/ui/LanguageSwitcher/LanguageSwitcher.tsx +125 -125
  62. package/src/client/theme/ui/LanguageSwitcher/index.ts +1 -1
  63. package/src/client/theme/ui/LanguageSwitcher/language-switcher.css +98 -98
  64. package/src/client/theme/ui/Layout/Layout.tsx +202 -213
  65. package/src/client/theme/ui/Layout/base.css +76 -76
  66. package/src/client/theme/ui/Layout/index.ts +2 -2
  67. package/src/client/theme/ui/Layout/pagination.css +72 -72
  68. package/src/client/theme/ui/Layout/responsive.css +36 -40
  69. package/src/client/theme/ui/Link/Link.tsx +254 -202
  70. package/src/client/theme/ui/Link/index.ts +2 -2
  71. package/src/client/theme/ui/Loading/Loading.tsx +10 -10
  72. package/src/client/theme/ui/Loading/index.ts +1 -1
  73. package/src/client/theme/ui/Loading/loading.css +30 -30
  74. package/src/client/theme/ui/Navbar/GithubStars.tsx +27 -27
  75. package/src/client/theme/ui/Navbar/Navbar.tsx +145 -145
  76. package/src/client/theme/ui/Navbar/index.ts +2 -2
  77. package/src/client/theme/ui/Navbar/navbar.css +233 -233
  78. package/src/client/theme/ui/NotFound/NotFound.tsx +19 -20
  79. package/src/client/theme/ui/NotFound/index.ts +1 -1
  80. package/src/client/theme/ui/NotFound/not-found.css +64 -64
  81. package/src/client/theme/ui/OnThisPage/OnThisPage.tsx +235 -192
  82. package/src/client/theme/ui/OnThisPage/index.ts +1 -1
  83. package/src/client/theme/ui/OnThisPage/toc.css +132 -132
  84. package/src/client/theme/ui/PoweredBy/PoweredBy.tsx +18 -18
  85. package/src/client/theme/ui/PoweredBy/index.ts +1 -1
  86. package/src/client/theme/ui/PoweredBy/powered-by.css +76 -76
  87. package/src/client/theme/ui/SearchDialog/SearchDialog.tsx +199 -199
  88. package/src/client/theme/ui/SearchDialog/index.ts +1 -1
  89. package/src/client/theme/ui/SearchDialog/search.css +152 -152
  90. package/src/client/theme/ui/Sidebar/Sidebar.tsx +204 -200
  91. package/src/client/theme/ui/Sidebar/index.ts +1 -1
  92. package/src/client/theme/ui/Sidebar/sidebar.css +236 -269
  93. package/src/client/theme/ui/ThemeToggle/ThemeToggle.tsx +69 -69
  94. package/src/client/theme/ui/ThemeToggle/index.ts +1 -1
  95. package/src/client/theme/ui/VersionSwitcher/VersionSwitcher.tsx +136 -136
  96. package/src/client/theme/ui/VersionSwitcher/index.ts +1 -1
  97. package/src/client/types.ts +50 -50
  98. package/src/client/utils.ts +26 -26
  99. package/src/node/cache.ts +408 -94
  100. package/src/node/config.ts +192 -185
  101. package/src/node/index.ts +21 -21
  102. package/src/node/mdx.ts +120 -41
  103. package/src/node/plugin/entry.ts +58 -58
  104. package/src/node/plugin/html.ts +55 -55
  105. package/src/node/plugin/index.ts +193 -190
  106. package/src/node/plugin/types.ts +11 -11
  107. package/src/node/routes/cache.ts +28 -24
  108. package/src/node/routes/index.ts +167 -152
  109. package/src/node/routes/parser.ts +153 -127
  110. package/src/node/routes/sorter.ts +42 -42
  111. package/src/node/routes/types.ts +49 -49
  112. package/src/node/ssg/index.ts +114 -110
  113. package/src/node/ssg/meta.ts +34 -34
  114. package/src/node/ssg/options.ts +13 -13
  115. package/src/node/ssg/sitemap.ts +54 -54
  116. package/src/node/utils.ts +134 -134
  117. package/tsconfig.json +20 -20
  118. package/tsup.config.ts +22 -22
  119. package/dist/Playground-B2FA34BC.mjs +0 -6
  120. package/dist/chunk-WPT4MWTQ.mjs +0 -89
  121. package/src/client/theme/styles/home.css +0 -60
@@ -1,124 +1,124 @@
1
- import React, { useState } from "react";
2
- import { LiveProvider, LiveEditor, LiveError, LivePreview } from "react-live";
3
- import { Copy, Check, Terminal, Play } from "lucide-react";
4
-
5
- interface PlaygroundProps {
6
- code?: string;
7
- children?: string | React.ReactNode;
8
- scope?: Record<string, any>;
9
- readonly?: boolean;
10
- noInline?: boolean;
11
- }
12
-
13
- /**
14
- * Transforms code that uses `export default` into a format compatible
15
- * with react-live's `noInline` mode by stripping the export and
16
- * appending a `render(<ComponentName />)` call.
17
- */
18
- function prepareCode(raw: string): { code: string; noInline: boolean } {
19
- const trimmed = raw.trim();
20
-
21
- // Match: export default function Name(...)
22
- const fnMatch = trimmed.match(/export\s+default\s+function\s+(\w+)/);
23
- if (fnMatch) {
24
- const name = fnMatch[1];
25
- const code =
26
- trimmed.replace(/export\s+default\s+/, "") + `\n\nrender(<${name} />);`;
27
- return { code, noInline: true };
28
- }
29
-
30
- // Match: export default ComponentName (at the end)
31
- const varMatch = trimmed.match(/export\s+default\s+(\w+)\s*;?\s*$/);
32
- if (varMatch) {
33
- const name = varMatch[1];
34
- const code =
35
- trimmed.replace(/export\s+default\s+\w+\s*;?\s*$/, "") +
36
- `\nrender(<${name} />);`;
37
- return { code, noInline: true };
38
- }
39
-
40
- // No export default — use inline mode (simple JSX expression)
41
- return { code: trimmed, noInline: false };
42
- }
43
-
44
- /**
45
- * A live React playground component.
46
- * Features a split layout with a live editor and a preview section.
47
- *
48
- * Supports `export default function App()` style code out of the box.
49
- */
50
- export function Playground({
51
- code,
52
- children,
53
- scope = {},
54
- readonly = false,
55
- noInline: forceNoInline,
56
- }: PlaygroundProps) {
57
- // Extract code from either `code` prop or `children`
58
- let initialCode = code || "";
59
- if (!initialCode && typeof children === "string") {
60
- initialCode = children;
61
- }
62
-
63
- const prepared = prepareCode(initialCode);
64
- const useNoInline = forceNoInline ?? prepared.noInline;
65
-
66
- const [copied, setCopied] = useState(false);
67
- const [activeCode, setActiveCode] = useState(prepared.code);
68
-
69
- const handleCopy = () => {
70
- navigator.clipboard.writeText(activeCode);
71
- setCopied(true);
72
- setTimeout(() => setCopied(false), 2000);
73
- };
74
-
75
- // Provide React generically
76
- const extendedScope = { React, ...scope };
77
-
78
- return (
79
- <div className="boltdocs-playground" data-readonly={readonly}>
80
- <LiveProvider
81
- code={activeCode}
82
- scope={extendedScope}
83
- theme={undefined}
84
- noInline={useNoInline}
85
- >
86
- <div className="playground-split-container">
87
- {/* Editor Side */}
88
- <div className="playground-panel playground-editor-panel">
89
- <div className="playground-panel-header">
90
- <div className="playground-panel-title">
91
- <Terminal size={14} />
92
- <span>{readonly ? "Code Example" : "Live Editor"}</span>
93
- </div>
94
- <button
95
- className="playground-copy-btn"
96
- onClick={handleCopy}
97
- title="Copy code"
98
- >
99
- {copied ? <Check size={14} /> : <Copy size={14} />}
100
- </button>
101
- </div>
102
- <div className="playground-panel-content playground-editor">
103
- <LiveEditor disabled={readonly} onChange={setActiveCode} />
104
- </div>
105
- </div>
106
-
107
- {/* Preview Side */}
108
- <div className="playground-panel playground-preview-panel">
109
- <div className="playground-panel-header">
110
- <div className="playground-panel-title">
111
- <Play size={14} />
112
- <span>Preview</span>
113
- </div>
114
- </div>
115
- <div className="playground-panel-content playground-preview">
116
- <LivePreview />
117
- <LiveError className="playground-error" />
118
- </div>
119
- </div>
120
- </div>
121
- </LiveProvider>
122
- </div>
123
- );
124
- }
1
+ import React, { useState } from "react";
2
+ import { LiveProvider, LiveEditor, LiveError, LivePreview } from "react-live";
3
+ import { Copy, Check, Terminal, Play } from "lucide-react";
4
+
5
+ interface PlaygroundProps {
6
+ code?: string;
7
+ children?: string | React.ReactNode;
8
+ scope?: Record<string, any>;
9
+ readonly?: boolean;
10
+ noInline?: boolean;
11
+ }
12
+
13
+ /**
14
+ * Transforms code that uses `export default` into a format compatible
15
+ * with react-live's `noInline` mode by stripping the export and
16
+ * appending a `render(<ComponentName />)` call.
17
+ */
18
+ function prepareCode(raw: string): { code: string; noInline: boolean } {
19
+ const trimmed = raw.trim();
20
+
21
+ // Match: export default function Name(...)
22
+ const fnMatch = trimmed.match(/export\s+default\s+function\s+(\w+)/);
23
+ if (fnMatch) {
24
+ const name = fnMatch[1];
25
+ const code =
26
+ trimmed.replace(/export\s+default\s+/, "") + `\n\nrender(<${name} />);`;
27
+ return { code, noInline: true };
28
+ }
29
+
30
+ // Match: export default ComponentName (at the end)
31
+ const varMatch = trimmed.match(/export\s+default\s+(\w+)\s*;?\s*$/);
32
+ if (varMatch) {
33
+ const name = varMatch[1];
34
+ const code =
35
+ trimmed.replace(/export\s+default\s+\w+\s*;?\s*$/, "") +
36
+ `\nrender(<${name} />);`;
37
+ return { code, noInline: true };
38
+ }
39
+
40
+ // No export default — use inline mode (simple JSX expression)
41
+ return { code: trimmed, noInline: false };
42
+ }
43
+
44
+ /**
45
+ * A live React playground component.
46
+ * Features a split layout with a live editor and a preview section.
47
+ *
48
+ * Supports `export default function App()` style code out of the box.
49
+ */
50
+ export function Playground({
51
+ code,
52
+ children,
53
+ scope = {},
54
+ readonly = false,
55
+ noInline: forceNoInline,
56
+ }: PlaygroundProps) {
57
+ // Extract code from either `code` prop or `children`
58
+ let initialCode = code || "";
59
+ if (!initialCode && typeof children === "string") {
60
+ initialCode = children;
61
+ }
62
+
63
+ const prepared = prepareCode(initialCode);
64
+ const useNoInline = forceNoInline ?? prepared.noInline;
65
+
66
+ const [copied, setCopied] = useState(false);
67
+ const [activeCode, setActiveCode] = useState(prepared.code);
68
+
69
+ const handleCopy = () => {
70
+ navigator.clipboard.writeText(activeCode);
71
+ setCopied(true);
72
+ setTimeout(() => setCopied(false), 2000);
73
+ };
74
+
75
+ // Provide React generically
76
+ const extendedScope = { React, ...scope };
77
+
78
+ return (
79
+ <div className="boltdocs-playground" data-readonly={readonly}>
80
+ <LiveProvider
81
+ code={activeCode}
82
+ scope={extendedScope}
83
+ theme={undefined}
84
+ noInline={useNoInline}
85
+ >
86
+ <div className="playground-split-container">
87
+ {/* Editor Side */}
88
+ <div className="playground-panel playground-editor-panel">
89
+ <div className="playground-panel-header">
90
+ <div className="playground-panel-title">
91
+ <Terminal size={14} />
92
+ <span>{readonly ? "Code Example" : "Live Editor"}</span>
93
+ </div>
94
+ <button
95
+ className="playground-copy-btn"
96
+ onClick={handleCopy}
97
+ title="Copy code"
98
+ >
99
+ {copied ? <Check size={14} /> : <Copy size={14} />}
100
+ </button>
101
+ </div>
102
+ <div className="playground-panel-content playground-editor">
103
+ <LiveEditor disabled={readonly} onChange={setActiveCode} />
104
+ </div>
105
+ </div>
106
+
107
+ {/* Preview Side */}
108
+ <div className="playground-panel playground-preview-panel">
109
+ <div className="playground-panel-header">
110
+ <div className="playground-panel-title">
111
+ <Play size={14} />
112
+ <span>Preview</span>
113
+ </div>
114
+ </div>
115
+ <div className="playground-panel-content playground-preview">
116
+ <LivePreview />
117
+ <LiveError className="playground-error" />
118
+ </div>
119
+ </div>
120
+ </div>
121
+ </LiveProvider>
122
+ </div>
123
+ );
124
+ }
@@ -1 +1 @@
1
- export { Playground } from "./Playground";
1
+ export { Playground } from "./Playground";
@@ -1,168 +1,168 @@
1
- /* ═══════════════════════════════════════════════════════════
2
- PLAYGROUND (SPLIT UI)
3
- ═══════════════════════════════════════════════════════════ */
4
- .boltdocs-playground {
5
- display: flex;
6
- flex-direction: column;
7
- margin: 2rem 0;
8
- border-radius: var(--ld-radius-lg);
9
- border: 1px solid var(--ld-border-subtle);
10
- background: var(--ld-code-bg);
11
- overflow: hidden;
12
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
13
- backdrop-filter: blur(10px);
14
- }
15
-
16
- .playground-split-container {
17
- display: flex;
18
- flex-direction: column;
19
- width: 100%;
20
- }
21
-
22
- @media (min-width: 1024px) {
23
- .playground-split-container {
24
- flex-direction: row;
25
- min-height: 350px;
26
- align-items: stretch;
27
- }
28
- }
29
-
30
- .playground-panel {
31
- display: flex;
32
- flex-direction: column;
33
- flex: 1;
34
- min-width: 0;
35
- }
36
-
37
- .playground-editor-panel {
38
- border-bottom: 1px solid var(--ld-border-subtle);
39
- background: var(--ld-code-bg);
40
- }
41
-
42
- @media (min-width: 1024px) {
43
- .playground-editor-panel {
44
- border-bottom: none;
45
- border-right: 1px solid var(--ld-border-subtle);
46
- }
47
- }
48
-
49
- .playground-preview-panel {
50
- background: var(--ld-bg-mute);
51
- position: relative;
52
- }
53
-
54
- /* Header */
55
- .playground-panel-header {
56
- display: flex;
57
- align-items: center;
58
- justify-content: space-between;
59
- padding: 0.5rem 1rem;
60
- border-bottom: 1px solid var(--ld-border-subtle);
61
- background: rgba(0, 0, 0, 0.1);
62
- }
63
-
64
- .playground-panel-title {
65
- display: flex;
66
- align-items: center;
67
- gap: 0.5rem;
68
- font-size: 0.75rem;
69
- font-weight: 600;
70
- color: var(--ld-text-muted);
71
- text-transform: uppercase;
72
- letter-spacing: 0.05em;
73
- }
74
-
75
- /* Copy Button */
76
- .playground-copy-btn {
77
- background: transparent;
78
- border: none;
79
- color: var(--ld-text-muted);
80
- cursor: pointer;
81
- padding: 0.25rem;
82
- border-radius: var(--ld-radius-sm);
83
- display: flex;
84
- align-items: center;
85
- justify-content: center;
86
- transition: all 0.2s;
87
- }
88
-
89
- .playground-copy-btn:hover {
90
- background: rgba(255, 255, 255, 0.1);
91
- color: var(--ld-text-main);
92
- }
93
-
94
- /* Content Area */
95
- .playground-panel-content {
96
- flex: 1;
97
- overflow: auto;
98
- position: relative;
99
- display: flex;
100
- flex-direction: column;
101
- }
102
-
103
- /* Editor Specifics */
104
- .playground-editor {
105
- background: transparent;
106
- }
107
-
108
- .playground-editor > div {
109
- font-family: var(--ld-font-mono) !important;
110
- font-size: 0.85rem !important;
111
- line-height: 1.5 !important;
112
- min-height: 100%;
113
- }
114
-
115
- .playground-editor pre {
116
- padding: 1.5rem !important;
117
- margin: 0 !important;
118
- background: transparent !important;
119
- }
120
-
121
- .playground-editor textarea {
122
- outline: none !important;
123
- padding: 1.5rem !important;
124
- }
125
-
126
- /* Prevent editing styles if read-only */
127
- .boltdocs-playground[data-readonly="true"] .playground-editor textarea {
128
- cursor: default !important;
129
- }
130
-
131
- /* Preview Specifics */
132
- .playground-preview {
133
- padding: 2rem;
134
- display: flex;
135
- align-items: center;
136
- justify-content: center;
137
- background-color: var(--ld-bg-mute);
138
- background-image: radial-gradient(
139
- var(--ld-border-subtle) 1.5px,
140
- transparent 1.5px
141
- );
142
- background-size: 24px 24px;
143
- color: var(--ld-text-main);
144
- min-height: 200px;
145
- }
146
-
147
- /* Error Specifics */
148
- .playground-error {
149
- margin: 0;
150
- padding: 1rem;
151
- background: #7f1d1d;
152
- color: #fca5a5;
153
- font-size: 0.8rem;
154
- font-family: var(--ld-font-mono);
155
- white-space: pre-wrap;
156
- border-top: 1px solid #991b1b;
157
- z-index: 10;
158
- }
159
-
160
- /* Loading Skeleton */
161
- .playground-skeleton {
162
- height: 350px;
163
- background: var(--ld-bg-mute);
164
- border-radius: var(--ld-radius-lg);
165
- animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
166
- margin: 2rem 0;
167
- border: 1px solid var(--ld-border-subtle);
168
- }
1
+ /* ═══════════════════════════════════════════════════════════
2
+ PLAYGROUND (SPLIT UI)
3
+ ═══════════════════════════════════════════════════════════ */
4
+ .boltdocs-playground {
5
+ display: flex;
6
+ flex-direction: column;
7
+ margin: 2rem 0;
8
+ border-radius: var(--ld-radius-lg);
9
+ border: 1px solid var(--ld-border-subtle);
10
+ background: var(--ld-code-bg);
11
+ overflow: hidden;
12
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
13
+ backdrop-filter: blur(10px);
14
+ }
15
+
16
+ .playground-split-container {
17
+ display: flex;
18
+ flex-direction: column;
19
+ width: 100%;
20
+ }
21
+
22
+ @media (min-width: 1024px) {
23
+ .playground-split-container {
24
+ flex-direction: row;
25
+ min-height: 350px;
26
+ align-items: stretch;
27
+ }
28
+ }
29
+
30
+ .playground-panel {
31
+ display: flex;
32
+ flex-direction: column;
33
+ flex: 1;
34
+ min-width: 0;
35
+ }
36
+
37
+ .playground-editor-panel {
38
+ border-bottom: 1px solid var(--ld-border-subtle);
39
+ background: var(--ld-code-bg);
40
+ }
41
+
42
+ @media (min-width: 1024px) {
43
+ .playground-editor-panel {
44
+ border-bottom: none;
45
+ border-right: 1px solid var(--ld-border-subtle);
46
+ }
47
+ }
48
+
49
+ .playground-preview-panel {
50
+ background: var(--ld-bg-mute);
51
+ position: relative;
52
+ }
53
+
54
+ /* Header */
55
+ .playground-panel-header {
56
+ display: flex;
57
+ align-items: center;
58
+ justify-content: space-between;
59
+ padding: 0.5rem 1rem;
60
+ border-bottom: 1px solid var(--ld-border-subtle);
61
+ background: rgba(0, 0, 0, 0.1);
62
+ }
63
+
64
+ .playground-panel-title {
65
+ display: flex;
66
+ align-items: center;
67
+ gap: 0.5rem;
68
+ font-size: 0.75rem;
69
+ font-weight: 600;
70
+ color: var(--ld-text-muted);
71
+ text-transform: uppercase;
72
+ letter-spacing: 0.05em;
73
+ }
74
+
75
+ /* Copy Button */
76
+ .playground-copy-btn {
77
+ background: transparent;
78
+ border: none;
79
+ color: var(--ld-text-muted);
80
+ cursor: pointer;
81
+ padding: 0.25rem;
82
+ border-radius: var(--ld-radius-sm);
83
+ display: flex;
84
+ align-items: center;
85
+ justify-content: center;
86
+ transition: all 0.2s;
87
+ }
88
+
89
+ .playground-copy-btn:hover {
90
+ background: rgba(255, 255, 255, 0.1);
91
+ color: var(--ld-text-main);
92
+ }
93
+
94
+ /* Content Area */
95
+ .playground-panel-content {
96
+ flex: 1;
97
+ overflow: auto;
98
+ position: relative;
99
+ display: flex;
100
+ flex-direction: column;
101
+ }
102
+
103
+ /* Editor Specifics */
104
+ .playground-editor {
105
+ background: transparent;
106
+ }
107
+
108
+ .playground-editor > div {
109
+ font-family: var(--ld-font-mono) !important;
110
+ font-size: 0.85rem !important;
111
+ line-height: 1.5 !important;
112
+ min-height: 100%;
113
+ }
114
+
115
+ .playground-editor pre {
116
+ padding: 1.5rem !important;
117
+ margin: 0 !important;
118
+ background: transparent !important;
119
+ }
120
+
121
+ .playground-editor textarea {
122
+ outline: none !important;
123
+ padding: 1.5rem !important;
124
+ }
125
+
126
+ /* Prevent editing styles if read-only */
127
+ .boltdocs-playground[data-readonly="true"] .playground-editor textarea {
128
+ cursor: default !important;
129
+ }
130
+
131
+ /* Preview Specifics */
132
+ .playground-preview {
133
+ padding: 2rem;
134
+ display: flex;
135
+ align-items: center;
136
+ justify-content: center;
137
+ background-color: var(--ld-bg-mute);
138
+ background-image: radial-gradient(
139
+ var(--ld-border-subtle) 1.5px,
140
+ transparent 1.5px
141
+ );
142
+ background-size: 24px 24px;
143
+ color: var(--ld-text-main);
144
+ min-height: 200px;
145
+ }
146
+
147
+ /* Error Specifics */
148
+ .playground-error {
149
+ margin: 0;
150
+ padding: 1rem;
151
+ background: #7f1d1d;
152
+ color: #fca5a5;
153
+ font-size: 0.8rem;
154
+ font-family: var(--ld-font-mono);
155
+ white-space: pre-wrap;
156
+ border-top: 1px solid #991b1b;
157
+ z-index: 10;
158
+ }
159
+
160
+ /* Loading Skeleton */
161
+ .playground-skeleton {
162
+ height: 350px;
163
+ background: var(--ld-bg-mute);
164
+ border-radius: var(--ld-radius-lg);
165
+ animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
166
+ margin: 2rem 0;
167
+ border: 1px solid var(--ld-border-subtle);
168
+ }