···
1
1
<script>
2
2
-
import * as Card from "$lib/components/ui/card";
3
3
-
import { Button } from "$lib/components/ui/button";
2
2
+
import * as Card from "$lib/components/ui/card";
3
3
+
import { Button } from "$lib/components/ui/button";
4
4
5
5
-
// Define the packages and their installers
6
6
-
const uv_tools = [
7
7
-
'fpw',
8
8
-
'harlequin',
9
9
-
'llm',
10
10
-
'marimo',
11
11
-
'mopup',
12
12
-
'posting',
13
13
-
'ruff',
14
14
-
'yt-dlp'
15
15
-
];
5
5
+
// Define the packages and their installers
6
6
+
const uv_tools = [
7
7
+
"fpw",
8
8
+
"harlequin",
9
9
+
"llm",
10
10
+
"marimo",
11
11
+
"mopup",
12
12
+
"posting",
13
13
+
"ruff",
14
14
+
"yt-dlp",
15
15
+
];
16
16
17
17
-
const brews = [
18
18
-
// Base utilities
19
19
-
'aria2',
20
20
-
'cursor',
21
21
-
'duckdb',
22
22
-
'jq',
23
23
-
'zoxide',
24
24
-
'choose-rust',
25
25
-
26
26
-
// System utilities
27
27
-
'bartender',
28
28
-
'istat-menus',
29
29
-
'macmediakeyforwarder',
30
30
-
'lingon-x',
31
31
-
'lunar',
32
32
-
'onyx',
33
33
-
'pastebot',
34
34
-
35
35
-
// Development tools
36
36
-
'beekeeper-studio',
37
37
-
'cloudflared',
38
38
-
'docker',
39
39
-
'docker-completion',
40
40
-
'docker-compose',
41
41
-
'github',
42
42
-
'orbstack',
43
43
-
'postico',
44
44
-
'postman',
45
45
-
'sublime-text',
46
46
-
47
47
-
// File management
48
48
-
'cyberduck',
49
49
-
'mountain-duck',
50
50
-
'diskonaut',
51
51
-
'dust',
52
52
-
'duf',
53
53
-
'the-unarchiver',
54
54
-
55
55
-
// Media tools
56
56
-
'iina',
57
57
-
'handbrake',
58
58
-
'homebrew/cask/handbrake',
59
59
-
'losslesscut',
60
60
-
'plex-media-server',
61
61
-
'qlvideo',
62
62
-
'subler',
63
63
-
64
64
-
// Internet & Communication
65
65
-
'firefox',
66
66
-
'notion',
67
67
-
'qbittorrent',
68
68
-
'homebrew/cask/syncthing',
69
69
-
'homebrew/cask/transmission',
70
70
-
'telegram',
71
71
-
72
72
-
// Text & Documentation
73
73
-
'typora',
74
74
-
'espanso'
75
75
-
];
17
17
+
const brews = [
18
18
+
// Base utilities
19
19
+
"aria2",
20
20
+
"cursor",
21
21
+
"duckdb",
22
22
+
"jq",
23
23
+
"zoxide",
24
24
+
"choose-rust",
76
25
77
77
-
const appstore_packages = [
78
78
-
{ name: 'PairVPN', id: '1347012179' },
79
79
-
{ name: 'Tailscale', id: '1475387142' },
80
80
-
{ name: 'HotKey', id: '975890633' },
81
81
-
{ name: 'Dark Reader', id: '1438243180' },
82
82
-
{ name: 'Daisy Disk', id: '411643860' },
83
83
-
{ name: 'Overlap', id: '1516950324' },
84
84
-
{ name: 'Velja', id: '1607635845' },
85
85
-
{ name: 'System Color Picker', id: '1545870783' },
86
86
-
{ name: 'VPN Unlimited', id: '694633015' },
87
87
-
{ name: 'Consent-O-Matic', id: '1606897889' }
88
88
-
];
26
26
+
// System utilities
27
27
+
"bartender",
28
28
+
"istat-menus",
29
29
+
"macmediakeyforwarder",
30
30
+
"lingon-x",
31
31
+
"lunar",
32
32
+
"onyx",
33
33
+
"pastebot",
34
34
+
35
35
+
// Development tools
36
36
+
"beekeeper-studio",
37
37
+
"cloudflared",
38
38
+
"docker",
39
39
+
"docker-completion",
40
40
+
"docker-compose",
41
41
+
"github",
42
42
+
"orbstack",
43
43
+
"postico",
44
44
+
"postman",
45
45
+
"sublime-text",
46
46
+
47
47
+
// File management
48
48
+
"cyberduck",
49
49
+
"mountain-duck",
50
50
+
"diskonaut",
51
51
+
"dust",
52
52
+
"duf",
53
53
+
"the-unarchiver",
54
54
+
55
55
+
// Media tools
56
56
+
"iina",
57
57
+
"handbrake",
58
58
+
"homebrew/cask/handbrake",
59
59
+
"losslesscut",
60
60
+
"plex-media-server",
61
61
+
"qlvideo",
62
62
+
"subler",
63
63
+
64
64
+
// Internet & Communication
65
65
+
"firefox",
66
66
+
"notion",
67
67
+
"qbittorrent",
68
68
+
"homebrew/cask/syncthing",
69
69
+
"homebrew/cask/transmission",
70
70
+
"telegram",
71
71
+
72
72
+
// Text & Documentation
73
73
+
"typora",
74
74
+
"espanso",
75
75
+
];
76
76
+
77
77
+
const appstore_packages = [
78
78
+
{ name: "PairVPN", id: "1347012179" },
79
79
+
{ name: "Tailscale", id: "1475387142" },
80
80
+
{ name: "HotKey", id: "975890633" },
81
81
+
{ name: "Dark Reader", id: "1438243180" },
82
82
+
{ name: "Daisy Disk", id: "411643860" },
83
83
+
{ name: "Overlap", id: "1516950324" },
84
84
+
{ name: "Velja", id: "1607635845" },
85
85
+
{ name: "System Color Picker", id: "1545870783" },
86
86
+
{ name: "VPN Unlimited", id: "694633015" },
87
87
+
{ name: "Consent-O-Matic", id: "1606897889" },
88
88
+
];
89
89
+
90
90
+
// Combine all packages into a single list
91
91
+
const packages = [
92
92
+
...uv_tools.map((name) => ({ name, installer: "uv" })),
93
93
+
...brews.map((name) => ({ name, installer: "homebrew" })),
94
94
+
...appstore_packages.map((pkg) => ({
95
95
+
name: pkg.name,
96
96
+
id: pkg.id,
97
97
+
installer: "mas",
98
98
+
})),
99
99
+
].sort((a, b) => a.name.localeCompare(b.name));
89
100
90
90
-
// Combine all packages into a single list
91
91
-
const packages = [
92
92
-
...uv_tools.map(name => ({ name, installer: 'uv' })),
93
93
-
...brews.map(name => ({ name, installer: 'homebrew' })),
94
94
-
...appstore_packages.map(pkg => ({ name: pkg.name, id: pkg.id, installer: 'mas' }))
95
95
-
].sort((a, b) => a.name.localeCompare(b.name));
101
101
+
// Reactive variables for selected packages and copied state
102
102
+
let selectedPackages = $state(new Set(packages));
103
103
+
let copied = false;
96
104
97
97
-
// Reactive variables for selected packages and copied state
98
98
-
let selectedPackages = $state(new Set(packages));
99
99
-
let copied = false;
105
105
+
// Toggle package selection
106
106
+
function togglePackage(pkg) {
107
107
+
selectedPackages = new Set(selectedPackages); // Create new Set for reactivity
108
108
+
const found = Array.from(selectedPackages).find(
109
109
+
(p) => p.name === pkg.name && p.installer === pkg.installer
110
110
+
);
100
111
101
101
-
// Toggle package selection
102
102
-
function togglePackage(pkg) {
103
103
-
selectedPackages = new Set(selectedPackages); // Create new Set for reactivity
104
104
-
const found = Array.from(selectedPackages).find(
105
105
-
p => p.name === pkg.name && p.installer === pkg.installer
106
106
-
);
107
107
-
108
108
-
if (found) {
109
109
-
selectedPackages.delete(found);
110
110
-
} else {
111
111
-
selectedPackages.add(pkg);
112
112
-
}
113
113
-
}
112
112
+
if (found) {
113
113
+
selectedPackages.delete(found);
114
114
+
} else {
115
115
+
selectedPackages.add(pkg);
116
116
+
}
117
117
+
}
114
118
115
119
// Group packages by installer
116
120
const packagesByInstaller = $derived({
117
117
-
homebrew: Array.from(selectedPackages).filter(pkg => pkg.installer === 'homebrew'),
118
118
-
uv: Array.from(selectedPackages).filter(pkg => pkg.installer === 'uv'),
119
119
-
mas: Array.from(selectedPackages).filter(pkg => pkg.installer === 'mas')
121
121
+
homebrew: Array.from(selectedPackages).filter(
122
122
+
(pkg) => pkg.installer === "homebrew"
123
123
+
),
124
124
+
uv: Array.from(selectedPackages).filter((pkg) => pkg.installer === "uv"),
125
125
+
mas: Array.from(selectedPackages).filter((pkg) => pkg.installer === "mas"),
120
126
});
121
127
122
128
// Generate install commands for each installer
123
129
const installerCommands = $derived({
124
124
-
homebrew: (packagesByInstaller.homebrew.length > 0 || packagesByInstaller.mas.length > 0) ?
125
125
-
`/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"` :
126
126
-
null,
127
127
-
uv: packagesByInstaller.uv.length > 0 ? [
128
128
-
'curl -LsSf https://astral.sh/uv/install.sh | sh',
129
129
-
'uv python install'
130
130
-
] : null,
131
131
-
mas: packagesByInstaller.mas.length > 0 ?
132
132
-
'brew install mas' :
133
133
-
null
130
130
+
homebrew:
131
131
+
packagesByInstaller.homebrew.length > 0 ||
132
132
+
packagesByInstaller.mas.length > 0
133
133
+
? `/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`
134
134
+
: null,
135
135
+
uv:
136
136
+
packagesByInstaller.uv.length > 0
137
137
+
? [
138
138
+
"curl -LsSf https://astral.sh/uv/install.sh | sh",
139
139
+
"uv python install",
140
140
+
]
141
141
+
: null,
142
142
+
mas: packagesByInstaller.mas.length > 0 ? "brew install mas" : null,
134
143
});
135
144
136
145
// Generate package install commands
137
146
const packageCommands = $derived({
138
138
-
homebrew: packagesByInstaller.homebrew.length > 0 ?
139
139
-
`brew install ${packagesByInstaller.homebrew.map(pkg => pkg.name).join(' ')}` :
140
140
-
null,
141
141
-
uv: packagesByInstaller.uv.length > 0 ?
142
142
-
`uv tool install ${packagesByInstaller.uv.map(pkg => pkg.name).join(' ')}` :
143
143
-
null,
144
144
-
mas: packagesByInstaller.mas.length > 0 ?
145
145
-
`mas install ${packagesByInstaller.mas.map(pkg => pkg.id).join(' ')}` :
146
146
-
null
147
147
+
homebrew:
148
148
+
packagesByInstaller.homebrew.length > 0
149
149
+
? `brew install ${packagesByInstaller.homebrew.map((pkg) => pkg.name).join(" ")}`
150
150
+
: null,
151
151
+
uv:
152
152
+
packagesByInstaller.uv.length > 0
153
153
+
? `uv tool install ${packagesByInstaller.uv.map((pkg) => pkg.name).join(" ")}`
154
154
+
: null,
155
155
+
mas:
156
156
+
packagesByInstaller.mas.length > 0
157
157
+
? `mas install ${packagesByInstaller.mas.map((pkg) => pkg.id).join(" ")}`
158
158
+
: null,
147
159
});
148
160
149
161
// Combine all commands in the correct order
150
150
-
const cmds = $derived([
162
162
+
const cmds = $derived(
163
163
+
[
151
164
installerCommands.homebrew,
152
165
installerCommands.uv,
153
166
installerCommands.mas,
154
167
packageCommands.homebrew,
155
168
packageCommands.uv,
156
156
-
packageCommands.mas
157
157
-
].filter(Boolean)
158
158
-
.flat()
159
159
-
.join('\n'));
169
169
+
packageCommands.mas,
170
170
+
]
171
171
+
.filter(Boolean)
172
172
+
.flat()
173
173
+
.join("\n")
174
174
+
);
160
175
161
161
-
// Copy the generated commands to clipboard
162
162
-
function copyToClipboard() {
163
163
-
navigator.clipboard.writeText(cmds);
164
164
-
showCopiedMessage();
165
165
-
}
176
176
+
// Copy the generated commands to clipboard
177
177
+
function copyToClipboard() {
178
178
+
navigator.clipboard.writeText(cmds);
179
179
+
showCopiedMessage();
180
180
+
}
166
181
167
167
-
// Show the "Copied!" message
168
168
-
function showCopiedMessage() {
169
169
-
copied = true;
170
170
-
setTimeout(() => copied = false, 2000);
171
171
-
}
182
182
+
// Show the "Copied!" message
183
183
+
function showCopiedMessage() {
184
184
+
copied = true;
185
185
+
setTimeout(() => (copied = false), 2000);
186
186
+
}
172
187
173
173
-
// Add new derived store to group commands by type
174
174
-
const groupedCommands = $derived({
175
175
-
installers: [
176
176
-
installerCommands.homebrew,
177
177
-
installerCommands.uv,
178
178
-
installerCommands.mas
179
179
-
].filter(Boolean).flat(),
180
180
-
packages: [
181
181
-
packageCommands.homebrew,
182
182
-
packageCommands.uv,
183
183
-
packageCommands.mas
184
184
-
].filter(Boolean)
185
185
-
});
186
186
-
187
187
-
// Add new copy functions for each section
188
188
-
function copyInstallers() {
189
189
-
navigator.clipboard.writeText(groupedCommands.installers.join('\n'));
190
190
-
showCopiedMessage();
191
191
-
}
188
188
+
// Add new derived store to group commands by type
189
189
+
const groupedCommands = $derived({
190
190
+
installers: [
191
191
+
installerCommands.homebrew,
192
192
+
installerCommands.uv,
193
193
+
installerCommands.mas,
194
194
+
]
195
195
+
.filter(Boolean)
196
196
+
.flat(),
197
197
+
packages: [
198
198
+
packageCommands.homebrew,
199
199
+
packageCommands.uv,
200
200
+
packageCommands.mas,
201
201
+
].filter(Boolean),
202
202
+
});
192
203
193
193
-
function copyPackages() {
194
194
-
navigator.clipboard.writeText(groupedCommands.packages.join('\n'));
195
195
-
showCopiedMessage();
196
196
-
}
204
204
+
// Add new copy functions for each section
205
205
+
function copyInstallers() {
206
206
+
navigator.clipboard.writeText(groupedCommands.installers.join("\n"));
207
207
+
showCopiedMessage();
208
208
+
}
197
209
198
198
-
// Add select/deselect all function
199
199
-
function toggleSelectAll() {
200
200
-
if (selectedPackages.size === packages.length) {
201
201
-
selectedPackages = new Set();
202
202
-
} else {
203
203
-
selectedPackages = new Set(packages);
204
204
-
}
205
205
-
}
210
210
+
function copyPackages() {
211
211
+
navigator.clipboard.writeText(groupedCommands.packages.join("\n"));
212
212
+
showCopiedMessage();
213
213
+
}
206
214
215
215
+
// Add select/deselect all function
216
216
+
function toggleSelectAll() {
217
217
+
if (selectedPackages.size === packages.length) {
218
218
+
selectedPackages = new Set();
219
219
+
} else {
220
220
+
selectedPackages = new Set(packages);
221
221
+
}
222
222
+
}
207
223
</script>
208
224
209
225
<div class="container mx-auto p-4">
210
226
<Card.Root>
211
227
<Card.Header>
212
228
<Card.Title>Package Selection</Card.Title>
213
213
-
<Card.Description>Select packages to install on your system</Card.Description>
229
229
+
<Card.Description
230
230
+
>Select packages to install on your system</Card.Description
231
231
+
>
214
232
</Card.Header>
215
233
<Card.Content>
216
234
<div class="flex justify-between items-center mb-4">
217
217
-
<Button
218
218
-
variant="outline"
219
219
-
size="sm"
220
220
-
on:click={toggleSelectAll}
221
221
-
>
222
222
-
{selectedPackages.size === packages.length ? 'Deselect All' : 'Select All'}
235
235
+
<Button variant="outline" size="sm" on:click={toggleSelectAll}>
236
236
+
{selectedPackages.size === packages.length
237
237
+
? "Deselect All"
238
238
+
: "Select All"}
223
239
</Button>
224
240
<span class="text-sm text-muted-foreground">
225
241
{selectedPackages.size} of {packages.length} selected
···
243
259
<Card.Root class="mt-4">
244
260
<Card.Header>
245
261
<Card.Title>Installation Commands</Card.Title>
246
246
-
<Card.Description>Copy and run these commands to install selected packages</Card.Description>
262
262
+
<Card.Description
263
263
+
>Copy and run these commands to install selected packages</Card.Description
264
264
+
>
247
265
</Card.Header>
248
266
<Card.Content>
249
267
<div class="terminal-output">
250
268
<Button class="copy-all-button" on:click={copyToClipboard}>
251
269
Copy All Commands
252
270
</Button>
253
253
-
271
271
+
254
272
{#if groupedCommands.installers.length > 0}
255
273
<div class="command-section">
256
274
<div class="section-header">
257
257
-
<h4>Install Package Managers</h4>
258
258
-
<Button
259
259
-
variant="outline"
260
260
-
size="sm"
261
261
-
on:click={copyInstallers}
262
262
-
>
275
275
+
<Button variant="outline" size="sm" on:click={copyInstallers}>
263
276
Copy
264
277
</Button>
265
278
</div>
266
266
-
<pre><code>{groupedCommands.installers.join('\n')}</code></pre>
279
279
+
<pre><code>{groupedCommands.installers.join("\n")}</code></pre>
267
280
</div>
268
281
{/if}
269
269
-
282
282
+
270
283
{#if groupedCommands.packages.length > 0}
271
284
<div class="command-section">
272
285
<div class="section-header">
273
273
-
<h4>Install Packages</h4>
274
274
-
<Button
275
275
-
variant="outline"
276
276
-
size="sm"
277
277
-
on:click={copyPackages}
278
278
-
>
286
286
+
<Button variant="outline" size="sm" on:click={copyPackages}>
279
287
Copy
280
288
</Button>
281
289
</div>
282
282
-
<pre><code>{groupedCommands.packages.join('\n')}</code></pre>
290
290
+
<pre><code>{groupedCommands.packages.join("\n")}</code></pre>
283
291
</div>
284
292
{/if}
285
293
···
291
299
</Card.Root>
292
300
{/if}
293
301
</div>
302
302
+
294
303
<style>
295
295
-
.package-list {
296
296
-
display: grid;
297
297
-
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
298
298
-
gap: 0.5rem;
299
299
-
max-height: 60vh;
300
300
-
overflow-y: auto;
301
301
-
}
304
304
+
.package-list {
305
305
+
display: grid;
306
306
+
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
307
307
+
gap: 0.5rem;
308
308
+
max-height: 60vh;
309
309
+
overflow-y: auto;
310
310
+
}
302
311
303
303
-
.package-name {
304
304
-
color: #666;
305
305
-
cursor: pointer;
306
306
-
padding: 0.5rem;
307
307
-
border: none;
308
308
-
background: none;
309
309
-
font-family: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono', monospace;
310
310
-
text-align: left;
311
311
-
white-space: nowrap;
312
312
-
overflow: hidden;
313
313
-
text-overflow: ellipsis;
314
314
-
transition: color 0.2s ease;
315
315
-
width: 100%;
316
316
-
border-radius: 0.25rem;
317
317
-
}
312
312
+
.package-name {
313
313
+
color: #666;
314
314
+
cursor: pointer;
315
315
+
padding: 0.5rem;
316
316
+
border: none;
317
317
+
background: none;
318
318
+
font-family: ui-monospace, "Cascadia Code", "Source Code Pro", Menlo,
319
319
+
Consolas, "DejaVu Sans Mono", monospace;
320
320
+
text-align: left;
321
321
+
white-space: nowrap;
322
322
+
overflow: hidden;
323
323
+
text-overflow: ellipsis;
324
324
+
transition: color 0.2s ease;
325
325
+
width: 100%;
326
326
+
border-radius: 0.25rem;
327
327
+
}
318
328
319
319
-
.package-name:hover {
320
320
-
background-color: rgba(0, 0, 0, 0.05);
321
321
-
}
329
329
+
.package-name:hover {
330
330
+
background-color: rgba(0, 0, 0, 0.05);
331
331
+
}
322
332
323
323
-
.package-name.selected {
324
324
-
color: #0d6efd;
325
325
-
background-color: rgba(13, 110, 253, 0.1);
326
326
-
}
333
333
+
.package-name.selected {
334
334
+
color: #0d6efd;
335
335
+
background-color: rgba(13, 110, 253, 0.1);
336
336
+
}
327
337
328
328
-
.terminal-output {
329
329
-
background-color: #161b22;
330
330
-
color: #c9d1d9;
331
331
-
padding: 1rem;
332
332
-
border-radius: 0.5rem;
333
333
-
position: fixed;
334
334
-
bottom: 1rem;
335
335
-
left: 1rem;
336
336
-
right: 1rem;
337
337
-
max-height: 40vh;
338
338
-
overflow-y: auto;
339
339
-
font-family: monospace;
340
340
-
white-space: pre-wrap;
341
341
-
z-index: 10; /* Ensure terminal stays on top */
342
342
-
}
338
338
+
.terminal-output {
339
339
+
background-color: #161b22;
340
340
+
color: #c9d1d9;
341
341
+
padding: 1rem;
342
342
+
border-radius: 0.5rem;
343
343
+
position: fixed;
344
344
+
bottom: 1rem;
345
345
+
left: 1rem;
346
346
+
right: 1rem;
347
347
+
max-height: 40vh;
348
348
+
overflow-y: auto;
349
349
+
font-family: monospace;
350
350
+
white-space: pre-wrap;
351
351
+
z-index: 10; /* Ensure terminal stays on top */
352
352
+
}
343
353
344
344
-
.copy-button {
345
345
-
position: absolute;
346
346
-
top: 0.5rem;
347
347
-
right: 0.5rem;
348
348
-
background-color: #0d6efd;
349
349
-
color: #fff;
350
350
-
border: none;
351
351
-
padding: 0.5rem;
352
352
-
border-radius: 0.25rem;
353
353
-
cursor: pointer;
354
354
-
}
354
354
+
.copy-button {
355
355
+
position: absolute;
356
356
+
top: 0.5rem;
357
357
+
right: 0.5rem;
358
358
+
background-color: #0d6efd;
359
359
+
color: #fff;
360
360
+
border: none;
361
361
+
padding: 0.5rem;
362
362
+
border-radius: 0.25rem;
363
363
+
cursor: pointer;
364
364
+
}
355
365
356
356
-
.copied-message {
357
357
-
position: absolute;
358
358
-
top: 0.5rem;
359
359
-
right: 5rem;
360
360
-
background-color: #198754;
361
361
-
color: #fff;
362
362
-
padding: 0.5rem;
363
363
-
border-radius: 0.25rem;
364
364
-
}
366
366
+
.copied-message {
367
367
+
position: absolute;
368
368
+
top: 0.5rem;
369
369
+
right: 5rem;
370
370
+
background-color: #198754;
371
371
+
color: #fff;
372
372
+
padding: 0.5rem;
373
373
+
border-radius: 0.25rem;
374
374
+
}
365
375
366
366
-
.terminal-output h4 {
367
367
-
color: #8b949e;
368
368
-
margin: 0.5rem 0;
369
369
-
font-size: 0.9rem;
370
370
-
font-weight: normal;
371
371
-
}
376
376
+
.terminal-output h4 {
377
377
+
color: #8b949e;
378
378
+
margin: 0.5rem 0;
379
379
+
font-size: 0.9rem;
380
380
+
font-weight: normal;
381
381
+
}
372
382
373
373
-
.terminal-output pre {
374
374
-
margin: 0.5rem 0 1rem 0;
375
375
-
}
383
383
+
.terminal-output pre {
384
384
+
margin: 0.5rem 0 1rem 0;
385
385
+
}
376
386
377
377
-
.command-section {
378
378
-
margin-bottom: 1rem;
379
379
-
border: 1px solid #30363d;
380
380
-
border-radius: 0.5rem;
381
381
-
padding: 1rem;
382
382
-
}
387
387
+
.command-section {
388
388
+
margin-bottom: 1rem;
389
389
+
border: 1px solid #30363d;
390
390
+
border-radius: 0.5rem;
391
391
+
padding: 1rem;
392
392
+
}
383
393
384
384
-
.section-header {
385
385
-
display: flex;
386
386
-
justify-content: space-between;
387
387
-
align-items: center;
388
388
-
margin-bottom: 0.5rem;
389
389
-
}
394
394
+
.section-header {
395
395
+
display: flex;
396
396
+
justify-content: space-between;
397
397
+
align-items: center;
398
398
+
margin-bottom: 0.5rem;
399
399
+
}
390
400
391
391
-
.section-header h4 {
392
392
-
margin: 0;
393
393
-
}
401
401
+
.section-header h4 {
402
402
+
margin: 0;
403
403
+
}
394
404
395
395
-
.copy-all-button {
396
396
-
display: block;
397
397
-
width: 100%;
398
398
-
margin-bottom: 1rem;
399
399
-
background-color: #0d6efd;
400
400
-
color: #fff;
401
401
-
border: none;
402
402
-
padding: 0.5rem;
403
403
-
border-radius: 0.25rem;
404
404
-
cursor: pointer;
405
405
-
}
405
405
+
.copy-all-button {
406
406
+
display: block;
407
407
+
width: 100%;
408
408
+
margin-bottom: 1rem;
409
409
+
background-color: #0d6efd;
410
410
+
color: #fff;
411
411
+
border: none;
412
412
+
padding: 0.5rem;
413
413
+
border-radius: 0.25rem;
414
414
+
cursor: pointer;
415
415
+
}
406
416
407
407
-
.copy-section-button {
408
408
-
background-color: #21262d;
409
409
-
color: #c9d1d9;
410
410
-
border: 1px solid #30363d;
411
411
-
padding: 0.25rem 0.5rem;
412
412
-
border-radius: 0.25rem;
413
413
-
cursor: pointer;
414
414
-
font-size: 0.8rem;
415
415
-
}
417
417
+
.copy-section-button {
418
418
+
background-color: #21262d;
419
419
+
color: #c9d1d9;
420
420
+
border: 1px solid #30363d;
421
421
+
padding: 0.25rem 0.5rem;
422
422
+
border-radius: 0.25rem;
423
423
+
cursor: pointer;
424
424
+
font-size: 0.8rem;
425
425
+
}
416
426
417
417
-
.copy-section-button:hover {
418
418
-
background-color: #30363d;
419
419
-
}
427
427
+
.copy-section-button:hover {
428
428
+
background-color: #30363d;
429
429
+
}
420
430
421
421
-
/* Remove the old copy-button style if it exists */
422
422
-
.copy-button {
423
423
-
display: none;
424
424
-
}
425
425
-
</style>
431
431
+
/* Remove the old copy-button style if it exists */
432
432
+
.copy-button {
433
433
+
display: none;
434
434
+
}
435
435
+
</style>