boltdocs 1.10.1 → 1.10.2

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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  AppShell
3
- } from "../chunk-OZLYRXAD.mjs";
3
+ } from "../chunk-TKLQWU7H.mjs";
4
4
  import "../chunk-FMTOYQLO.mjs";
5
5
 
6
6
  // src/client/ssr.tsx
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "boltdocs",
3
- "version": "1.10.1",
3
+ "version": "1.10.2",
4
4
  "description": "A lightweight documentation generator for React projects.",
5
5
  "main": "dist/node/index.js",
6
6
  "module": "dist/node/index.mjs",
@@ -8,7 +8,6 @@ export { Sidebar } from "./theme/ui/Sidebar";
8
8
  export { OnThisPage } from "./theme/ui/OnThisPage";
9
9
  export { Head } from "./theme/ui/Head";
10
10
  export { Breadcrumbs } from "./theme/ui/Breadcrumbs";
11
- export { BackgroundGradient } from "./theme/ui/BackgroundGradient";
12
11
  export { Playground } from "./theme/components/Playground";
13
12
  export { NotFound } from "./theme/ui/NotFound";
14
13
  export { Loading } from "./theme/ui/Loading";
@@ -14,6 +14,8 @@ interface CodeBlockProps {
14
14
  */
15
15
  export function CodeBlock({ children, ...props }: CodeBlockProps) {
16
16
  const [copied, setCopied] = useState(false);
17
+ const [isExpanded, setIsExpanded] = useState(false);
18
+ const [isExpandable, setIsExpandable] = useState(false);
17
19
  const preRef = useRef<HTMLPreElement>(null);
18
20
 
19
21
  const handleCopy = useCallback(async () => {
@@ -23,8 +25,17 @@ export function CodeBlock({ children, ...props }: CodeBlockProps) {
23
25
  setTimeout(() => setCopied(false), 2000);
24
26
  }, []);
25
27
 
28
+ React.useEffect(() => {
29
+ if (preRef.current) {
30
+ const codeLength = preRef.current.textContent?.length || 0;
31
+ setIsExpandable(codeLength > 500);
32
+ }
33
+ }, [children]);
34
+
35
+ const shouldTruncate = isExpandable && !isExpanded;
36
+
26
37
  return (
27
- <div className="code-block-wrapper">
38
+ <div className={`code-block-wrapper ${shouldTruncate ? "is-truncated" : ""}`}>
28
39
  <button
29
40
  className={`code-block-copy ${copied ? "copied" : ""}`}
30
41
  onClick={handleCopy}
@@ -35,6 +46,16 @@ export function CodeBlock({ children, ...props }: CodeBlockProps) {
35
46
  <pre ref={preRef} {...props}>
36
47
  {children}
37
48
  </pre>
49
+ {isExpandable && (
50
+ <div className="code-block-expand-wrapper">
51
+ <button
52
+ className="code-block-expand-btn"
53
+ onClick={() => setIsExpanded(!isExpanded)}
54
+ >
55
+ {isExpanded ? "Show less" : "Expand code"}
56
+ </button>
57
+ </div>
58
+ )}
38
59
  </div>
39
60
  );
40
61
  }
@@ -1,10 +1,12 @@
1
- import React, { useState } from "react";
1
+ import React, { useState, useMemo } from "react";
2
2
  import { LiveProvider, LiveEditor, LiveError, LivePreview } from "react-live";
3
3
  import { Copy, Check, Terminal, Play } from "lucide-react";
4
+ import { CodeBlock } from "../CodeBlock";
4
5
 
5
6
  interface PlaygroundProps {
6
7
  code?: string;
7
8
  children?: string | React.ReactNode;
9
+ preview?: React.ReactNode;
8
10
  scope?: Record<string, any>;
9
11
  readonly?: boolean;
10
12
  noInline?: boolean;
@@ -16,7 +18,7 @@ interface PlaygroundProps {
16
18
  * appending a `render(<ComponentName />)` call.
17
19
  */
18
20
  function prepareCode(raw: string): { code: string; noInline: boolean } {
19
- const trimmed = raw.trim();
21
+ const trimmed = (raw || "").trim();
20
22
 
21
23
  // Match: export default function Name(...)
22
24
  const fnMatch = trimmed.match(/export\s+default\s+function\s+(\w+)/);
@@ -41,33 +43,38 @@ function prepareCode(raw: string): { code: string; noInline: boolean } {
41
43
  return { code: trimmed, noInline: false };
42
44
  }
43
45
 
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
46
  export function Playground({
51
- code,
47
+ code: propsCode,
52
48
  children,
49
+ preview,
53
50
  scope = {},
54
51
  readonly = false,
55
52
  noInline: forceNoInline,
56
53
  }: PlaygroundProps) {
57
54
  // Extract code from either `code` prop or `children`
58
- let initialCode = code || "";
59
- if (!initialCode && typeof children === "string") {
60
- initialCode = children;
61
- }
55
+ const initialCode = useMemo(() => {
56
+ let base = propsCode || "";
57
+ if (!base && typeof children === "string") {
58
+ base = children;
59
+ }
60
+ return base.trim();
61
+ }, [propsCode, children]);
62
62
 
63
- const prepared = prepareCode(initialCode);
63
+ const prepared = useMemo(() => prepareCode(initialCode), [initialCode]);
64
64
  const useNoInline = forceNoInline ?? prepared.noInline;
65
65
 
66
66
  const [copied, setCopied] = useState(false);
67
67
  const [activeCode, setActiveCode] = useState(prepared.code);
68
+ const [isExpanded, setIsExpanded] = useState(false);
69
+
70
+ // Sync activeCode when initialCode changes (e.g. in static mode)
71
+ React.useEffect(() => {
72
+ setActiveCode(prepared.code);
73
+ }, [prepared.code]);
68
74
 
69
75
  const handleCopy = () => {
70
- navigator.clipboard.writeText(activeCode);
76
+ const textToCopy = !!preview ? initialCode : activeCode;
77
+ navigator.clipboard.writeText(textToCopy);
71
78
  setCopied(true);
72
79
  setTimeout(() => setCopied(false), 2000);
73
80
  };
@@ -75,50 +82,99 @@ export function Playground({
75
82
  // Provide React generically
76
83
  const extendedScope = { React, ...scope };
77
84
 
85
+ const charLimit = 800; // Adjust as needed
86
+ const isExpandable = (propsCode || initialCode).length > charLimit;
87
+ const shouldTruncate = isExpandable && !isExpanded;
88
+
89
+ const isStatic = !!preview;
90
+
91
+ // Transformer to prevent ReferenceError: require is not defined
92
+ // only used in static mode to allow highlighting without execution
93
+ const staticTransform = (code: string) => {
94
+ // Return empty or a simple dummy to avoid running the code
95
+ return "render(<div style={{display:'none'}} />)";
96
+ };
97
+
78
98
  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">
99
+ <div className={`boltdocs-playground ${shouldTruncate ? "is-truncated" : ""}`} data-readonly={readonly || isStatic}>
100
+ <div className="playground-split-container">
101
+ {/* Preview Side - Now on top */}
102
+ <div className="playground-panel playground-preview-panel">
103
+ <div className="playground-panel-header">
104
+ <div className="playground-panel-title">
105
+ <Play size={14} />
106
+ <span>Preview</span>
107
+ </div>
108
+ </div>
109
+ <div className="playground-panel-content playground-preview">
110
+ {isStatic ? (
111
+ preview
112
+ ) : (
113
+ <LiveProvider
114
+ code={activeCode}
115
+ scope={extendedScope}
116
+ theme={undefined}
117
+ noInline={useNoInline}
118
+ >
119
+ <LivePreview />
120
+ <LiveError className="playground-error" />
121
+ </LiveProvider>
122
+ )}
123
+ </div>
124
+ </div>
125
+
126
+ {/* Editor Side - Now on bottom */}
127
+ <div className="playground-panel playground-editor-panel">
128
+ {!isStatic && (
89
129
  <div className="playground-panel-header">
90
130
  <div className="playground-panel-title">
91
131
  <Terminal size={14} />
92
132
  <span>{readonly ? "Code Example" : "Live Editor"}</span>
93
133
  </div>
134
+ </div>
135
+ )}
136
+ <div className="playground-panel-content playground-editor">
137
+ {/* Copy button moved inside code area */}
138
+ <button
139
+ className="playground-copy-btn-inner"
140
+ onClick={handleCopy}
141
+ title="Copy code"
142
+ >
143
+ {copied ? <Check size={14} /> : <Copy size={14} />}
144
+ </button>
145
+
146
+ {isStatic ? (
147
+ <LiveProvider
148
+ code={initialCode}
149
+ noInline={true}
150
+ transformCode={staticTransform}
151
+ >
152
+ <LiveEditor disabled />
153
+ </LiveProvider>
154
+ ) : (
155
+ <LiveProvider
156
+ code={activeCode}
157
+ scope={extendedScope}
158
+ theme={undefined}
159
+ noInline={useNoInline}
160
+ >
161
+ <LiveEditor disabled={readonly} onChange={setActiveCode} />
162
+ </LiveProvider>
163
+ )}
164
+ </div>
165
+
166
+ {isExpandable && (
167
+ <div className="playground-expand-wrapper">
94
168
  <button
95
- className="playground-copy-btn"
96
- onClick={handleCopy}
97
- title="Copy code"
169
+ className="playground-expand-btn"
170
+ onClick={() => setIsExpanded(!isExpanded)}
98
171
  >
99
- {copied ? <Check size={14} /> : <Copy size={14} />}
172
+ {isExpanded ? "Show less" : "Expand code"}
100
173
  </button>
101
174
  </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>
175
+ )}
120
176
  </div>
121
- </LiveProvider>
177
+ </div>
122
178
  </div>
123
179
  );
124
180
  }
@@ -19,14 +19,6 @@
19
19
  width: 100%;
20
20
  }
21
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
22
  .playground-panel {
31
23
  display: flex;
32
24
  flex-direction: column;
@@ -35,15 +27,62 @@
35
27
  }
36
28
 
37
29
  .playground-editor-panel {
38
- border-bottom: 1px solid var(--ld-border-subtle);
30
+ border-top: 1px solid var(--ld-border-subtle);
39
31
  background: var(--ld-code-bg);
32
+ position: relative;
33
+ }
34
+
35
+ .boltdocs-playground.is-truncated .playground-editor {
36
+ max-height: 250px;
37
+ overflow: hidden;
38
+ }
39
+
40
+ .boltdocs-playground[data-readonly="true"]:not(.is-truncated) .playground-editor {
41
+ max-height: 600px; /* Limit height even if not truncated manually */
40
42
  }
41
43
 
42
- @media (min-width: 1024px) {
43
- .playground-editor-panel {
44
- border-bottom: none;
45
- border-right: 1px solid var(--ld-border-subtle);
46
- }
44
+ .playground-expand-wrapper {
45
+ position: absolute;
46
+ bottom: 0;
47
+ left: 0;
48
+ right: 0;
49
+ height: 80px;
50
+ background: linear-gradient(to top, var(--ld-code-bg) 20%, transparent);
51
+ display: flex;
52
+ align-items: flex-end;
53
+ justify-content: center;
54
+ padding-bottom: 1rem;
55
+ z-index: 10;
56
+ }
57
+
58
+ .playground-expand-btn {
59
+ background-color: var(--ld-surface);
60
+ border: 1px solid var(--ld-border-subtle);
61
+ border-radius: 20px;
62
+ color: var(--ld-text-main);
63
+ padding: 0.5rem 1.25rem;
64
+ font-size: 0.8125rem;
65
+ font-weight: 500;
66
+ cursor: pointer;
67
+ transition: all 0.2s ease;
68
+ backdrop-filter: blur(8px);
69
+ -webkit-backdrop-filter: blur(8px);
70
+ }
71
+
72
+ .playground-expand-btn:hover {
73
+ background-color: var(--ld-border-subtle);
74
+ transform: translateY(-1px);
75
+ }
76
+
77
+ /* When expanded, maybe show the button at the bottom without overlay */
78
+ .boltdocs-playground:not(.is-truncated) .playground-expand-wrapper {
79
+ position: relative;
80
+ height: auto;
81
+ background: none;
82
+ display: flex;
83
+ justify-content: center;
84
+ padding: 1rem 0;
85
+ border-top: 1px solid var(--ld-border-subtle);
47
86
  }
48
87
 
49
88
  .playground-preview-panel {
@@ -130,18 +169,18 @@
130
169
 
131
170
  /* Preview Specifics */
132
171
  .playground-preview {
133
- padding: 2rem;
172
+ padding: 2.5rem;
134
173
  display: flex;
135
174
  align-items: center;
136
175
  justify-content: center;
137
- background-color: var(--ld-bg-mute);
176
+ background-color: #000; /* Dark background as in the image */
138
177
  background-image: radial-gradient(
139
- var(--ld-border-subtle) 1.5px,
178
+ rgba(255, 255, 255, 0.05) 1.5px,
140
179
  transparent 1.5px
141
180
  );
142
181
  background-size: 24px 24px;
143
182
  color: var(--ld-text-main);
144
- min-height: 200px;
183
+ min-height: 300px;
145
184
  }
146
185
 
147
186
  /* Error Specifics */
@@ -166,3 +205,34 @@
166
205
  margin: 2rem 0;
167
206
  border: 1px solid var(--ld-border-subtle);
168
207
  }
208
+ /* Copy Button - Inner */
209
+ .playground-copy-btn-inner {
210
+ position: absolute;
211
+ top: 1rem;
212
+ right: 1.5rem;
213
+ z-index: 20;
214
+ display: flex;
215
+ align-items: center;
216
+ justify-content: center;
217
+ width: 32px;
218
+ height: 32px;
219
+ border-radius: 6px;
220
+ border: 1px solid var(--ld-border-subtle);
221
+ background: var(--ld-surface);
222
+ color: var(--ld-text-dim);
223
+ cursor: pointer;
224
+ transition: all 0.2s ease;
225
+ backdrop-filter: blur(8px);
226
+ -webkit-backdrop-filter: blur(8px);
227
+ }
228
+
229
+ .playground-copy-btn-inner:hover {
230
+ background: var(--ld-border-subtle);
231
+ color: var(--ld-text-main);
232
+ transform: translateY(-1px);
233
+ }
234
+
235
+ /* Obsolete Static Code Integration - Cleaning up since we use LiveEditor now */
236
+ .playground-static-code {
237
+ display: none;
238
+ }
@@ -77,6 +77,7 @@
77
77
  font-weight: 700;
78
78
  letter-spacing: -0.025em;
79
79
  color: var(--ld-text-main);
80
+ padding-right: 160px; /* Space for CopyMarkdown button */
80
81
  }
81
82
 
82
83
  .boltdocs-page h1 + p {
@@ -267,6 +268,58 @@
267
268
  padding: 1.25rem 1rem !important;
268
269
  }
269
270
 
271
+ .code-block-wrapper.is-truncated pre {
272
+ max-height: 250px;
273
+ overflow: hidden;
274
+ }
275
+
276
+ .code-block-expand-wrapper {
277
+ position: absolute;
278
+ bottom: 0;
279
+ left: 0;
280
+ right: 0;
281
+ height: 80px;
282
+ background: linear-gradient(to top, var(--ld-code-bg) 20%, transparent);
283
+ display: none;
284
+ align-items: flex-end;
285
+ justify-content: center;
286
+ padding-bottom: 1rem;
287
+ z-index: 10;
288
+ }
289
+
290
+ .code-block-wrapper.is-truncated .code-block-expand-wrapper {
291
+ display: flex;
292
+ }
293
+
294
+ .code-block-expand-btn {
295
+ background-color: var(--ld-surface);
296
+ border: 1px solid var(--ld-border-subtle);
297
+ border-radius: 20px;
298
+ color: var(--ld-text-main);
299
+ padding: 0.5rem 1.25rem;
300
+ font-size: 0.8125rem;
301
+ font-weight: 500;
302
+ cursor: pointer;
303
+ transition: all 0.2s ease;
304
+ backdrop-filter: blur(8px);
305
+ -webkit-backdrop-filter: blur(8px);
306
+ }
307
+
308
+ .code-block-expand-btn:hover {
309
+ background-color: var(--ld-border-subtle);
310
+ transform: translateY(-1px);
311
+ }
312
+
313
+ .code-block-wrapper:not(.is-truncated) .code-block-expand-wrapper {
314
+ position: relative;
315
+ height: auto;
316
+ background: none;
317
+ display: flex;
318
+ justify-content: center;
319
+ padding: 1rem 0;
320
+ border-top: 1px solid var(--ld-border-subtle);
321
+ }
322
+
270
323
  .code-block-wrapper pre > code .line {
271
324
  padding: 0 1.25rem;
272
325
  }
@@ -32,10 +32,6 @@
32
32
  --ld-btn-secondary-bg: #ffffff;
33
33
  --ld-btn-secondary-text: #111827;
34
34
 
35
- /* ─ Gradients ─ */
36
- --ld-gradient-from: var(--ld-color-primary);
37
- --ld-gradient-to: #a855f7;
38
-
39
35
  --ld-code-bg: #f3f4f6;
40
36
  --ld-code-header: #e5e7eb;
41
37
  --ld-code-text: #1f2937;
@@ -45,8 +41,6 @@
45
41
  --ld-navbar-blur: 12px;
46
42
  --ld-sidebar-bg: transparent;
47
43
  --ld-sidebar-blur: 0px;
48
- --ld-glow-1-bg: var(--ld-color-primary-glow);
49
- --ld-glow-2-bg: rgba(215, 59, 246, 0.15);
50
44
 
51
45
  /* ─ UI Components (overridable independently from layout) ─ */
52
46
  --ld-ui-btn-primary-bg: var(--ld-btn-primary-bg);
@@ -102,10 +96,6 @@
102
96
  --ld-btn-secondary-bg: #1a1a2e;
103
97
  --ld-btn-secondary-text: #e4e4ed;
104
98
 
105
- /* ─ Gradients ─ */
106
- --ld-gradient-from: #ffffff;
107
- --ld-gradient-to: rgba(255, 255, 255, 0.7);
108
-
109
99
  /* ─ Code ─ */
110
100
  --ld-code-bg: #050505;
111
101
  --ld-code-header: #111119;
@@ -116,8 +106,6 @@
116
106
  --ld-navbar-blur: 12px;
117
107
  --ld-sidebar-bg: transparent;
118
108
  --ld-sidebar-blur: 0px;
119
- --ld-glow-1-bg: var(--ld-color-primary-glow);
120
- --ld-glow-2-bg: rgba(246, 59, 187, 0.15);
121
109
 
122
110
  /* ─ UI Components (dark) ─ */
123
111
  --ld-ui-btn-primary-bg: var(--ld-btn-primary-bg);
@@ -30,6 +30,7 @@
30
30
  /* Pages */
31
31
  @import "./ui/NotFound/not-found.css";
32
32
  @import "./ui/Loading/loading.css";
33
+ @import "./ui/ErrorBoundary/error-boundary.css";
33
34
 
34
35
  /* Playground */
35
36
  @import "./components/Playground/playground.css";
@@ -12,12 +12,10 @@
12
12
  border-radius: var(--ld-radius-full);
13
13
  overflow: hidden;
14
14
  transition: all 0.2s ease;
15
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
16
15
  }
17
16
 
18
17
  .copy-btn-group:hover {
19
18
  border-color: var(--ld-color-primary-hover);
20
- box-shadow: 0 4px 20px rgba(59, 130, 246, 0.15);
21
19
  }
22
20
 
23
21
  .copy-btn {
@@ -1,4 +1,5 @@
1
- import React, { Component, ErrorInfo, ReactNode } from "react";
1
+ import { Component, ErrorInfo, ReactNode } from "react";
2
+ import "./error-boundary.css";
2
3
 
3
4
  interface Props {
4
5
  children?: ReactNode;
@@ -12,7 +13,7 @@ interface State {
12
13
 
13
14
  export class ErrorBoundary extends Component<Props, State> {
14
15
  public state: State = {
15
- hasError: false
16
+ hasError: false,
16
17
  };
17
18
 
18
19
  public static getDerivedStateFromError(error: Error): State {
@@ -25,19 +26,22 @@ export class ErrorBoundary extends Component<Props, State> {
25
26
 
26
27
  public render() {
27
28
  if (this.state.hasError) {
28
- return this.props.fallback || (
29
- <div className="boltdocs-error-boundary">
30
- <div className="boltdocs-error-title">Something went wrong</div>
31
- <p className="boltdocs-error-message">
32
- {this.state.error?.message || "An unexpected error occurred while rendering this page."}
33
- </p>
34
- <button
35
- className="boltdocs-error-retry"
36
- onClick={() => this.setState({ hasError: false })}
37
- >
38
- Try again
39
- </button>
40
- </div>
29
+ return (
30
+ this.props.fallback || (
31
+ <div className="boltdocs-error-boundary">
32
+ <div className="boltdocs-error-title">Something went wrong</div>
33
+ <p className="boltdocs-error-message">
34
+ {this.state.error?.message ||
35
+ "An unexpected error occurred while rendering this page."}
36
+ </p>
37
+ <button
38
+ className="boltdocs-error-retry"
39
+ onClick={() => this.setState({ hasError: false })}
40
+ >
41
+ Try again
42
+ </button>
43
+ </div>
44
+ )
41
45
  );
42
46
  }
43
47
 
@@ -0,0 +1,55 @@
1
+ .boltdocs-error-boundary {
2
+ display: flex;
3
+ flex-direction: column;
4
+ align-items: center;
5
+ justify-content: center;
6
+ padding: 3rem 2rem;
7
+ margin: 2rem 0;
8
+ background-color: var(--ld-bg-soft);
9
+ border: 1px solid var(--ld-ui-danger-border);
10
+ border-radius: var(--ld-radius-lg);
11
+ text-align: center;
12
+ backdrop-filter: blur(8px);
13
+ -webkit-backdrop-filter: blur(8px);
14
+ }
15
+
16
+ .boltdocs-error-title {
17
+ font-size: 1.5rem;
18
+ font-weight: 700;
19
+ color: var(--ld-ui-danger-text);
20
+ margin-bottom: 0.75rem;
21
+ font-family: var(--ld-font-sans);
22
+ }
23
+
24
+ .boltdocs-error-message {
25
+ font-size: 1rem;
26
+ color: var(--ld-text-muted);
27
+ max-width: 100%;
28
+ margin-bottom: 1.5rem;
29
+ line-height: 1.6;
30
+ overflow-wrap: break-word;
31
+ word-break: break-word;
32
+ }
33
+
34
+ .boltdocs-error-retry {
35
+ padding: 0.6rem 1.25rem;
36
+ background-color: var(--ld-ui-btn-primary-bg);
37
+ color: var(--ld-ui-btn-primary-text);
38
+ border: none;
39
+ border-radius: var(--ld-radius-full);
40
+ font-size: 0.875rem;
41
+ font-weight: 600;
42
+ cursor: pointer;
43
+ transition: all 0.2s ease;
44
+ box-shadow: 0 4px 12px var(--ld-color-primary-glow);
45
+ }
46
+
47
+ .boltdocs-error-retry:hover {
48
+ background-color: var(--ld-color-primary-hover);
49
+ transform: translateY(-1px);
50
+ box-shadow: 0 6px 16px var(--ld-color-primary-glow);
51
+ }
52
+
53
+ .boltdocs-error-retry:active {
54
+ transform: translateY(0);
55
+ }